Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-omap1/mcbsp.c
10817 views
1
/*
2
* linux/arch/arm/mach-omap1/mcbsp.c
3
*
4
* Copyright (C) 2008 Instituto Nokia de Tecnologia
5
* Contact: Eduardo Valentin <[email protected]>
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);
411
412