1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/arch/arm/mach-omap1/mcbsp.c
5 * Copyright (C) 2008 Instituto Nokia de Tecnologia
6 * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
8 * Multichannel mode not supported.
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>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
19 #include <linux/omap-dma.h>
22 #include <linux/platform_data/asoc-ti-mcbsp.h>
24 #include <mach/irqs.h>
28 #define DPS_RSTCT2_PER_EN (1 << 0)
29 #define DSP_RSTCT2_WD_PER_EN (1 << 1)
32 static struct clk
*api_clk
;
33 static struct clk
*dsp_clk
;
34 static struct platform_device
**omap_mcbsp_devices
;
36 static void omap1_mcbsp_request(unsigned int id
)
39 * On 1510, 1610 and 1710, McBSP1 and McBSP3
40 * are DSP public peripherals.
42 if (id
== 0 || id
== 2) {
44 api_clk
= clk_get(NULL
, "api_ck");
45 dsp_clk
= clk_get(NULL
, "dsp_ck");
46 if (!IS_ERR(api_clk
) && !IS_ERR(dsp_clk
)) {
51 * DSP external peripheral reset
52 * FIXME: This should be moved to dsp code
54 __raw_writew(__raw_readw(DSP_RSTCT2
) | DPS_RSTCT2_PER_EN
|
55 DSP_RSTCT2_WD_PER_EN
, DSP_RSTCT2
);
61 static void omap1_mcbsp_free(unsigned int id
)
63 if (id
== 0 || id
== 2) {
65 if (!IS_ERR(api_clk
)) {
69 if (!IS_ERR(dsp_clk
)) {
77 static struct omap_mcbsp_ops omap1_mcbsp_ops
= {
78 .request
= omap1_mcbsp_request
,
79 .free
= omap1_mcbsp_free
,
82 #define OMAP7XX_MCBSP1_BASE 0xfffb1000
83 #define OMAP7XX_MCBSP2_BASE 0xfffb1800
85 #define OMAP1510_MCBSP1_BASE 0xe1011800
86 #define OMAP1510_MCBSP2_BASE 0xfffb1000
87 #define OMAP1510_MCBSP3_BASE 0xe1017000
89 #define OMAP1610_MCBSP1_BASE 0xe1011800
90 #define OMAP1610_MCBSP2_BASE 0xfffb1000
91 #define OMAP1610_MCBSP3_BASE 0xe1017000
93 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
94 struct resource omap7xx_mcbsp_res
[][6] = {
97 .start
= OMAP7XX_MCBSP1_BASE
,
98 .end
= OMAP7XX_MCBSP1_BASE
+ SZ_256
,
99 .flags
= IORESOURCE_MEM
,
103 .start
= INT_7XX_McBSP1RX
,
104 .flags
= IORESOURCE_IRQ
,
108 .start
= INT_7XX_McBSP1TX
,
109 .flags
= IORESOURCE_IRQ
,
114 .flags
= IORESOURCE_DMA
,
119 .flags
= IORESOURCE_DMA
,
124 .start
= OMAP7XX_MCBSP2_BASE
,
125 .end
= OMAP7XX_MCBSP2_BASE
+ SZ_256
,
126 .flags
= IORESOURCE_MEM
,
130 .start
= INT_7XX_McBSP2RX
,
131 .flags
= IORESOURCE_IRQ
,
135 .start
= INT_7XX_McBSP2TX
,
136 .flags
= IORESOURCE_IRQ
,
141 .flags
= IORESOURCE_DMA
,
146 .flags
= IORESOURCE_DMA
,
151 #define omap7xx_mcbsp_res_0 omap7xx_mcbsp_res[0]
153 static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata
[] = {
155 .ops
= &omap1_mcbsp_ops
,
158 .ops
= &omap1_mcbsp_ops
,
161 #define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
162 #define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
164 #define omap7xx_mcbsp_res_0 NULL
165 #define omap7xx_mcbsp_pdata NULL
166 #define OMAP7XX_MCBSP_RES_SZ 0
167 #define OMAP7XX_MCBSP_COUNT 0
170 #ifdef CONFIG_ARCH_OMAP15XX
171 struct resource omap15xx_mcbsp_res
[][6] = {
174 .start
= OMAP1510_MCBSP1_BASE
,
175 .end
= OMAP1510_MCBSP1_BASE
+ SZ_256
,
176 .flags
= IORESOURCE_MEM
,
180 .start
= INT_McBSP1RX
,
181 .flags
= IORESOURCE_IRQ
,
185 .start
= INT_McBSP1TX
,
186 .flags
= IORESOURCE_IRQ
,
191 .flags
= IORESOURCE_DMA
,
196 .flags
= IORESOURCE_DMA
,
201 .start
= OMAP1510_MCBSP2_BASE
,
202 .end
= OMAP1510_MCBSP2_BASE
+ SZ_256
,
203 .flags
= IORESOURCE_MEM
,
207 .start
= INT_1510_SPI_RX
,
208 .flags
= IORESOURCE_IRQ
,
212 .start
= INT_1510_SPI_TX
,
213 .flags
= IORESOURCE_IRQ
,
218 .flags
= IORESOURCE_DMA
,
223 .flags
= IORESOURCE_DMA
,
228 .start
= OMAP1510_MCBSP3_BASE
,
229 .end
= OMAP1510_MCBSP3_BASE
+ SZ_256
,
230 .flags
= IORESOURCE_MEM
,
234 .start
= INT_McBSP3RX
,
235 .flags
= IORESOURCE_IRQ
,
239 .start
= INT_McBSP3TX
,
240 .flags
= IORESOURCE_IRQ
,
245 .flags
= IORESOURCE_DMA
,
250 .flags
= IORESOURCE_DMA
,
255 #define omap15xx_mcbsp_res_0 omap15xx_mcbsp_res[0]
257 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata
[] = {
259 .ops
= &omap1_mcbsp_ops
,
262 .ops
= &omap1_mcbsp_ops
,
265 .ops
= &omap1_mcbsp_ops
,
268 #define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
269 #define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
271 #define omap15xx_mcbsp_res_0 NULL
272 #define omap15xx_mcbsp_pdata NULL
273 #define OMAP15XX_MCBSP_RES_SZ 0
274 #define OMAP15XX_MCBSP_COUNT 0
277 #ifdef CONFIG_ARCH_OMAP16XX
278 struct resource omap16xx_mcbsp_res
[][6] = {
281 .start
= OMAP1610_MCBSP1_BASE
,
282 .end
= OMAP1610_MCBSP1_BASE
+ SZ_256
,
283 .flags
= IORESOURCE_MEM
,
287 .start
= INT_McBSP1RX
,
288 .flags
= IORESOURCE_IRQ
,
292 .start
= INT_McBSP1TX
,
293 .flags
= IORESOURCE_IRQ
,
298 .flags
= IORESOURCE_DMA
,
303 .flags
= IORESOURCE_DMA
,
308 .start
= OMAP1610_MCBSP2_BASE
,
309 .end
= OMAP1610_MCBSP2_BASE
+ SZ_256
,
310 .flags
= IORESOURCE_MEM
,
314 .start
= INT_1610_McBSP2_RX
,
315 .flags
= IORESOURCE_IRQ
,
319 .start
= INT_1610_McBSP2_TX
,
320 .flags
= IORESOURCE_IRQ
,
325 .flags
= IORESOURCE_DMA
,
330 .flags
= IORESOURCE_DMA
,
335 .start
= OMAP1610_MCBSP3_BASE
,
336 .end
= OMAP1610_MCBSP3_BASE
+ SZ_256
,
337 .flags
= IORESOURCE_MEM
,
341 .start
= INT_McBSP3RX
,
342 .flags
= IORESOURCE_IRQ
,
346 .start
= INT_McBSP3TX
,
347 .flags
= IORESOURCE_IRQ
,
352 .flags
= IORESOURCE_DMA
,
357 .flags
= IORESOURCE_DMA
,
362 #define omap16xx_mcbsp_res_0 omap16xx_mcbsp_res[0]
364 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata
[] = {
366 .ops
= &omap1_mcbsp_ops
,
369 .ops
= &omap1_mcbsp_ops
,
372 .ops
= &omap1_mcbsp_ops
,
375 #define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
376 #define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
378 #define omap16xx_mcbsp_res_0 NULL
379 #define omap16xx_mcbsp_pdata NULL
380 #define OMAP16XX_MCBSP_RES_SZ 0
381 #define OMAP16XX_MCBSP_COUNT 0
384 static void omap_mcbsp_register_board_cfg(struct resource
*res
, int res_count
,
385 struct omap_mcbsp_platform_data
*config
, int size
)
389 omap_mcbsp_devices
= kcalloc(size
, sizeof(struct platform_device
*),
391 if (!omap_mcbsp_devices
) {
392 printk(KERN_ERR
"Could not register McBSP devices\n");
396 for (i
= 0; i
< size
; i
++) {
397 struct platform_device
*new_mcbsp
;
400 new_mcbsp
= platform_device_alloc("omap-mcbsp", i
+ 1);
403 platform_device_add_resources(new_mcbsp
, &res
[i
* res_count
],
405 config
[i
].reg_size
= 2;
406 config
[i
].reg_step
= 2;
407 new_mcbsp
->dev
.platform_data
= &config
[i
];
408 ret
= platform_device_add(new_mcbsp
);
410 platform_device_put(new_mcbsp
);
413 omap_mcbsp_devices
[i
] = new_mcbsp
;
417 static int __init
omap1_mcbsp_init(void)
419 if (!cpu_class_is_omap1())
422 if (cpu_is_omap7xx())
423 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0
,
424 OMAP7XX_MCBSP_RES_SZ
,
426 OMAP7XX_MCBSP_COUNT
);
428 if (cpu_is_omap15xx())
429 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0
,
430 OMAP15XX_MCBSP_RES_SZ
,
431 omap15xx_mcbsp_pdata
,
432 OMAP15XX_MCBSP_COUNT
);
434 if (cpu_is_omap16xx())
435 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0
,
436 OMAP16XX_MCBSP_RES_SZ
,
437 omap16xx_mcbsp_pdata
,
438 OMAP16XX_MCBSP_COUNT
);
443 arch_initcall(omap1_mcbsp_init
);