diff options
| -rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 197 |
1 files changed, 102 insertions, 95 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 9cf83c4da9fa..c0018b1b6673 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
| @@ -21,9 +21,7 @@ | |||
| 21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
| 22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | 24 | #include <linux/io.h> | |
| 25 | #include <asm/io.h> | ||
| 26 | #include <asm/irq.h> | ||
| 27 | 25 | ||
| 28 | #include <asm/arch/dma.h> | 26 | #include <asm/arch/dma.h> |
| 29 | #include <asm/arch/mux.h> | 27 | #include <asm/arch/mux.h> |
| @@ -61,20 +59,21 @@ struct omap_mcbsp { | |||
| 61 | struct completion tx_dma_completion; | 59 | struct completion tx_dma_completion; |
| 62 | struct completion rx_dma_completion; | 60 | struct completion rx_dma_completion; |
| 63 | 61 | ||
| 62 | /* Protect the field .free, while checking if the mcbsp is in use */ | ||
| 64 | spinlock_t lock; | 63 | spinlock_t lock; |
| 65 | }; | 64 | }; |
| 66 | 65 | ||
| 67 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; | 66 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; |
| 68 | #ifdef CONFIG_ARCH_OMAP1 | 67 | #ifdef CONFIG_ARCH_OMAP1 |
| 69 | static struct clk *mcbsp_dsp_ck = 0; | 68 | static struct clk *mcbsp_dsp_ck; |
| 70 | static struct clk *mcbsp_api_ck = 0; | 69 | static struct clk *mcbsp_api_ck; |
| 71 | static struct clk *mcbsp_dspxor_ck = 0; | 70 | static struct clk *mcbsp_dspxor_ck; |
| 72 | #endif | 71 | #endif |
| 73 | #ifdef CONFIG_ARCH_OMAP2 | 72 | #ifdef CONFIG_ARCH_OMAP2 |
| 74 | static struct clk *mcbsp1_ick = 0; | 73 | static struct clk *mcbsp1_ick; |
| 75 | static struct clk *mcbsp1_fck = 0; | 74 | static struct clk *mcbsp1_fck; |
| 76 | static struct clk *mcbsp2_ick = 0; | 75 | static struct clk *mcbsp2_ick; |
| 77 | static struct clk *mcbsp2_fck = 0; | 76 | static struct clk *mcbsp2_fck; |
| 78 | #endif | 77 | #endif |
| 79 | 78 | ||
| 80 | static void omap_mcbsp_dump_reg(u8 id) | 79 | static void omap_mcbsp_dump_reg(u8 id) |
| @@ -104,6 +103,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | |||
| 104 | OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); | 103 | OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); |
| 105 | 104 | ||
| 106 | complete(&mcbsp_tx->tx_irq_completion); | 105 | complete(&mcbsp_tx->tx_irq_completion); |
| 106 | |||
| 107 | return IRQ_HANDLED; | 107 | return IRQ_HANDLED; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -115,6 +115,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | |||
| 115 | OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); | 115 | OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); |
| 116 | 116 | ||
| 117 | complete(&mcbsp_rx->rx_irq_completion); | 117 | complete(&mcbsp_rx->rx_irq_completion); |
| 118 | |||
| 118 | return IRQ_HANDLED; | 119 | return IRQ_HANDLED; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| @@ -146,19 +147,17 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) | |||
| 146 | complete(&mcbsp_dma_rx->rx_dma_completion); | 147 | complete(&mcbsp_dma_rx->rx_dma_completion); |
| 147 | } | 148 | } |
| 148 | 149 | ||
| 149 | |||
| 150 | /* | 150 | /* |
| 151 | * omap_mcbsp_config simply write a config to the | 151 | * omap_mcbsp_config simply write a config to the |
| 152 | * appropriate McBSP. | 152 | * appropriate McBSP. |
| 153 | * You either call this function or set the McBSP registers | 153 | * You either call this function or set the McBSP registers |
| 154 | * by yourself before calling omap_mcbsp_start(). | 154 | * by yourself before calling omap_mcbsp_start(). |
| 155 | */ | 155 | */ |
| 156 | 156 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | |
| 157 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config) | ||
| 158 | { | 157 | { |
| 159 | u32 io_base = mcbsp[id].io_base; | 158 | u32 io_base = mcbsp[id].io_base; |
| 160 | 159 | ||
| 161 | DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base); | 160 | DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id + 1, io_base); |
| 162 | 161 | ||
| 163 | /* We write the given config */ | 162 | /* We write the given config */ |
| 164 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); | 163 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); |
| @@ -173,14 +172,14 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config | |||
| 173 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); | 172 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); |
| 174 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); | 173 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); |
| 175 | } | 174 | } |
| 176 | 175 | EXPORT_SYMBOL(omap_mcbsp_config); | |
| 177 | |||
| 178 | 176 | ||
| 179 | static int omap_mcbsp_check(unsigned int id) | 177 | static int omap_mcbsp_check(unsigned int id) |
| 180 | { | 178 | { |
| 181 | if (cpu_is_omap730()) { | 179 | if (cpu_is_omap730()) { |
| 182 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | 180 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { |
| 183 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | 181 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", |
| 182 | id + 1); | ||
| 184 | return -1; | 183 | return -1; |
| 185 | } | 184 | } |
| 186 | return 0; | 185 | return 0; |
| @@ -188,7 +187,8 @@ static int omap_mcbsp_check(unsigned int id) | |||
| 188 | 187 | ||
| 189 | if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { | 188 | if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { |
| 190 | if (id > OMAP_MAX_MCBSP_COUNT) { | 189 | if (id > OMAP_MAX_MCBSP_COUNT) { |
| 191 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | 190 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", |
| 191 | id + 1); | ||
| 192 | return -1; | 192 | return -1; |
| 193 | } | 193 | } |
| 194 | return 0; | 194 | return 0; |
| @@ -263,7 +263,8 @@ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | |||
| 263 | spin_lock(&mcbsp[id].lock); | 263 | spin_lock(&mcbsp[id].lock); |
| 264 | 264 | ||
| 265 | if (!mcbsp[id].free) { | 265 | if (!mcbsp[id].free) { |
| 266 | printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); | 266 | printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", |
| 267 | id + 1); | ||
| 267 | spin_unlock(&mcbsp[id].lock); | 268 | spin_unlock(&mcbsp[id].lock); |
| 268 | return -EINVAL; | 269 | return -EINVAL; |
| 269 | } | 270 | } |
| @@ -274,6 +275,7 @@ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | |||
| 274 | 275 | ||
| 275 | return 0; | 276 | return 0; |
| 276 | } | 277 | } |
| 278 | EXPORT_SYMBOL(omap_mcbsp_set_io_type); | ||
| 277 | 279 | ||
| 278 | int omap_mcbsp_request(unsigned int id) | 280 | int omap_mcbsp_request(unsigned int id) |
| 279 | { | 281 | { |
| @@ -305,7 +307,8 @@ int omap_mcbsp_request(unsigned int id) | |||
| 305 | 307 | ||
| 306 | spin_lock(&mcbsp[id].lock); | 308 | spin_lock(&mcbsp[id].lock); |
| 307 | if (!mcbsp[id].free) { | 309 | if (!mcbsp[id].free) { |
| 308 | printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); | 310 | printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", |
| 311 | id + 1); | ||
| 309 | spin_unlock(&mcbsp[id].lock); | 312 | spin_unlock(&mcbsp[id].lock); |
| 310 | return -1; | 313 | return -1; |
| 311 | } | 314 | } |
| @@ -315,24 +318,23 @@ int omap_mcbsp_request(unsigned int id) | |||
| 315 | 318 | ||
| 316 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { | 319 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { |
| 317 | /* We need to get IRQs here */ | 320 | /* We need to get IRQs here */ |
| 318 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, | 321 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, |
| 319 | "McBSP", | 322 | 0, "McBSP", (void *) (&mcbsp[id])); |
| 320 | (void *) (&mcbsp[id])); | ||
| 321 | if (err != 0) { | 323 | if (err != 0) { |
| 322 | printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", | 324 | printk(KERN_ERR "OMAP-McBSP: Unable to " |
| 323 | mcbsp[id].tx_irq, mcbsp[id].id); | 325 | "request TX IRQ %d for McBSP%d\n", |
| 326 | mcbsp[id].tx_irq, mcbsp[id].id); | ||
| 324 | return err; | 327 | return err; |
| 325 | } | 328 | } |
| 326 | 329 | ||
| 327 | init_completion(&(mcbsp[id].tx_irq_completion)); | 330 | init_completion(&(mcbsp[id].tx_irq_completion)); |
| 328 | 331 | ||
| 329 | 332 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, | |
| 330 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, | 333 | 0, "McBSP", (void *) (&mcbsp[id])); |
| 331 | "McBSP", | ||
| 332 | (void *) (&mcbsp[id])); | ||
| 333 | if (err != 0) { | 334 | if (err != 0) { |
| 334 | printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", | 335 | printk(KERN_ERR "OMAP-McBSP: Unable to " |
| 335 | mcbsp[id].rx_irq, mcbsp[id].id); | 336 | "request RX IRQ %d for McBSP%d\n", |
| 337 | mcbsp[id].rx_irq, mcbsp[id].id); | ||
| 336 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 338 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); |
| 337 | return err; | 339 | return err; |
| 338 | } | 340 | } |
| @@ -341,8 +343,8 @@ int omap_mcbsp_request(unsigned int id) | |||
| 341 | } | 343 | } |
| 342 | 344 | ||
| 343 | return 0; | 345 | return 0; |
| 344 | |||
| 345 | } | 346 | } |
| 347 | EXPORT_SYMBOL(omap_mcbsp_request); | ||
| 346 | 348 | ||
| 347 | void omap_mcbsp_free(unsigned int id) | 349 | void omap_mcbsp_free(unsigned int id) |
| 348 | { | 350 | { |
| @@ -370,7 +372,8 @@ void omap_mcbsp_free(unsigned int id) | |||
| 370 | 372 | ||
| 371 | spin_lock(&mcbsp[id].lock); | 373 | spin_lock(&mcbsp[id].lock); |
| 372 | if (mcbsp[id].free) { | 374 | if (mcbsp[id].free) { |
| 373 | printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1); | 375 | printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", |
| 376 | id + 1); | ||
| 374 | spin_unlock(&mcbsp[id].lock); | 377 | spin_unlock(&mcbsp[id].lock); |
| 375 | return; | 378 | return; |
| 376 | } | 379 | } |
| @@ -384,6 +387,7 @@ void omap_mcbsp_free(unsigned int id) | |||
| 384 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 387 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); |
| 385 | } | 388 | } |
| 386 | } | 389 | } |
| 390 | EXPORT_SYMBOL(omap_mcbsp_free); | ||
| 387 | 391 | ||
| 388 | /* | 392 | /* |
| 389 | * Here we start the McBSP, by enabling the sample | 393 | * Here we start the McBSP, by enabling the sample |
| @@ -400,8 +404,8 @@ void omap_mcbsp_start(unsigned int id) | |||
| 400 | 404 | ||
| 401 | io_base = mcbsp[id].io_base; | 405 | io_base = mcbsp[id].io_base; |
| 402 | 406 | ||
| 403 | mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7); | 407 | mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; |
| 404 | mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7); | 408 | mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; |
| 405 | 409 | ||
| 406 | /* Start the sample generator */ | 410 | /* Start the sample generator */ |
| 407 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 411 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| @@ -422,8 +426,8 @@ void omap_mcbsp_start(unsigned int id) | |||
| 422 | 426 | ||
| 423 | /* Dump McBSP Regs */ | 427 | /* Dump McBSP Regs */ |
| 424 | omap_mcbsp_dump_reg(id); | 428 | omap_mcbsp_dump_reg(id); |
| 425 | |||
| 426 | } | 429 | } |
| 430 | EXPORT_SYMBOL(omap_mcbsp_start); | ||
| 427 | 431 | ||
| 428 | void omap_mcbsp_stop(unsigned int id) | 432 | void omap_mcbsp_stop(unsigned int id) |
| 429 | { | 433 | { |
| @@ -435,7 +439,7 @@ void omap_mcbsp_stop(unsigned int id) | |||
| 435 | 439 | ||
| 436 | io_base = mcbsp[id].io_base; | 440 | io_base = mcbsp[id].io_base; |
| 437 | 441 | ||
| 438 | /* Reset transmitter */ | 442 | /* Reset transmitter */ |
| 439 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 443 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| 440 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); | 444 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); |
| 441 | 445 | ||
| @@ -447,7 +451,7 @@ void omap_mcbsp_stop(unsigned int id) | |||
| 447 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 451 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| 448 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); | 452 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); |
| 449 | } | 453 | } |
| 450 | 454 | EXPORT_SYMBOL(omap_mcbsp_stop); | |
| 451 | 455 | ||
| 452 | /* polled mcbsp i/o operations */ | 456 | /* polled mcbsp i/o operations */ |
| 453 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | 457 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) |
| @@ -480,10 +484,12 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | |||
| 480 | } | 484 | } |
| 481 | } | 485 | } |
| 482 | } | 486 | } |
| 487 | |||
| 483 | return 0; | 488 | return 0; |
| 484 | } | 489 | } |
| 490 | EXPORT_SYMBOL(omap_mcbsp_pollwrite); | ||
| 485 | 491 | ||
| 486 | int omap_mcbsp_pollread(unsigned int id, u16 * buf) | 492 | int omap_mcbsp_pollread(unsigned int id, u16 *buf) |
| 487 | { | 493 | { |
| 488 | u32 base = mcbsp[id].io_base; | 494 | u32 base = mcbsp[id].io_base; |
| 489 | /* if frame sync error - clear the error */ | 495 | /* if frame sync error - clear the error */ |
| @@ -513,8 +519,10 @@ int omap_mcbsp_pollread(unsigned int id, u16 * buf) | |||
| 513 | } | 519 | } |
| 514 | } | 520 | } |
| 515 | *buf = readw(base + OMAP_MCBSP_REG_DRR1); | 521 | *buf = readw(base + OMAP_MCBSP_REG_DRR1); |
| 522 | |||
| 516 | return 0; | 523 | return 0; |
| 517 | } | 524 | } |
| 525 | EXPORT_SYMBOL(omap_mcbsp_pollread); | ||
| 518 | 526 | ||
| 519 | /* | 527 | /* |
| 520 | * IRQ based word transmission. | 528 | * IRQ based word transmission. |
| @@ -535,6 +543,7 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word) | |||
| 535 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); | 543 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); |
| 536 | OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); | 544 | OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); |
| 537 | } | 545 | } |
| 546 | EXPORT_SYMBOL(omap_mcbsp_xmit_word); | ||
| 538 | 547 | ||
| 539 | u32 omap_mcbsp_recv_word(unsigned int id) | 548 | u32 omap_mcbsp_recv_word(unsigned int id) |
| 540 | { | 549 | { |
| @@ -555,7 +564,7 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
| 555 | 564 | ||
| 556 | return (word_lsb | (word_msb << 16)); | 565 | return (word_lsb | (word_msb << 16)); |
| 557 | } | 566 | } |
| 558 | 567 | EXPORT_SYMBOL(omap_mcbsp_recv_word); | |
| 559 | 568 | ||
| 560 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | 569 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) |
| 561 | { | 570 | { |
| @@ -577,7 +586,7 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
| 577 | udelay(10); | 586 | udelay(10); |
| 578 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 587 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
| 579 | udelay(10); | 588 | udelay(10); |
| 580 | printk("McBSP transmitter not ready\n"); | 589 | printk(KERN_ERR "McBSP transmitter not ready\n"); |
| 581 | return -EAGAIN; | 590 | return -EAGAIN; |
| 582 | } | 591 | } |
| 583 | } | 592 | } |
| @@ -597,7 +606,7 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
| 597 | udelay(10); | 606 | udelay(10); |
| 598 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 607 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
| 599 | udelay(10); | 608 | udelay(10); |
| 600 | printk("McBSP receiver not ready\n"); | 609 | printk(KERN_ERR "McBSP receiver not ready\n"); |
| 601 | return -EAGAIN; | 610 | return -EAGAIN; |
| 602 | } | 611 | } |
| 603 | } | 612 | } |
| @@ -609,8 +618,9 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
| 609 | 618 | ||
| 610 | return 0; | 619 | return 0; |
| 611 | } | 620 | } |
| 621 | EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | ||
| 612 | 622 | ||
| 613 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | 623 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) |
| 614 | { | 624 | { |
| 615 | u32 io_base = mcbsp[id].io_base, clock_word = 0; | 625 | u32 io_base = mcbsp[id].io_base, clock_word = 0; |
| 616 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | 626 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; |
| @@ -630,7 +640,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | |||
| 630 | udelay(10); | 640 | udelay(10); |
| 631 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 641 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
| 632 | udelay(10); | 642 | udelay(10); |
| 633 | printk("McBSP transmitter not ready\n"); | 643 | printk(KERN_ERR "McBSP transmitter not ready\n"); |
| 634 | return -EAGAIN; | 644 | return -EAGAIN; |
| 635 | } | 645 | } |
| 636 | } | 646 | } |
| @@ -650,7 +660,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | |||
| 650 | udelay(10); | 660 | udelay(10); |
| 651 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 661 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
| 652 | udelay(10); | 662 | udelay(10); |
| 653 | printk("McBSP receiver not ready\n"); | 663 | printk(KERN_ERR "McBSP receiver not ready\n"); |
| 654 | return -EAGAIN; | 664 | return -EAGAIN; |
| 655 | } | 665 | } |
| 656 | } | 666 | } |
| @@ -664,7 +674,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | |||
| 664 | 674 | ||
| 665 | return 0; | 675 | return 0; |
| 666 | } | 676 | } |
| 667 | 677 | EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); | |
| 668 | 678 | ||
| 669 | /* | 679 | /* |
| 670 | * Simple DMA based buffer rx/tx routines. | 680 | * Simple DMA based buffer rx/tx routines. |
| @@ -673,7 +683,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | |||
| 673 | * For anything fancier, you should use your own customized DMA | 683 | * For anything fancier, you should use your own customized DMA |
| 674 | * routines and callbacks. | 684 | * routines and callbacks. |
| 675 | */ | 685 | */ |
| 676 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 686 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, |
| 687 | unsigned int length) | ||
| 677 | { | 688 | { |
| 678 | int dma_tx_ch; | 689 | int dma_tx_ch; |
| 679 | int src_port = 0; | 690 | int src_port = 0; |
| @@ -683,10 +694,12 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 683 | if (omap_mcbsp_check(id) < 0) | 694 | if (omap_mcbsp_check(id) < 0) |
| 684 | return -EINVAL; | 695 | return -EINVAL; |
| 685 | 696 | ||
| 686 | if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback, | 697 | if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", |
| 687 | &mcbsp[id], | 698 | omap_mcbsp_tx_dma_callback, |
| 688 | &dma_tx_ch)) { | 699 | &mcbsp[id], |
| 689 | printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1); | 700 | &dma_tx_ch)) { |
| 701 | printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for" | ||
| 702 | " McBSP%d TX. Trying IRQ based TX\n", id + 1); | ||
| 690 | return -EAGAIN; | 703 | return -EAGAIN; |
| 691 | } | 704 | } |
| 692 | mcbsp[id].dma_tx_lch = dma_tx_ch; | 705 | mcbsp[id].dma_tx_lch = dma_tx_ch; |
| @@ -722,11 +735,13 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 722 | 735 | ||
| 723 | omap_start_dma(mcbsp[id].dma_tx_lch); | 736 | omap_start_dma(mcbsp[id].dma_tx_lch); |
| 724 | wait_for_completion(&(mcbsp[id].tx_dma_completion)); | 737 | wait_for_completion(&(mcbsp[id].tx_dma_completion)); |
| 738 | |||
| 725 | return 0; | 739 | return 0; |
| 726 | } | 740 | } |
| 741 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); | ||
| 727 | 742 | ||
| 728 | 743 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, | |
| 729 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 744 | unsigned int length) |
| 730 | { | 745 | { |
| 731 | int dma_rx_ch; | 746 | int dma_rx_ch; |
| 732 | int src_port = 0; | 747 | int src_port = 0; |
| @@ -736,10 +751,12 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 736 | if (omap_mcbsp_check(id) < 0) | 751 | if (omap_mcbsp_check(id) < 0) |
| 737 | return -EINVAL; | 752 | return -EINVAL; |
| 738 | 753 | ||
| 739 | if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback, | 754 | if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", |
| 740 | &mcbsp[id], | 755 | omap_mcbsp_rx_dma_callback, |
| 741 | &dma_rx_ch)) { | 756 | &mcbsp[id], |
| 742 | printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1); | 757 | &dma_rx_ch)) { |
| 758 | printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX." | ||
| 759 | " Trying IRQ based RX\n", id + 1); | ||
| 743 | return -EAGAIN; | 760 | return -EAGAIN; |
| 744 | } | 761 | } |
| 745 | mcbsp[id].dma_rx_lch = dma_rx_ch; | 762 | mcbsp[id].dma_rx_lch = dma_rx_ch; |
| @@ -756,10 +773,10 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 756 | sync_dev = mcbsp[id].dma_rx_sync; | 773 | sync_dev = mcbsp[id].dma_rx_sync; |
| 757 | 774 | ||
| 758 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 775 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, |
| 759 | OMAP_DMA_DATA_TYPE_S16, | 776 | OMAP_DMA_DATA_TYPE_S16, |
| 760 | length >> 1, 1, | 777 | length >> 1, 1, |
| 761 | OMAP_DMA_SYNC_ELEMENT, | 778 | OMAP_DMA_SYNC_ELEMENT, |
| 762 | sync_dev, 0); | 779 | sync_dev, 0); |
| 763 | 780 | ||
| 764 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, | 781 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, |
| 765 | src_port, | 782 | src_port, |
| @@ -768,16 +785,17 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 768 | 0, 0); | 785 | 0, 0); |
| 769 | 786 | ||
| 770 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, | 787 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, |
| 771 | dest_port, | 788 | dest_port, |
| 772 | OMAP_DMA_AMODE_POST_INC, | 789 | OMAP_DMA_AMODE_POST_INC, |
| 773 | buffer, | 790 | buffer, |
| 774 | 0, 0); | 791 | 0, 0); |
| 775 | 792 | ||
| 776 | omap_start_dma(mcbsp[id].dma_rx_lch); | 793 | omap_start_dma(mcbsp[id].dma_rx_lch); |
| 777 | wait_for_completion(&(mcbsp[id].rx_dma_completion)); | 794 | wait_for_completion(&(mcbsp[id].rx_dma_completion)); |
| 795 | |||
| 778 | return 0; | 796 | return 0; |
| 779 | } | 797 | } |
| 780 | 798 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); | |
| 781 | 799 | ||
| 782 | /* | 800 | /* |
| 783 | * SPI wrapper. | 801 | * SPI wrapper. |
| @@ -785,7 +803,8 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 785 | * this wrapper just need an omap_mcbsp_spi_cfg structure as an input. | 803 | * this wrapper just need an omap_mcbsp_spi_cfg structure as an input. |
| 786 | * Once this is done, you can call omap_mcbsp_start(). | 804 | * Once this is done, you can call omap_mcbsp_start(). |
| 787 | */ | 805 | */ |
| 788 | void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg) | 806 | void omap_mcbsp_set_spi_mode(unsigned int id, |
| 807 | const struct omap_mcbsp_spi_cfg *spi_cfg) | ||
| 789 | { | 808 | { |
| 790 | struct omap_mcbsp_reg_cfg mcbsp_cfg; | 809 | struct omap_mcbsp_reg_cfg mcbsp_cfg; |
| 791 | 810 | ||
| @@ -798,7 +817,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * | |||
| 798 | mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0)); | 817 | mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0)); |
| 799 | mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0)); | 818 | mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0)); |
| 800 | 819 | ||
| 801 | /* Clock stop mode */ | 820 | /* Clock stop mode */ |
| 802 | if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY) | 821 | if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY) |
| 803 | mcbsp_cfg.spcr1 |= (1 << 12); | 822 | mcbsp_cfg.spcr1 |= (1 << 12); |
| 804 | else | 823 | else |
| @@ -827,13 +846,12 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * | |||
| 827 | 846 | ||
| 828 | if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) { | 847 | if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) { |
| 829 | mcbsp_cfg.pcr0 |= CLKXM; | 848 | mcbsp_cfg.pcr0 |= CLKXM; |
| 830 | mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1); | 849 | mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1); |
| 831 | mcbsp_cfg.pcr0 |= FSXM; | 850 | mcbsp_cfg.pcr0 |= FSXM; |
| 832 | mcbsp_cfg.srgr2 &= ~FSGM; | 851 | mcbsp_cfg.srgr2 &= ~FSGM; |
| 833 | mcbsp_cfg.xcr2 |= XDATDLY(1); | 852 | mcbsp_cfg.xcr2 |= XDATDLY(1); |
| 834 | mcbsp_cfg.rcr2 |= RDATDLY(1); | 853 | mcbsp_cfg.rcr2 |= RDATDLY(1); |
| 835 | } | 854 | } else { |
| 836 | else { | ||
| 837 | mcbsp_cfg.pcr0 &= ~CLKXM; | 855 | mcbsp_cfg.pcr0 &= ~CLKXM; |
| 838 | mcbsp_cfg.srgr1 |= CLKGDV(1); | 856 | mcbsp_cfg.srgr1 |= CLKGDV(1); |
| 839 | mcbsp_cfg.pcr0 &= ~FSXM; | 857 | mcbsp_cfg.pcr0 &= ~FSXM; |
| @@ -846,7 +864,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * | |||
| 846 | 864 | ||
| 847 | omap_mcbsp_config(id, &mcbsp_cfg); | 865 | omap_mcbsp_config(id, &mcbsp_cfg); |
| 848 | } | 866 | } |
| 849 | 867 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | |
| 850 | 868 | ||
| 851 | /* | 869 | /* |
| 852 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. | 870 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. |
| @@ -935,7 +953,7 @@ static int __init omap_mcbsp_init(void) | |||
| 935 | int mcbsp_count = 0, i; | 953 | int mcbsp_count = 0, i; |
| 936 | static const struct omap_mcbsp_info *mcbsp_info; | 954 | static const struct omap_mcbsp_info *mcbsp_info; |
| 937 | 955 | ||
| 938 | printk("Initializing OMAP McBSP system\n"); | 956 | printk(KERN_INFO "Initializing OMAP McBSP system\n"); |
| 939 | 957 | ||
| 940 | #ifdef CONFIG_ARCH_OMAP1 | 958 | #ifdef CONFIG_ARCH_OMAP1 |
| 941 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); | 959 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); |
| @@ -957,22 +975,26 @@ static int __init omap_mcbsp_init(void) | |||
| 957 | #ifdef CONFIG_ARCH_OMAP2 | 975 | #ifdef CONFIG_ARCH_OMAP2 |
| 958 | mcbsp1_ick = clk_get(0, "mcbsp1_ick"); | 976 | mcbsp1_ick = clk_get(0, "mcbsp1_ick"); |
| 959 | if (IS_ERR(mcbsp1_ick)) { | 977 | if (IS_ERR(mcbsp1_ick)) { |
| 960 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); | 978 | printk(KERN_ERR "mcbsp: could not acquire " |
| 979 | "mcbsp1_ick handle.\n"); | ||
| 961 | return PTR_ERR(mcbsp1_ick); | 980 | return PTR_ERR(mcbsp1_ick); |
| 962 | } | 981 | } |
| 963 | mcbsp1_fck = clk_get(0, "mcbsp1_fck"); | 982 | mcbsp1_fck = clk_get(0, "mcbsp1_fck"); |
| 964 | if (IS_ERR(mcbsp1_fck)) { | 983 | if (IS_ERR(mcbsp1_fck)) { |
| 965 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); | 984 | printk(KERN_ERR "mcbsp: could not acquire " |
| 985 | "mcbsp1_fck handle.\n"); | ||
| 966 | return PTR_ERR(mcbsp1_fck); | 986 | return PTR_ERR(mcbsp1_fck); |
| 967 | } | 987 | } |
| 968 | mcbsp2_ick = clk_get(0, "mcbsp2_ick"); | 988 | mcbsp2_ick = clk_get(0, "mcbsp2_ick"); |
| 969 | if (IS_ERR(mcbsp2_ick)) { | 989 | if (IS_ERR(mcbsp2_ick)) { |
| 970 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); | 990 | printk(KERN_ERR "mcbsp: could not acquire " |
| 991 | "mcbsp2_ick handle.\n"); | ||
| 971 | return PTR_ERR(mcbsp2_ick); | 992 | return PTR_ERR(mcbsp2_ick); |
| 972 | } | 993 | } |
| 973 | mcbsp2_fck = clk_get(0, "mcbsp2_fck"); | 994 | mcbsp2_fck = clk_get(0, "mcbsp2_fck"); |
| 974 | if (IS_ERR(mcbsp2_fck)) { | 995 | if (IS_ERR(mcbsp2_fck)) { |
| 975 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); | 996 | printk(KERN_ERR "mcbsp: could not acquire " |
| 997 | "mcbsp2_fck handle.\n"); | ||
| 976 | return PTR_ERR(mcbsp2_fck); | 998 | return PTR_ERR(mcbsp2_fck); |
| 977 | } | 999 | } |
| 978 | #endif | 1000 | #endif |
| @@ -1006,7 +1028,7 @@ static int __init omap_mcbsp_init(void) | |||
| 1006 | if (i >= mcbsp_count) { | 1028 | if (i >= mcbsp_count) { |
| 1007 | mcbsp[i].io_base = 0; | 1029 | mcbsp[i].io_base = 0; |
| 1008 | mcbsp[i].free = 0; | 1030 | mcbsp[i].free = 0; |
| 1009 | continue; | 1031 | continue; |
| 1010 | } | 1032 | } |
| 1011 | mcbsp[i].id = i + 1; | 1033 | mcbsp[i].id = i + 1; |
| 1012 | mcbsp[i].free = 1; | 1034 | mcbsp[i].free = 1; |
| @@ -1014,7 +1036,8 @@ static int __init omap_mcbsp_init(void) | |||
| 1014 | mcbsp[i].dma_rx_lch = -1; | 1036 | mcbsp[i].dma_rx_lch = -1; |
| 1015 | 1037 | ||
| 1016 | mcbsp[i].io_base = mcbsp_info[i].virt_base; | 1038 | mcbsp[i].io_base = mcbsp_info[i].virt_base; |
| 1017 | mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ | 1039 | /* Default I/O is IRQ based */ |
| 1040 | mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; | ||
| 1018 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; | 1041 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; |
| 1019 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; | 1042 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; |
| 1020 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; | 1043 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; |
| @@ -1026,19 +1049,3 @@ static int __init omap_mcbsp_init(void) | |||
| 1026 | } | 1049 | } |
| 1027 | 1050 | ||
| 1028 | arch_initcall(omap_mcbsp_init); | 1051 | arch_initcall(omap_mcbsp_init); |
| 1029 | |||
| 1030 | EXPORT_SYMBOL(omap_mcbsp_config); | ||
| 1031 | EXPORT_SYMBOL(omap_mcbsp_request); | ||
| 1032 | EXPORT_SYMBOL(omap_mcbsp_set_io_type); | ||
| 1033 | EXPORT_SYMBOL(omap_mcbsp_free); | ||
| 1034 | EXPORT_SYMBOL(omap_mcbsp_start); | ||
| 1035 | EXPORT_SYMBOL(omap_mcbsp_stop); | ||
| 1036 | EXPORT_SYMBOL(omap_mcbsp_pollread); | ||
| 1037 | EXPORT_SYMBOL(omap_mcbsp_pollwrite); | ||
| 1038 | EXPORT_SYMBOL(omap_mcbsp_xmit_word); | ||
| 1039 | EXPORT_SYMBOL(omap_mcbsp_recv_word); | ||
| 1040 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); | ||
| 1041 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); | ||
| 1042 | EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | ||
| 1043 | EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); | ||
| 1044 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | ||
