Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-omap1/mcbsp.c
26292 views
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 <[email protected]>
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 omap15xx_mcbsp_res[][6] = {
93
{
94
{
95
.start = OMAP1510_MCBSP1_BASE,
96
.end = OMAP1510_MCBSP1_BASE + SZ_256,
97
.flags = IORESOURCE_MEM,
98
},
99
{
100
.name = "rx",
101
.start = INT_McBSP1RX,
102
.flags = IORESOURCE_IRQ,
103
},
104
{
105
.name = "tx",
106
.start = INT_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 = OMAP1510_MCBSP2_BASE,
123
.end = OMAP1510_MCBSP2_BASE + SZ_256,
124
.flags = IORESOURCE_MEM,
125
},
126
{
127
.name = "rx",
128
.start = INT_1510_SPI_RX,
129
.flags = IORESOURCE_IRQ,
130
},
131
{
132
.name = "tx",
133
.start = INT_1510_SPI_TX,
134
.flags = IORESOURCE_IRQ,
135
},
136
{
137
.name = "rx",
138
.start = 17,
139
.flags = IORESOURCE_DMA,
140
},
141
{
142
.name = "tx",
143
.start = 16,
144
.flags = IORESOURCE_DMA,
145
},
146
},
147
{
148
{
149
.start = OMAP1510_MCBSP3_BASE,
150
.end = OMAP1510_MCBSP3_BASE + SZ_256,
151
.flags = IORESOURCE_MEM,
152
},
153
{
154
.name = "rx",
155
.start = INT_McBSP3RX,
156
.flags = IORESOURCE_IRQ,
157
},
158
{
159
.name = "tx",
160
.start = INT_McBSP3TX,
161
.flags = IORESOURCE_IRQ,
162
},
163
{
164
.name = "rx",
165
.start = 11,
166
.flags = IORESOURCE_DMA,
167
},
168
{
169
.name = "tx",
170
.start = 10,
171
.flags = IORESOURCE_DMA,
172
},
173
},
174
};
175
176
#define omap15xx_mcbsp_res_0 omap15xx_mcbsp_res[0]
177
178
static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
179
{
180
.ops = &omap1_mcbsp_ops,
181
},
182
{
183
.ops = &omap1_mcbsp_ops,
184
},
185
{
186
.ops = &omap1_mcbsp_ops,
187
},
188
};
189
#define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
190
#define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
191
192
struct resource omap16xx_mcbsp_res[][6] = {
193
{
194
{
195
.start = OMAP1610_MCBSP1_BASE,
196
.end = OMAP1610_MCBSP1_BASE + SZ_256,
197
.flags = IORESOURCE_MEM,
198
},
199
{
200
.name = "rx",
201
.start = INT_McBSP1RX,
202
.flags = IORESOURCE_IRQ,
203
},
204
{
205
.name = "tx",
206
.start = INT_McBSP1TX,
207
.flags = IORESOURCE_IRQ,
208
},
209
{
210
.name = "rx",
211
.start = 9,
212
.flags = IORESOURCE_DMA,
213
},
214
{
215
.name = "tx",
216
.start = 8,
217
.flags = IORESOURCE_DMA,
218
},
219
},
220
{
221
{
222
.start = OMAP1610_MCBSP2_BASE,
223
.end = OMAP1610_MCBSP2_BASE + SZ_256,
224
.flags = IORESOURCE_MEM,
225
},
226
{
227
.name = "rx",
228
.start = INT_1610_McBSP2_RX,
229
.flags = IORESOURCE_IRQ,
230
},
231
{
232
.name = "tx",
233
.start = INT_1610_McBSP2_TX,
234
.flags = IORESOURCE_IRQ,
235
},
236
{
237
.name = "rx",
238
.start = 17,
239
.flags = IORESOURCE_DMA,
240
},
241
{
242
.name = "tx",
243
.start = 16,
244
.flags = IORESOURCE_DMA,
245
},
246
},
247
{
248
{
249
.start = OMAP1610_MCBSP3_BASE,
250
.end = OMAP1610_MCBSP3_BASE + SZ_256,
251
.flags = IORESOURCE_MEM,
252
},
253
{
254
.name = "rx",
255
.start = INT_McBSP3RX,
256
.flags = IORESOURCE_IRQ,
257
},
258
{
259
.name = "tx",
260
.start = INT_McBSP3TX,
261
.flags = IORESOURCE_IRQ,
262
},
263
{
264
.name = "rx",
265
.start = 11,
266
.flags = IORESOURCE_DMA,
267
},
268
{
269
.name = "tx",
270
.start = 10,
271
.flags = IORESOURCE_DMA,
272
},
273
},
274
};
275
276
#define omap16xx_mcbsp_res_0 omap16xx_mcbsp_res[0]
277
278
static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
279
{
280
.ops = &omap1_mcbsp_ops,
281
},
282
{
283
.ops = &omap1_mcbsp_ops,
284
},
285
{
286
.ops = &omap1_mcbsp_ops,
287
},
288
};
289
#define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
290
#define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
291
292
static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
293
struct omap_mcbsp_platform_data *config, int size)
294
{
295
int i;
296
297
omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *),
298
GFP_KERNEL);
299
if (!omap_mcbsp_devices) {
300
printk(KERN_ERR "Could not register McBSP devices\n");
301
return;
302
}
303
304
for (i = 0; i < size; i++) {
305
struct platform_device *new_mcbsp;
306
int ret;
307
308
new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
309
if (!new_mcbsp)
310
continue;
311
platform_device_add_resources(new_mcbsp, &res[i * res_count],
312
res_count);
313
config[i].reg_size = 2;
314
config[i].reg_step = 2;
315
new_mcbsp->dev.platform_data = &config[i];
316
ret = platform_device_add(new_mcbsp);
317
if (ret) {
318
platform_device_put(new_mcbsp);
319
continue;
320
}
321
omap_mcbsp_devices[i] = new_mcbsp;
322
}
323
}
324
325
static int __init omap1_mcbsp_init(void)
326
{
327
if (!cpu_class_is_omap1())
328
return -ENODEV;
329
330
if (cpu_is_omap15xx())
331
omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
332
OMAP15XX_MCBSP_RES_SZ,
333
omap15xx_mcbsp_pdata,
334
OMAP15XX_MCBSP_COUNT);
335
336
if (cpu_is_omap16xx())
337
omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
338
OMAP16XX_MCBSP_RES_SZ,
339
omap16xx_mcbsp_pdata,
340
OMAP16XX_MCBSP_COUNT);
341
342
return 0;
343
}
344
345
arch_initcall(omap1_mcbsp_init);
346
347