Security: allow capable check to permit mmap or low vm space
[linux-2.6] / arch / arm / plat-omap / mcbsp.c
1 /*
2  * linux/arch/arm/plat-omap/mcbsp.c
3  *
4  * Copyright (C) 2004 Nokia Corporation
5  * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
6  *
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * Multichannel mode not supported.
13  */
14
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/device.h>
18 #include <linux/wait.h>
19 #include <linux/completion.h>
20 #include <linux/interrupt.h>
21 #include <linux/err.h>
22 #include <linux/clk.h>
23 #include <linux/delay.h>
24
25 #include <asm/io.h>
26 #include <asm/irq.h>
27
28 #include <asm/arch/dma.h>
29 #include <asm/arch/mux.h>
30 #include <asm/arch/irqs.h>
31 #include <asm/arch/dsp_common.h>
32 #include <asm/arch/mcbsp.h>
33
34 #ifdef CONFIG_MCBSP_DEBUG
35 #define DBG(x...)       printk(x)
36 #else
37 #define DBG(x...)                       do { } while (0)
38 #endif
39
40 struct omap_mcbsp {
41         u32                          io_base;
42         u8                           id;
43         u8                           free;
44         omap_mcbsp_word_length       rx_word_length;
45         omap_mcbsp_word_length       tx_word_length;
46
47         omap_mcbsp_io_type_t         io_type; /* IRQ or poll */
48         /* IRQ based TX/RX */
49         int                          rx_irq;
50         int                          tx_irq;
51
52         /* DMA stuff */
53         u8                           dma_rx_sync;
54         short                        dma_rx_lch;
55         u8                           dma_tx_sync;
56         short                        dma_tx_lch;
57
58         /* Completion queues */
59         struct completion            tx_irq_completion;
60         struct completion            rx_irq_completion;
61         struct completion            tx_dma_completion;
62         struct completion            rx_dma_completion;
63
64         spinlock_t                   lock;
65 };
66
67 static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
68 #ifdef CONFIG_ARCH_OMAP1
69 static struct clk *mcbsp_dsp_ck = 0;
70 static struct clk *mcbsp_api_ck = 0;
71 static struct clk *mcbsp_dspxor_ck = 0;
72 #endif
73 #ifdef CONFIG_ARCH_OMAP2
74 static struct clk *mcbsp1_ick = 0;
75 static struct clk *mcbsp1_fck = 0;
76 static struct clk *mcbsp2_ick = 0;
77 static struct clk *mcbsp2_fck = 0;
78 #endif
79
80 static void omap_mcbsp_dump_reg(u8 id)
81 {
82         DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
83         DBG("DRR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
84         DBG("DRR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
85         DBG("DXR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
86         DBG("DXR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
87         DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
88         DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
89         DBG("RCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
90         DBG("RCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
91         DBG("XCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
92         DBG("XCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
93         DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
94         DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
95         DBG("PCR0:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
96         DBG("***********************\n");
97 }
98
99 static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
100 {
101         struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
102
103         DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
104
105         complete(&mcbsp_tx->tx_irq_completion);
106         return IRQ_HANDLED;
107 }
108
109 static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
110 {
111         struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
112
113         DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
114
115         complete(&mcbsp_rx->rx_irq_completion);
116         return IRQ_HANDLED;
117 }
118
119 static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
120 {
121         struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
122
123         DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
124
125         /* We can free the channels */
126         omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
127         mcbsp_dma_tx->dma_tx_lch = -1;
128
129         complete(&mcbsp_dma_tx->tx_dma_completion);
130 }
131
132 static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
133 {
134         struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
135
136         DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
137
138         /* We can free the channels */
139         omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
140         mcbsp_dma_rx->dma_rx_lch = -1;
141
142         complete(&mcbsp_dma_rx->rx_dma_completion);
143 }
144
145
146 /*
147  * omap_mcbsp_config simply write a config to the
148  * appropriate McBSP.
149  * You either call this function or set the McBSP registers
150  * by yourself before calling omap_mcbsp_start().
151  */
152
153 void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
154 {
155         u32 io_base = mcbsp[id].io_base;
156
157         DBG("OMAP-McBSP: McBSP%d  io_base: 0x%8x\n", id+1, io_base);
158
159         /* We write the given config */
160         OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
161         OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
162         OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
163         OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
164         OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
165         OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
166         OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
167         OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
168         OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
169         OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
170         OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
171 }
172
173
174
175 static int omap_mcbsp_check(unsigned int id)
176 {
177         if (cpu_is_omap730()) {
178                 if (id > OMAP_MAX_MCBSP_COUNT - 1) {
179                        printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
180                        return -1;
181                 }
182                 return 0;
183         }
184
185         if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
186                 if (id > OMAP_MAX_MCBSP_COUNT) {
187                         printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
188                         return -1;
189                 }
190                 return 0;
191         }
192
193         return -1;
194 }
195
196 #ifdef CONFIG_ARCH_OMAP1
197 static void omap_mcbsp_dsp_request(void)
198 {
199         if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
200                 clk_enable(mcbsp_dsp_ck);
201                 clk_enable(mcbsp_api_ck);
202
203                 /* enable 12MHz clock to mcbsp 1 & 3 */
204                 clk_enable(mcbsp_dspxor_ck);
205
206                 /*
207                  * DSP external peripheral reset
208                  * FIXME: This should be moved to dsp code
209                  */
210                 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
211                              DSP_RSTCT2);
212         }
213 }
214
215 static void omap_mcbsp_dsp_free(void)
216 {
217         if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
218                 clk_disable(mcbsp_dspxor_ck);
219                 clk_disable(mcbsp_dsp_ck);
220                 clk_disable(mcbsp_api_ck);
221         }
222 }
223 #endif
224
225 #ifdef CONFIG_ARCH_OMAP2
226 static void omap2_mcbsp2_mux_setup(void)
227 {
228         if (cpu_is_omap2420()) {
229                 omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
230                 omap_cfg_reg(R14_24XX_MCBSP2_FSX);
231                 omap_cfg_reg(W15_24XX_MCBSP2_DR);
232                 omap_cfg_reg(V15_24XX_MCBSP2_DX);
233                 omap_cfg_reg(V14_24XX_GPIO117);
234         }
235         /*
236          * Need to add MUX settings for OMAP 2430 SDP
237          */
238 }
239 #endif
240
241 /*
242  * We can choose between IRQ based or polled IO.
243  * This needs to be called before omap_mcbsp_request().
244  */
245 int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
246 {
247         if (omap_mcbsp_check(id) < 0)
248                 return -EINVAL;
249
250         spin_lock(&mcbsp[id].lock);
251
252         if (!mcbsp[id].free) {
253                 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
254                 spin_unlock(&mcbsp[id].lock);
255                 return -EINVAL;
256         }
257
258         mcbsp[id].io_type = io_type;
259
260         spin_unlock(&mcbsp[id].lock);
261
262         return 0;
263 }
264
265 int omap_mcbsp_request(unsigned int id)
266 {
267         int err;
268
269         if (omap_mcbsp_check(id) < 0)
270                 return -EINVAL;
271
272 #ifdef CONFIG_ARCH_OMAP1
273         /*
274          * On 1510, 1610 and 1710, McBSP1 and McBSP3
275          * are DSP public peripherals.
276          */
277         if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
278                 omap_mcbsp_dsp_request();
279 #endif
280
281 #ifdef CONFIG_ARCH_OMAP2
282         if (cpu_is_omap24xx()) {
283                 if (id == OMAP_MCBSP1) {
284                         clk_enable(mcbsp1_ick);
285                         clk_enable(mcbsp1_fck);
286                 } else {
287                         clk_enable(mcbsp2_ick);
288                         clk_enable(mcbsp2_fck);
289                 }
290         }
291 #endif
292
293         spin_lock(&mcbsp[id].lock);
294         if (!mcbsp[id].free) {
295                 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
296                 spin_unlock(&mcbsp[id].lock);
297                 return -1;
298         }
299
300         mcbsp[id].free = 0;
301         spin_unlock(&mcbsp[id].lock);
302
303         if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
304                 /* We need to get IRQs here */
305                 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
306                                   "McBSP",
307                                   (void *) (&mcbsp[id]));
308                 if (err != 0) {
309                         printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
310                                mcbsp[id].tx_irq, mcbsp[id].id);
311                         return err;
312                 }
313
314                 init_completion(&(mcbsp[id].tx_irq_completion));
315
316
317                 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
318                                   "McBSP",
319                                   (void *) (&mcbsp[id]));
320                 if (err != 0) {
321                         printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
322                                mcbsp[id].rx_irq, mcbsp[id].id);
323                         free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
324                         return err;
325                 }
326
327                 init_completion(&(mcbsp[id].rx_irq_completion));
328         }
329
330         return 0;
331
332 }
333
334 void omap_mcbsp_free(unsigned int id)
335 {
336         if (omap_mcbsp_check(id) < 0)
337                 return;
338
339 #ifdef CONFIG_ARCH_OMAP1
340         if (cpu_class_is_omap1()) {
341                 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
342                         omap_mcbsp_dsp_free();
343         }
344 #endif
345
346 #ifdef CONFIG_ARCH_OMAP2
347         if (cpu_is_omap24xx()) {
348                 if (id == OMAP_MCBSP1) {
349                         clk_disable(mcbsp1_ick);
350                         clk_disable(mcbsp1_fck);
351                 } else {
352                         clk_disable(mcbsp2_ick);
353                         clk_disable(mcbsp2_fck);
354                 }
355         }
356 #endif
357
358         spin_lock(&mcbsp[id].lock);
359         if (mcbsp[id].free) {
360                 printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
361                 spin_unlock(&mcbsp[id].lock);
362                 return;
363         }
364
365         mcbsp[id].free = 1;
366         spin_unlock(&mcbsp[id].lock);
367
368         if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
369                 /* Free IRQs */
370                 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
371                 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
372         }
373 }
374
375 /*
376  * Here we start the McBSP, by enabling the sample
377  * generator, both transmitter and receivers,
378  * and the frame sync.
379  */
380 void omap_mcbsp_start(unsigned int id)
381 {
382         u32 io_base;
383         u16 w;
384
385         if (omap_mcbsp_check(id) < 0)
386                 return;
387
388         io_base = mcbsp[id].io_base;
389
390         mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
391         mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
392
393         /* Start the sample generator */
394         w = OMAP_MCBSP_READ(io_base, SPCR2);
395         OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
396
397         /* Enable transmitter and receiver */
398         w = OMAP_MCBSP_READ(io_base, SPCR2);
399         OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
400
401         w = OMAP_MCBSP_READ(io_base, SPCR1);
402         OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
403
404         udelay(100);
405
406         /* Start frame sync */
407         w = OMAP_MCBSP_READ(io_base, SPCR2);
408         OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
409
410         /* Dump McBSP Regs */
411         omap_mcbsp_dump_reg(id);
412
413 }
414
415 void omap_mcbsp_stop(unsigned int id)
416 {
417         u32 io_base;
418         u16 w;
419
420         if (omap_mcbsp_check(id) < 0)
421                 return;
422
423         io_base = mcbsp[id].io_base;
424
425         /* Reset transmitter */
426         w = OMAP_MCBSP_READ(io_base, SPCR2);
427         OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
428
429         /* Reset receiver */
430         w = OMAP_MCBSP_READ(io_base, SPCR1);
431         OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
432
433         /* Reset the sample rate generator */
434         w = OMAP_MCBSP_READ(io_base, SPCR2);
435         OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
436 }
437
438
439 /* polled mcbsp i/o operations */
440 int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
441 {
442         u32 base = mcbsp[id].io_base;
443         writew(buf, base + OMAP_MCBSP_REG_DXR1);
444         /* if frame sync error - clear the error */
445         if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
446                 /* clear error */
447                 writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
448                        base + OMAP_MCBSP_REG_SPCR2);
449                 /* resend */
450                 return -1;
451         } else {
452                 /* wait for transmit confirmation */
453                 int attemps = 0;
454                 while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
455                         if (attemps++ > 1000) {
456                                 writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
457                                        (~XRST),
458                                        base + OMAP_MCBSP_REG_SPCR2);
459                                 udelay(10);
460                                 writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
461                                        (XRST),
462                                        base + OMAP_MCBSP_REG_SPCR2);
463                                 udelay(10);
464                                 printk(KERN_ERR
465                                        " Could not write to McBSP Register\n");
466                                 return -2;
467                         }
468                 }
469         }
470         return 0;
471 }
472
473 int omap_mcbsp_pollread(unsigned int id, u16 * buf)
474 {
475         u32 base = mcbsp[id].io_base;
476         /* if frame sync error - clear the error */
477         if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
478                 /* clear error */
479                 writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
480                        base + OMAP_MCBSP_REG_SPCR1);
481                 /* resend */
482                 return -1;
483         } else {
484                 /* wait for recieve confirmation */
485                 int attemps = 0;
486                 while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
487                         if (attemps++ > 1000) {
488                                 writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
489                                        (~RRST),
490                                        base + OMAP_MCBSP_REG_SPCR1);
491                                 udelay(10);
492                                 writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
493                                        (RRST),
494                                        base + OMAP_MCBSP_REG_SPCR1);
495                                 udelay(10);
496                                 printk(KERN_ERR
497                                        " Could not read from McBSP Register\n");
498                                 return -2;
499                         }
500                 }
501         }
502         *buf = readw(base + OMAP_MCBSP_REG_DRR1);
503         return 0;
504 }
505
506 /*
507  * IRQ based word transmission.
508  */
509 void omap_mcbsp_xmit_word(unsigned int id, u32 word)
510 {
511         u32 io_base;
512         omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
513
514         if (omap_mcbsp_check(id) < 0)
515                 return;
516
517         io_base = mcbsp[id].io_base;
518
519         wait_for_completion(&(mcbsp[id].tx_irq_completion));
520
521         if (word_length > OMAP_MCBSP_WORD_16)
522                 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
523         OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
524 }
525
526 u32 omap_mcbsp_recv_word(unsigned int id)
527 {
528         u32 io_base;
529         u16 word_lsb, word_msb = 0;
530         omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
531
532         if (omap_mcbsp_check(id) < 0)
533                 return -EINVAL;
534
535         io_base = mcbsp[id].io_base;
536
537         wait_for_completion(&(mcbsp[id].rx_irq_completion));
538
539         if (word_length > OMAP_MCBSP_WORD_16)
540                 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
541         word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
542
543         return (word_lsb | (word_msb << 16));
544 }
545
546
547 int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
548 {
549         u32 io_base = mcbsp[id].io_base;
550         omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
551         omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
552         u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
553
554         if (tx_word_length != rx_word_length)
555                 return -EINVAL;
556
557         /* First we wait for the transmitter to be ready */
558         spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
559         while (!(spcr2 & XRDY)) {
560                 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
561                 if (attempts++ > 1000) {
562                         /* We must reset the transmitter */
563                         OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
564                         udelay(10);
565                         OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
566                         udelay(10);
567                         printk("McBSP transmitter not ready\n");
568                         return -EAGAIN;
569                 }
570         }
571
572         /* Now we can push the data */
573         if (tx_word_length > OMAP_MCBSP_WORD_16)
574                 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
575         OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
576
577         /* We wait for the receiver to be ready */
578         spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
579         while (!(spcr1 & RRDY)) {
580                 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
581                 if (attempts++ > 1000) {
582                         /* We must reset the receiver */
583                         OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
584                         udelay(10);
585                         OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
586                         udelay(10);
587                         printk("McBSP receiver not ready\n");
588                         return -EAGAIN;
589                 }
590         }
591
592         /* Receiver is ready, let's read the dummy data */
593         if (rx_word_length > OMAP_MCBSP_WORD_16)
594                 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
595         word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
596
597         return 0;
598 }
599
600 int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
601 {
602         u32 io_base = mcbsp[id].io_base, clock_word = 0;
603         omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
604         omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
605         u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
606
607         if (tx_word_length != rx_word_length)
608                 return -EINVAL;
609
610         /* First we wait for the transmitter to be ready */
611         spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
612         while (!(spcr2 & XRDY)) {
613                 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
614                 if (attempts++ > 1000) {
615                         /* We must reset the transmitter */
616                         OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
617                         udelay(10);
618                         OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
619                         udelay(10);
620                         printk("McBSP transmitter not ready\n");
621                         return -EAGAIN;
622                 }
623         }
624
625         /* We first need to enable the bus clock */
626         if (tx_word_length > OMAP_MCBSP_WORD_16)
627                 OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
628         OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
629
630         /* We wait for the receiver to be ready */
631         spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
632         while (!(spcr1 & RRDY)) {
633                 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
634                 if (attempts++ > 1000) {
635                         /* We must reset the receiver */
636                         OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
637                         udelay(10);
638                         OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
639                         udelay(10);
640                         printk("McBSP receiver not ready\n");
641                         return -EAGAIN;
642                 }
643         }
644
645         /* Receiver is ready, there is something for us */
646         if (rx_word_length > OMAP_MCBSP_WORD_16)
647                 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
648         word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
649
650         word[0] = (word_lsb | (word_msb << 16));
651
652         return 0;
653 }
654
655
656 /*
657  * Simple DMA based buffer rx/tx routines.
658  * Nothing fancy, just a single buffer tx/rx through DMA.
659  * The DMA resources are released once the transfer is done.
660  * For anything fancier, you should use your own customized DMA
661  * routines and callbacks.
662  */
663 int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
664 {
665         int dma_tx_ch;
666         int src_port = 0;
667         int dest_port = 0;
668         int sync_dev = 0;
669
670         if (omap_mcbsp_check(id) < 0)
671                 return -EINVAL;
672
673         if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
674                              &mcbsp[id],
675                              &dma_tx_ch)) {
676                 printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
677                 return -EAGAIN;
678         }
679         mcbsp[id].dma_tx_lch = dma_tx_ch;
680
681         DBG("TX DMA on channel %d\n", dma_tx_ch);
682
683         init_completion(&(mcbsp[id].tx_dma_completion));
684
685         if (cpu_class_is_omap1()) {
686                 src_port = OMAP_DMA_PORT_TIPB;
687                 dest_port = OMAP_DMA_PORT_EMIFF;
688         }
689         if (cpu_is_omap24xx())
690                 sync_dev = mcbsp[id].dma_tx_sync;
691
692         omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
693                                      OMAP_DMA_DATA_TYPE_S16,
694                                      length >> 1, 1,
695                                      OMAP_DMA_SYNC_ELEMENT,
696          sync_dev, 0);
697
698         omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
699                                  src_port,
700                                  OMAP_DMA_AMODE_CONSTANT,
701                                  mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
702                                  0, 0);
703
704         omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
705                                 dest_port,
706                                 OMAP_DMA_AMODE_POST_INC,
707                                 buffer,
708                                 0, 0);
709
710         omap_start_dma(mcbsp[id].dma_tx_lch);
711         wait_for_completion(&(mcbsp[id].tx_dma_completion));
712         return 0;
713 }
714
715
716 int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
717 {
718         int dma_rx_ch;
719         int src_port = 0;
720         int dest_port = 0;
721         int sync_dev = 0;
722
723         if (omap_mcbsp_check(id) < 0)
724                 return -EINVAL;
725
726         if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
727                              &mcbsp[id],
728                              &dma_rx_ch)) {
729                 printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
730                 return -EAGAIN;
731         }
732         mcbsp[id].dma_rx_lch = dma_rx_ch;
733
734         DBG("RX DMA on channel %d\n", dma_rx_ch);
735
736         init_completion(&(mcbsp[id].rx_dma_completion));
737
738         if (cpu_class_is_omap1()) {
739                 src_port = OMAP_DMA_PORT_TIPB;
740                 dest_port = OMAP_DMA_PORT_EMIFF;
741         }
742         if (cpu_is_omap24xx())
743                 sync_dev = mcbsp[id].dma_rx_sync;
744
745         omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
746                                      OMAP_DMA_DATA_TYPE_S16,
747                                      length >> 1, 1,
748                                      OMAP_DMA_SYNC_ELEMENT,
749          sync_dev, 0);
750
751         omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
752                                 src_port,
753                                 OMAP_DMA_AMODE_CONSTANT,
754                                 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
755                                 0, 0);
756
757         omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
758                                  dest_port,
759                                  OMAP_DMA_AMODE_POST_INC,
760                                  buffer,
761                                  0, 0);
762
763         omap_start_dma(mcbsp[id].dma_rx_lch);
764         wait_for_completion(&(mcbsp[id].rx_dma_completion));
765         return 0;
766 }
767
768
769 /*
770  * SPI wrapper.
771  * Since SPI setup is much simpler than the generic McBSP one,
772  * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
773  * Once this is done, you can call omap_mcbsp_start().
774  */
775 void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
776 {
777         struct omap_mcbsp_reg_cfg mcbsp_cfg;
778
779         if (omap_mcbsp_check(id) < 0)
780                 return;
781
782         memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
783
784         /* SPI has only one frame */
785         mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
786         mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
787
788         /* Clock stop mode */
789         if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
790                 mcbsp_cfg.spcr1 |= (1 << 12);
791         else
792                 mcbsp_cfg.spcr1 |= (3 << 11);
793
794         /* Set clock parities */
795         if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
796                 mcbsp_cfg.pcr0 |= CLKRP;
797         else
798                 mcbsp_cfg.pcr0 &= ~CLKRP;
799
800         if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
801                 mcbsp_cfg.pcr0 &= ~CLKXP;
802         else
803                 mcbsp_cfg.pcr0 |= CLKXP;
804
805         /* Set SCLKME to 0 and CLKSM to 1 */
806         mcbsp_cfg.pcr0 &= ~SCLKME;
807         mcbsp_cfg.srgr2 |= CLKSM;
808
809         /* Set FSXP */
810         if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
811                 mcbsp_cfg.pcr0 &= ~FSXP;
812         else
813                 mcbsp_cfg.pcr0 |= FSXP;
814
815         if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
816                 mcbsp_cfg.pcr0 |= CLKXM;
817                 mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
818                 mcbsp_cfg.pcr0 |= FSXM;
819                 mcbsp_cfg.srgr2 &= ~FSGM;
820                 mcbsp_cfg.xcr2 |= XDATDLY(1);
821                 mcbsp_cfg.rcr2 |= RDATDLY(1);
822         }
823         else {
824                 mcbsp_cfg.pcr0 &= ~CLKXM;
825                 mcbsp_cfg.srgr1 |= CLKGDV(1);
826                 mcbsp_cfg.pcr0 &= ~FSXM;
827                 mcbsp_cfg.xcr2 &= ~XDATDLY(3);
828                 mcbsp_cfg.rcr2 &= ~RDATDLY(3);
829         }
830
831         mcbsp_cfg.xcr2 &= ~XPHASE;
832         mcbsp_cfg.rcr2 &= ~RPHASE;
833
834         omap_mcbsp_config(id, &mcbsp_cfg);
835 }
836
837
838 /*
839  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
840  * 730 has only 2 McBSP, and both of them are MPU peripherals.
841  */
842 struct omap_mcbsp_info {
843         u32 virt_base;
844         u8 dma_rx_sync, dma_tx_sync;
845         u16 rx_irq, tx_irq;
846 };
847
848 #ifdef CONFIG_ARCH_OMAP730
849 static const struct omap_mcbsp_info mcbsp_730[] = {
850         [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
851                 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
852                 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
853                 .rx_irq = INT_730_McBSP1RX,
854                 .tx_irq = INT_730_McBSP1TX },
855         [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
856                 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
857                 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
858                 .rx_irq = INT_730_McBSP2RX,
859                 .tx_irq = INT_730_McBSP2TX },
860 };
861 #endif
862
863 #ifdef CONFIG_ARCH_OMAP15XX
864 static const struct omap_mcbsp_info mcbsp_1510[] = {
865         [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
866                 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
867                 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
868                 .rx_irq = INT_McBSP1RX,
869                 .tx_irq = INT_McBSP1TX },
870         [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
871                 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
872                 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
873                 .rx_irq = INT_1510_SPI_RX,
874                 .tx_irq = INT_1510_SPI_TX },
875         [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
876                 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
877                 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
878                 .rx_irq = INT_McBSP3RX,
879                 .tx_irq = INT_McBSP3TX },
880 };
881 #endif
882
883 #if defined(CONFIG_ARCH_OMAP16XX)
884 static const struct omap_mcbsp_info mcbsp_1610[] = {
885         [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
886                 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
887                 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
888                 .rx_irq = INT_McBSP1RX,
889                 .tx_irq = INT_McBSP1TX },
890         [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
891                 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
892                 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
893                 .rx_irq = INT_1610_McBSP2_RX,
894                 .tx_irq = INT_1610_McBSP2_TX },
895         [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
896                 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
897                 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
898                 .rx_irq = INT_McBSP3RX,
899                 .tx_irq = INT_McBSP3TX },
900 };
901 #endif
902
903 #if defined(CONFIG_ARCH_OMAP24XX)
904 static const struct omap_mcbsp_info mcbsp_24xx[] = {
905         [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
906                 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
907                 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
908                 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
909                 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
910                 },
911         [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
912                 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
913                 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
914                 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
915                 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
916                 },
917 };
918 #endif
919
920 static int __init omap_mcbsp_init(void)
921 {
922         int mcbsp_count = 0, i;
923         static const struct omap_mcbsp_info *mcbsp_info;
924
925         printk("Initializing OMAP McBSP system\n");
926
927 #ifdef CONFIG_ARCH_OMAP1
928         mcbsp_dsp_ck = clk_get(0, "dsp_ck");
929         if (IS_ERR(mcbsp_dsp_ck)) {
930                 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
931                 return PTR_ERR(mcbsp_dsp_ck);
932         }
933         mcbsp_api_ck = clk_get(0, "api_ck");
934         if (IS_ERR(mcbsp_api_ck)) {
935                 printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
936                 return PTR_ERR(mcbsp_api_ck);
937         }
938         mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
939         if (IS_ERR(mcbsp_dspxor_ck)) {
940                 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
941                 return PTR_ERR(mcbsp_dspxor_ck);
942         }
943 #endif
944 #ifdef CONFIG_ARCH_OMAP2
945         mcbsp1_ick = clk_get(0, "mcbsp1_ick");
946         if (IS_ERR(mcbsp1_ick)) {
947                 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
948                 return PTR_ERR(mcbsp1_ick);
949         }
950         mcbsp1_fck = clk_get(0, "mcbsp1_fck");
951         if (IS_ERR(mcbsp1_fck)) {
952                 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
953                 return PTR_ERR(mcbsp1_fck);
954         }
955         mcbsp2_ick = clk_get(0, "mcbsp2_ick");
956         if (IS_ERR(mcbsp2_ick)) {
957                 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
958                 return PTR_ERR(mcbsp2_ick);
959         }
960         mcbsp2_fck = clk_get(0, "mcbsp2_fck");
961         if (IS_ERR(mcbsp2_fck)) {
962                 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
963                 return PTR_ERR(mcbsp2_fck);
964         }
965 #endif
966
967 #ifdef CONFIG_ARCH_OMAP730
968         if (cpu_is_omap730()) {
969                 mcbsp_info = mcbsp_730;
970                 mcbsp_count = ARRAY_SIZE(mcbsp_730);
971         }
972 #endif
973 #ifdef CONFIG_ARCH_OMAP15XX
974         if (cpu_is_omap15xx()) {
975                 mcbsp_info = mcbsp_1510;
976                 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
977         }
978 #endif
979 #if defined(CONFIG_ARCH_OMAP16XX)
980         if (cpu_is_omap16xx()) {
981                 mcbsp_info = mcbsp_1610;
982                 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
983         }
984 #endif
985 #if defined(CONFIG_ARCH_OMAP24XX)
986         if (cpu_is_omap24xx()) {
987                 mcbsp_info = mcbsp_24xx;
988                 mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
989                 omap2_mcbsp2_mux_setup();
990         }
991 #endif
992         for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
993                 if (i >= mcbsp_count) {
994                         mcbsp[i].io_base = 0;
995                         mcbsp[i].free = 0;
996                         continue;
997                 }
998                 mcbsp[i].id = i + 1;
999                 mcbsp[i].free = 1;
1000                 mcbsp[i].dma_tx_lch = -1;
1001                 mcbsp[i].dma_rx_lch = -1;
1002
1003                 mcbsp[i].io_base = mcbsp_info[i].virt_base;
1004                 mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */
1005                 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
1006                 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
1007                 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
1008                 mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
1009                 spin_lock_init(&mcbsp[i].lock);
1010         }
1011
1012         return 0;
1013 }
1014
1015 arch_initcall(omap_mcbsp_init);
1016
1017 EXPORT_SYMBOL(omap_mcbsp_config);
1018 EXPORT_SYMBOL(omap_mcbsp_request);
1019 EXPORT_SYMBOL(omap_mcbsp_set_io_type);
1020 EXPORT_SYMBOL(omap_mcbsp_free);
1021 EXPORT_SYMBOL(omap_mcbsp_start);
1022 EXPORT_SYMBOL(omap_mcbsp_stop);
1023 EXPORT_SYMBOL(omap_mcbsp_xmit_word);
1024 EXPORT_SYMBOL(omap_mcbsp_recv_word);
1025 EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
1026 EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
1027 EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
1028 EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
1029 EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);