2 * linux/arch/arm/plat-omap/mcbsp.c
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
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.
12 * Multichannel mode not supported.
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>
24 #include <asm/delay.h>
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>
34 #ifdef CONFIG_MCBSP_DEBUG
35 #define DBG(x...) printk(x)
37 #define DBG(x...) do { } while (0)
44 omap_mcbsp_word_length rx_word_length;
45 omap_mcbsp_word_length tx_word_length;
57 /* Completion queues */
58 struct completion tx_irq_completion;
59 struct completion rx_irq_completion;
60 struct completion tx_dma_completion;
61 struct completion rx_dma_completion;
66 static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
67 #ifdef CONFIG_ARCH_OMAP1
68 static struct clk *mcbsp_dsp_ck = 0;
69 static struct clk *mcbsp_api_ck = 0;
70 static struct clk *mcbsp_dspxor_ck = 0;
72 #ifdef CONFIG_ARCH_OMAP2
73 static struct clk *mcbsp1_ick = 0;
74 static struct clk *mcbsp1_fck = 0;
75 static struct clk *mcbsp2_ick = 0;
76 static struct clk *mcbsp2_fck = 0;
77 static struct clk *sys_ck = 0;
78 static struct clk *sys_clkout = 0;
81 static void omap_mcbsp_dump_reg(u8 id)
83 DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
84 DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
85 DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
86 DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
87 DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
88 DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
89 DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
90 DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
91 DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
92 DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
93 DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
94 DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
95 DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
96 DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
97 DBG("***********************\n");
100 static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
102 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
104 DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
106 complete(&mcbsp_tx->tx_irq_completion);
110 static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
112 struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
114 DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
116 complete(&mcbsp_rx->rx_irq_completion);
120 static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
122 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
124 DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
126 /* We can free the channels */
127 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
128 mcbsp_dma_tx->dma_tx_lch = -1;
130 complete(&mcbsp_dma_tx->tx_dma_completion);
133 static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
135 struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
137 DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
139 /* We can free the channels */
140 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
141 mcbsp_dma_rx->dma_rx_lch = -1;
143 complete(&mcbsp_dma_rx->rx_dma_completion);
148 * omap_mcbsp_config simply write a config to the
150 * You either call this function or set the McBSP registers
151 * by yourself before calling omap_mcbsp_start().
154 void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
156 u32 io_base = mcbsp[id].io_base;
158 DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
160 /* We write the given config */
161 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
162 OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
163 OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
164 OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
165 OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
166 OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
167 OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
168 OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
169 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
170 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
171 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
176 static int omap_mcbsp_check(unsigned int id)
178 if (cpu_is_omap730()) {
179 if (id > OMAP_MAX_MCBSP_COUNT - 1) {
180 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
186 if (cpu_is_omap1510() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
187 if (id > OMAP_MAX_MCBSP_COUNT) {
188 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
197 #ifdef CONFIG_ARCH_OMAP1
198 static void omap_mcbsp_dsp_request(void)
200 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
201 omap_dsp_request_mem();
202 clk_enable(mcbsp_dsp_ck);
203 clk_enable(mcbsp_api_ck);
205 /* enable 12MHz clock to mcbsp 1 & 3 */
206 clk_enable(mcbsp_dspxor_ck);
209 * DSP external peripheral reset
210 * FIXME: This should be moved to dsp code
212 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
217 static void omap_mcbsp_dsp_free(void)
219 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
220 omap_dsp_release_mem();
221 clk_disable(mcbsp_dspxor_ck);
222 clk_disable(mcbsp_dsp_ck);
223 clk_disable(mcbsp_api_ck);
228 #ifdef CONFIG_ARCH_OMAP2
229 static void omap2_mcbsp2_mux_setup(void)
231 omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
232 omap_cfg_reg(R14_24XX_MCBSP2_FSX);
233 omap_cfg_reg(W15_24XX_MCBSP2_DR);
234 omap_cfg_reg(V15_24XX_MCBSP2_DX);
235 omap_cfg_reg(V14_24XX_GPIO117);
236 omap_cfg_reg(W14_24XX_SYS_CLKOUT);
240 int omap_mcbsp_request(unsigned int id)
244 if (omap_mcbsp_check(id) < 0)
247 #ifdef CONFIG_ARCH_OMAP1
249 * On 1510, 1610 and 1710, McBSP1 and McBSP3
250 * are DSP public peripherals.
252 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
253 omap_mcbsp_dsp_request();
256 #ifdef CONFIG_ARCH_OMAP2
257 if (cpu_is_omap24xx()) {
258 if (id == OMAP_MCBSP1) {
259 clk_enable(mcbsp1_ick);
260 clk_enable(mcbsp1_fck);
262 clk_enable(mcbsp2_ick);
263 clk_enable(mcbsp2_fck);
268 spin_lock(&mcbsp[id].lock);
269 if (!mcbsp[id].free) {
270 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
271 spin_unlock(&mcbsp[id].lock);
276 spin_unlock(&mcbsp[id].lock);
278 /* We need to get IRQs here */
279 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
281 (void *) (&mcbsp[id]));
283 printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
284 mcbsp[id].tx_irq, mcbsp[id].id);
288 init_completion(&(mcbsp[id].tx_irq_completion));
291 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
293 (void *) (&mcbsp[id]));
295 printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
296 mcbsp[id].rx_irq, mcbsp[id].id);
297 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
301 init_completion(&(mcbsp[id].rx_irq_completion));
306 void omap_mcbsp_free(unsigned int id)
308 if (omap_mcbsp_check(id) < 0)
311 #ifdef CONFIG_ARCH_OMAP1
312 if (cpu_class_is_omap1()) {
313 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
314 omap_mcbsp_dsp_free();
318 #ifdef CONFIG_ARCH_OMAP2
319 if (cpu_is_omap24xx()) {
320 if (id == OMAP_MCBSP1) {
321 clk_disable(mcbsp1_ick);
322 clk_disable(mcbsp1_fck);
324 clk_disable(mcbsp2_ick);
325 clk_disable(mcbsp2_fck);
330 spin_lock(&mcbsp[id].lock);
331 if (mcbsp[id].free) {
332 printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
333 spin_unlock(&mcbsp[id].lock);
338 spin_unlock(&mcbsp[id].lock);
341 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
342 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
346 * Here we start the McBSP, by enabling the sample
347 * generator, both transmitter and receivers,
348 * and the frame sync.
350 void omap_mcbsp_start(unsigned int id)
355 if (omap_mcbsp_check(id) < 0)
358 io_base = mcbsp[id].io_base;
360 mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
361 mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
363 /* Start the sample generator */
364 w = OMAP_MCBSP_READ(io_base, SPCR2);
365 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
367 /* Enable transmitter and receiver */
368 w = OMAP_MCBSP_READ(io_base, SPCR2);
369 OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
371 w = OMAP_MCBSP_READ(io_base, SPCR1);
372 OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
376 /* Start frame sync */
377 w = OMAP_MCBSP_READ(io_base, SPCR2);
378 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
380 /* Dump McBSP Regs */
381 omap_mcbsp_dump_reg(id);
385 void omap_mcbsp_stop(unsigned int id)
390 if (omap_mcbsp_check(id) < 0)
393 io_base = mcbsp[id].io_base;
395 /* Reset transmitter */
396 w = OMAP_MCBSP_READ(io_base, SPCR2);
397 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
400 w = OMAP_MCBSP_READ(io_base, SPCR1);
401 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
403 /* Reset the sample rate generator */
404 w = OMAP_MCBSP_READ(io_base, SPCR2);
405 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
409 /* polled mcbsp i/o operations */
410 int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
412 u32 base = mcbsp[id].io_base;
413 writew(buf, base + OMAP_MCBSP_REG_DXR1);
414 /* if frame sync error - clear the error */
415 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
417 writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
418 base + OMAP_MCBSP_REG_SPCR2);
422 /* wait for transmit confirmation */
424 while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
425 if (attemps++ > 1000) {
426 writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
428 base + OMAP_MCBSP_REG_SPCR2);
430 writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
432 base + OMAP_MCBSP_REG_SPCR2);
435 " Could not write to McBSP Register\n");
443 int omap_mcbsp_pollread(unsigned int id, u16 * buf)
445 u32 base = mcbsp[id].io_base;
446 /* if frame sync error - clear the error */
447 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
449 writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
450 base + OMAP_MCBSP_REG_SPCR1);
454 /* wait for recieve confirmation */
456 while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
457 if (attemps++ > 1000) {
458 writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
460 base + OMAP_MCBSP_REG_SPCR1);
462 writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
464 base + OMAP_MCBSP_REG_SPCR1);
467 " Could not read from McBSP Register\n");
472 *buf = readw(base + OMAP_MCBSP_REG_DRR1);
477 * IRQ based word transmission.
479 void omap_mcbsp_xmit_word(unsigned int id, u32 word)
482 omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
484 if (omap_mcbsp_check(id) < 0)
487 io_base = mcbsp[id].io_base;
489 wait_for_completion(&(mcbsp[id].tx_irq_completion));
491 if (word_length > OMAP_MCBSP_WORD_16)
492 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
493 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
496 u32 omap_mcbsp_recv_word(unsigned int id)
499 u16 word_lsb, word_msb = 0;
500 omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
502 if (omap_mcbsp_check(id) < 0)
505 io_base = mcbsp[id].io_base;
507 wait_for_completion(&(mcbsp[id].rx_irq_completion));
509 if (word_length > OMAP_MCBSP_WORD_16)
510 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
511 word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
513 return (word_lsb | (word_msb << 16));
518 * Simple DMA based buffer rx/tx routines.
519 * Nothing fancy, just a single buffer tx/rx through DMA.
520 * The DMA resources are released once the transfer is done.
521 * For anything fancier, you should use your own customized DMA
522 * routines and callbacks.
524 int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
531 if (omap_mcbsp_check(id) < 0)
534 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
537 printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
540 mcbsp[id].dma_tx_lch = dma_tx_ch;
542 DBG("TX DMA on channel %d\n", dma_tx_ch);
544 init_completion(&(mcbsp[id].tx_dma_completion));
546 if (cpu_class_is_omap1()) {
547 src_port = OMAP_DMA_PORT_TIPB;
548 dest_port = OMAP_DMA_PORT_EMIFF;
550 if (cpu_is_omap24xx())
551 sync_dev = mcbsp[id].dma_tx_sync;
553 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
554 OMAP_DMA_DATA_TYPE_S16,
556 OMAP_DMA_SYNC_ELEMENT,
559 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
561 OMAP_DMA_AMODE_CONSTANT,
562 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
565 omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
567 OMAP_DMA_AMODE_POST_INC,
571 omap_start_dma(mcbsp[id].dma_tx_lch);
572 wait_for_completion(&(mcbsp[id].tx_dma_completion));
577 int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
584 if (omap_mcbsp_check(id) < 0)
587 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
590 printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
593 mcbsp[id].dma_rx_lch = dma_rx_ch;
595 DBG("RX DMA on channel %d\n", dma_rx_ch);
597 init_completion(&(mcbsp[id].rx_dma_completion));
599 if (cpu_class_is_omap1()) {
600 src_port = OMAP_DMA_PORT_TIPB;
601 dest_port = OMAP_DMA_PORT_EMIFF;
603 if (cpu_is_omap24xx())
604 sync_dev = mcbsp[id].dma_rx_sync;
606 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
607 OMAP_DMA_DATA_TYPE_S16,
609 OMAP_DMA_SYNC_ELEMENT,
612 omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
614 OMAP_DMA_AMODE_CONSTANT,
615 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
618 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
620 OMAP_DMA_AMODE_POST_INC,
624 omap_start_dma(mcbsp[id].dma_rx_lch);
625 wait_for_completion(&(mcbsp[id].rx_dma_completion));
632 * Since SPI setup is much simpler than the generic McBSP one,
633 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
634 * Once this is done, you can call omap_mcbsp_start().
636 void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
638 struct omap_mcbsp_reg_cfg mcbsp_cfg;
640 if (omap_mcbsp_check(id) < 0)
643 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
645 /* SPI has only one frame */
646 mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
647 mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
649 /* Clock stop mode */
650 if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
651 mcbsp_cfg.spcr1 |= (1 << 12);
653 mcbsp_cfg.spcr1 |= (3 << 11);
655 /* Set clock parities */
656 if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
657 mcbsp_cfg.pcr0 |= CLKRP;
659 mcbsp_cfg.pcr0 &= ~CLKRP;
661 if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
662 mcbsp_cfg.pcr0 &= ~CLKXP;
664 mcbsp_cfg.pcr0 |= CLKXP;
666 /* Set SCLKME to 0 and CLKSM to 1 */
667 mcbsp_cfg.pcr0 &= ~SCLKME;
668 mcbsp_cfg.srgr2 |= CLKSM;
671 if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
672 mcbsp_cfg.pcr0 &= ~FSXP;
674 mcbsp_cfg.pcr0 |= FSXP;
676 if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
677 mcbsp_cfg.pcr0 |= CLKXM;
678 mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
679 mcbsp_cfg.pcr0 |= FSXM;
680 mcbsp_cfg.srgr2 &= ~FSGM;
681 mcbsp_cfg.xcr2 |= XDATDLY(1);
682 mcbsp_cfg.rcr2 |= RDATDLY(1);
685 mcbsp_cfg.pcr0 &= ~CLKXM;
686 mcbsp_cfg.srgr1 |= CLKGDV(1);
687 mcbsp_cfg.pcr0 &= ~FSXM;
688 mcbsp_cfg.xcr2 &= ~XDATDLY(3);
689 mcbsp_cfg.rcr2 &= ~RDATDLY(3);
692 mcbsp_cfg.xcr2 &= ~XPHASE;
693 mcbsp_cfg.rcr2 &= ~RPHASE;
695 omap_mcbsp_config(id, &mcbsp_cfg);
700 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
701 * 730 has only 2 McBSP, and both of them are MPU peripherals.
703 struct omap_mcbsp_info {
705 u8 dma_rx_sync, dma_tx_sync;
709 #ifdef CONFIG_ARCH_OMAP730
710 static const struct omap_mcbsp_info mcbsp_730[] = {
711 [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
712 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
713 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
714 .rx_irq = INT_730_McBSP1RX,
715 .tx_irq = INT_730_McBSP1TX },
716 [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
717 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
718 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
719 .rx_irq = INT_730_McBSP2RX,
720 .tx_irq = INT_730_McBSP2TX },
724 #ifdef CONFIG_ARCH_OMAP15XX
725 static const struct omap_mcbsp_info mcbsp_1510[] = {
726 [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
727 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
728 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
729 .rx_irq = INT_McBSP1RX,
730 .tx_irq = INT_McBSP1TX },
731 [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
732 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
733 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
734 .rx_irq = INT_1510_SPI_RX,
735 .tx_irq = INT_1510_SPI_TX },
736 [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
737 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
738 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
739 .rx_irq = INT_McBSP3RX,
740 .tx_irq = INT_McBSP3TX },
744 #if defined(CONFIG_ARCH_OMAP16XX)
745 static const struct omap_mcbsp_info mcbsp_1610[] = {
746 [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
747 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
748 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
749 .rx_irq = INT_McBSP1RX,
750 .tx_irq = INT_McBSP1TX },
751 [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
752 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
753 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
754 .rx_irq = INT_1610_McBSP2_RX,
755 .tx_irq = INT_1610_McBSP2_TX },
756 [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
757 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
758 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
759 .rx_irq = INT_McBSP3RX,
760 .tx_irq = INT_McBSP3TX },
764 #if defined(CONFIG_ARCH_OMAP24XX)
765 static const struct omap_mcbsp_info mcbsp_24xx[] = {
766 [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
767 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
768 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
769 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
770 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
772 [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
773 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
774 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
775 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
776 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
781 static int __init omap_mcbsp_init(void)
783 int mcbsp_count = 0, i;
784 static const struct omap_mcbsp_info *mcbsp_info;
786 printk("Initializing OMAP McBSP system\n");
788 #ifdef CONFIG_ARCH_OMAP1
789 mcbsp_dsp_ck = clk_get(0, "dsp_ck");
790 if (IS_ERR(mcbsp_dsp_ck)) {
791 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
792 return PTR_ERR(mcbsp_dsp_ck);
794 mcbsp_api_ck = clk_get(0, "api_ck");
795 if (IS_ERR(mcbsp_api_ck)) {
796 printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
797 return PTR_ERR(mcbsp_api_ck);
799 mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
800 if (IS_ERR(mcbsp_dspxor_ck)) {
801 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
802 return PTR_ERR(mcbsp_dspxor_ck);
805 #ifdef CONFIG_ARCH_OMAP2
806 mcbsp1_ick = clk_get(0, "mcbsp1_ick");
807 if (IS_ERR(mcbsp1_ick)) {
808 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
809 return PTR_ERR(mcbsp1_ick);
811 mcbsp1_fck = clk_get(0, "mcbsp1_fck");
812 if (IS_ERR(mcbsp1_fck)) {
813 printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
814 return PTR_ERR(mcbsp1_fck);
816 mcbsp2_ick = clk_get(0, "mcbsp2_ick");
817 if (IS_ERR(mcbsp2_ick)) {
818 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
819 return PTR_ERR(mcbsp2_ick);
821 mcbsp2_fck = clk_get(0, "mcbsp2_fck");
822 if (IS_ERR(mcbsp2_fck)) {
823 printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
824 return PTR_ERR(mcbsp2_fck);
828 #ifdef CONFIG_ARCH_OMAP730
829 if (cpu_is_omap730()) {
830 mcbsp_info = mcbsp_730;
831 mcbsp_count = ARRAY_SIZE(mcbsp_730);
834 #ifdef CONFIG_ARCH_OMAP15XX
835 if (cpu_is_omap1510()) {
836 mcbsp_info = mcbsp_1510;
837 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
840 #if defined(CONFIG_ARCH_OMAP16XX)
841 if (cpu_is_omap16xx()) {
842 mcbsp_info = mcbsp_1610;
843 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
846 #if defined(CONFIG_ARCH_OMAP24XX)
847 if (cpu_is_omap24xx()) {
848 mcbsp_info = mcbsp_24xx;
849 mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
851 /* REVISIT: where's the right place? */
852 omap2_mcbsp2_mux_setup();
853 sys_ck = clk_get(0, "sys_ck");
854 sys_clkout = clk_get(0, "sys_clkout");
855 clk_set_parent(sys_clkout, sys_ck);
856 clk_enable(sys_clkout);
859 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
860 if (i >= mcbsp_count) {
861 mcbsp[i].io_base = 0;
867 mcbsp[i].dma_tx_lch = -1;
868 mcbsp[i].dma_rx_lch = -1;
870 mcbsp[i].io_base = mcbsp_info[i].virt_base;
871 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
872 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
873 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
874 mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
875 spin_lock_init(&mcbsp[i].lock);
881 arch_initcall(omap_mcbsp_init);
883 EXPORT_SYMBOL(omap_mcbsp_config);
884 EXPORT_SYMBOL(omap_mcbsp_request);
885 EXPORT_SYMBOL(omap_mcbsp_free);
886 EXPORT_SYMBOL(omap_mcbsp_start);
887 EXPORT_SYMBOL(omap_mcbsp_stop);
888 EXPORT_SYMBOL(omap_mcbsp_xmit_word);
889 EXPORT_SYMBOL(omap_mcbsp_recv_word);
890 EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
891 EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
892 EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);