diff options
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
| -rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 345 |
1 files changed, 306 insertions, 39 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 1cd2cace7e1b..196aac3ac329 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | #ifdef CONFIG_MCBSP_DEBUG | 34 | #ifdef CONFIG_MCBSP_DEBUG |
| 35 | #define DBG(x...) printk(x) | 35 | #define DBG(x...) printk(x) |
| 36 | #else | 36 | #else |
| 37 | #define DBG(x...) do { } while (0) | 37 | #define DBG(x...) do { } while (0) |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | struct omap_mcbsp { | 40 | struct omap_mcbsp { |
| @@ -44,6 +44,7 @@ struct omap_mcbsp { | |||
| 44 | omap_mcbsp_word_length rx_word_length; | 44 | omap_mcbsp_word_length rx_word_length; |
| 45 | omap_mcbsp_word_length tx_word_length; | 45 | omap_mcbsp_word_length tx_word_length; |
| 46 | 46 | ||
| 47 | omap_mcbsp_io_type_t io_type; /* IRQ or poll */ | ||
| 47 | /* IRQ based TX/RX */ | 48 | /* IRQ based TX/RX */ |
| 48 | int rx_irq; | 49 | int rx_irq; |
| 49 | int tx_irq; | 50 | int tx_irq; |
| @@ -64,10 +65,19 @@ struct omap_mcbsp { | |||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; | 67 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; |
| 68 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 67 | static struct clk *mcbsp_dsp_ck = 0; | 69 | static struct clk *mcbsp_dsp_ck = 0; |
| 68 | static struct clk *mcbsp_api_ck = 0; | 70 | static struct clk *mcbsp_api_ck = 0; |
| 69 | static struct clk *mcbsp_dspxor_ck = 0; | 71 | static struct clk *mcbsp_dspxor_ck = 0; |
| 70 | 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 | static struct clk *sys_ck = 0; | ||
| 79 | static struct clk *sys_clkout = 0; | ||
| 80 | #endif | ||
| 71 | 81 | ||
| 72 | static void omap_mcbsp_dump_reg(u8 id) | 82 | static void omap_mcbsp_dump_reg(u8 id) |
| 73 | { | 83 | { |
| @@ -88,7 +98,6 @@ static void omap_mcbsp_dump_reg(u8 id) | |||
| 88 | DBG("***********************\n"); | 98 | DBG("***********************\n"); |
| 89 | } | 99 | } |
| 90 | 100 | ||
| 91 | |||
| 92 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | 101 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) |
| 93 | { | 102 | { |
| 94 | struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); | 103 | struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); |
| @@ -109,7 +118,6 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_re | |||
| 109 | return IRQ_HANDLED; | 118 | return IRQ_HANDLED; |
| 110 | } | 119 | } |
| 111 | 120 | ||
| 112 | |||
| 113 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) | 121 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) |
| 114 | { | 122 | { |
| 115 | struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); | 123 | struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); |
| @@ -176,7 +184,7 @@ static int omap_mcbsp_check(unsigned int id) | |||
| 176 | return 0; | 184 | return 0; |
| 177 | } | 185 | } |
| 178 | 186 | ||
| 179 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 187 | if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { |
| 180 | if (id > OMAP_MAX_MCBSP_COUNT) { | 188 | if (id > OMAP_MAX_MCBSP_COUNT) { |
| 181 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | 189 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); |
| 182 | return -1; | 190 | return -1; |
| @@ -187,9 +195,10 @@ static int omap_mcbsp_check(unsigned int id) | |||
| 187 | return -1; | 195 | return -1; |
| 188 | } | 196 | } |
| 189 | 197 | ||
| 198 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 190 | static void omap_mcbsp_dsp_request(void) | 199 | static void omap_mcbsp_dsp_request(void) |
| 191 | { | 200 | { |
| 192 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 201 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { |
| 193 | clk_enable(mcbsp_dsp_ck); | 202 | clk_enable(mcbsp_dsp_ck); |
| 194 | clk_enable(mcbsp_api_ck); | 203 | clk_enable(mcbsp_api_ck); |
| 195 | 204 | ||
| @@ -207,12 +216,49 @@ static void omap_mcbsp_dsp_request(void) | |||
| 207 | 216 | ||
| 208 | static void omap_mcbsp_dsp_free(void) | 217 | static void omap_mcbsp_dsp_free(void) |
| 209 | { | 218 | { |
| 210 | if (cpu_is_omap1510() || cpu_is_omap16xx()) { | 219 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { |
| 211 | clk_disable(mcbsp_dspxor_ck); | 220 | clk_disable(mcbsp_dspxor_ck); |
| 212 | clk_disable(mcbsp_dsp_ck); | 221 | clk_disable(mcbsp_dsp_ck); |
| 213 | clk_disable(mcbsp_api_ck); | 222 | clk_disable(mcbsp_api_ck); |
| 214 | } | 223 | } |
| 215 | } | 224 | } |
| 225 | #endif | ||
| 226 | |||
| 227 | #ifdef CONFIG_ARCH_OMAP2 | ||
| 228 | static void omap2_mcbsp2_mux_setup(void) | ||
| 229 | { | ||
| 230 | omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); | ||
| 231 | omap_cfg_reg(R14_24XX_MCBSP2_FSX); | ||
| 232 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | ||
| 233 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | ||
| 234 | omap_cfg_reg(V14_24XX_GPIO117); | ||
| 235 | omap_cfg_reg(W14_24XX_SYS_CLKOUT); | ||
| 236 | } | ||
| 237 | #endif | ||
| 238 | |||
| 239 | /* | ||
| 240 | * We can choose between IRQ based or polled IO. | ||
| 241 | * This needs to be called before omap_mcbsp_request(). | ||
| 242 | */ | ||
| 243 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | ||
| 244 | { | ||
| 245 | if (omap_mcbsp_check(id) < 0) | ||
| 246 | return -EINVAL; | ||
| 247 | |||
| 248 | spin_lock(&mcbsp[id].lock); | ||
| 249 | |||
| 250 | if (!mcbsp[id].free) { | ||
| 251 | printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); | ||
| 252 | spin_unlock(&mcbsp[id].lock); | ||
| 253 | return -EINVAL; | ||
| 254 | } | ||
| 255 | |||
| 256 | mcbsp[id].io_type = io_type; | ||
| 257 | |||
| 258 | spin_unlock(&mcbsp[id].lock); | ||
| 259 | |||
| 260 | return 0; | ||
| 261 | } | ||
| 216 | 262 | ||
| 217 | int omap_mcbsp_request(unsigned int id) | 263 | int omap_mcbsp_request(unsigned int id) |
| 218 | { | 264 | { |
| @@ -221,12 +267,26 @@ int omap_mcbsp_request(unsigned int id) | |||
| 221 | if (omap_mcbsp_check(id) < 0) | 267 | if (omap_mcbsp_check(id) < 0) |
| 222 | return -EINVAL; | 268 | return -EINVAL; |
| 223 | 269 | ||
| 270 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 224 | /* | 271 | /* |
| 225 | * On 1510, 1610 and 1710, McBSP1 and McBSP3 | 272 | * On 1510, 1610 and 1710, McBSP1 and McBSP3 |
| 226 | * are DSP public peripherals. | 273 | * are DSP public peripherals. |
| 227 | */ | 274 | */ |
| 228 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | 275 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) |
| 229 | omap_mcbsp_dsp_request(); | 276 | omap_mcbsp_dsp_request(); |
| 277 | #endif | ||
| 278 | |||
| 279 | #ifdef CONFIG_ARCH_OMAP2 | ||
| 280 | if (cpu_is_omap24xx()) { | ||
| 281 | if (id == OMAP_MCBSP1) { | ||
| 282 | clk_enable(mcbsp1_ick); | ||
| 283 | clk_enable(mcbsp1_fck); | ||
| 284 | } else { | ||
| 285 | clk_enable(mcbsp2_ick); | ||
| 286 | clk_enable(mcbsp2_fck); | ||
| 287 | } | ||
| 288 | } | ||
| 289 | #endif | ||
| 230 | 290 | ||
| 231 | spin_lock(&mcbsp[id].lock); | 291 | spin_lock(&mcbsp[id].lock); |
| 232 | if (!mcbsp[id].free) { | 292 | if (!mcbsp[id].free) { |
| @@ -238,30 +298,33 @@ int omap_mcbsp_request(unsigned int id) | |||
| 238 | mcbsp[id].free = 0; | 298 | mcbsp[id].free = 0; |
| 239 | spin_unlock(&mcbsp[id].lock); | 299 | spin_unlock(&mcbsp[id].lock); |
| 240 | 300 | ||
| 241 | /* We need to get IRQs here */ | 301 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { |
| 242 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, | 302 | /* We need to get IRQs here */ |
| 243 | "McBSP", | 303 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, |
| 244 | (void *) (&mcbsp[id])); | 304 | "McBSP", |
| 245 | if (err != 0) { | 305 | (void *) (&mcbsp[id])); |
| 246 | printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", | 306 | if (err != 0) { |
| 247 | mcbsp[id].tx_irq, mcbsp[id].id); | 307 | printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", |
| 248 | return err; | 308 | mcbsp[id].tx_irq, mcbsp[id].id); |
| 249 | } | 309 | return err; |
| 310 | } | ||
| 250 | 311 | ||
| 251 | init_completion(&(mcbsp[id].tx_irq_completion)); | 312 | init_completion(&(mcbsp[id].tx_irq_completion)); |
| 252 | 313 | ||
| 253 | 314 | ||
| 254 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, | 315 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, |
| 255 | "McBSP", | 316 | "McBSP", |
| 256 | (void *) (&mcbsp[id])); | 317 | (void *) (&mcbsp[id])); |
| 257 | if (err != 0) { | 318 | if (err != 0) { |
| 258 | printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", | 319 | printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", |
| 259 | mcbsp[id].rx_irq, mcbsp[id].id); | 320 | mcbsp[id].rx_irq, mcbsp[id].id); |
| 260 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 321 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); |
| 261 | return err; | 322 | return err; |
| 323 | } | ||
| 324 | |||
| 325 | init_completion(&(mcbsp[id].rx_irq_completion)); | ||
| 262 | } | 326 | } |
| 263 | 327 | ||
| 264 | init_completion(&(mcbsp[id].rx_irq_completion)); | ||
| 265 | return 0; | 328 | return 0; |
| 266 | 329 | ||
| 267 | } | 330 | } |
| @@ -271,8 +334,24 @@ void omap_mcbsp_free(unsigned int id) | |||
| 271 | if (omap_mcbsp_check(id) < 0) | 334 | if (omap_mcbsp_check(id) < 0) |
| 272 | return; | 335 | return; |
| 273 | 336 | ||
| 274 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | 337 | #ifdef CONFIG_ARCH_OMAP1 |
| 275 | omap_mcbsp_dsp_free(); | 338 | if (cpu_class_is_omap1()) { |
| 339 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | ||
| 340 | omap_mcbsp_dsp_free(); | ||
| 341 | } | ||
| 342 | #endif | ||
| 343 | |||
| 344 | #ifdef CONFIG_ARCH_OMAP2 | ||
| 345 | if (cpu_is_omap24xx()) { | ||
| 346 | if (id == OMAP_MCBSP1) { | ||
| 347 | clk_disable(mcbsp1_ick); | ||
| 348 | clk_disable(mcbsp1_fck); | ||
| 349 | } else { | ||
| 350 | clk_disable(mcbsp2_ick); | ||
| 351 | clk_disable(mcbsp2_fck); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | #endif | ||
| 276 | 355 | ||
| 277 | spin_lock(&mcbsp[id].lock); | 356 | spin_lock(&mcbsp[id].lock); |
| 278 | if (mcbsp[id].free) { | 357 | if (mcbsp[id].free) { |
| @@ -284,9 +363,11 @@ void omap_mcbsp_free(unsigned int id) | |||
| 284 | mcbsp[id].free = 1; | 363 | mcbsp[id].free = 1; |
| 285 | spin_unlock(&mcbsp[id].lock); | 364 | spin_unlock(&mcbsp[id].lock); |
| 286 | 365 | ||
| 287 | /* Free IRQs */ | 366 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { |
| 288 | free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); | 367 | /* Free IRQs */ |
| 289 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 368 | free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); |
| 369 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | ||
| 370 | } | ||
| 290 | } | 371 | } |
| 291 | 372 | ||
| 292 | /* | 373 | /* |
| @@ -461,6 +542,115 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
| 461 | } | 542 | } |
| 462 | 543 | ||
| 463 | 544 | ||
| 545 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | ||
| 546 | { | ||
| 547 | u32 io_base = mcbsp[id].io_base; | ||
| 548 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | ||
| 549 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | ||
| 550 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | ||
| 551 | |||
| 552 | if (tx_word_length != rx_word_length) | ||
| 553 | return -EINVAL; | ||
| 554 | |||
| 555 | /* First we wait for the transmitter to be ready */ | ||
| 556 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 557 | while (!(spcr2 & XRDY)) { | ||
| 558 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 559 | if (attempts++ > 1000) { | ||
| 560 | /* We must reset the transmitter */ | ||
| 561 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); | ||
| 562 | udelay(10); | ||
| 563 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | ||
| 564 | udelay(10); | ||
| 565 | printk("McBSP transmitter not ready\n"); | ||
| 566 | return -EAGAIN; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | /* Now we can push the data */ | ||
| 571 | if (tx_word_length > OMAP_MCBSP_WORD_16) | ||
| 572 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); | ||
| 573 | OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); | ||
| 574 | |||
| 575 | /* We wait for the receiver to be ready */ | ||
| 576 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
| 577 | while (!(spcr1 & RRDY)) { | ||
| 578 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
| 579 | if (attempts++ > 1000) { | ||
| 580 | /* We must reset the receiver */ | ||
| 581 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); | ||
| 582 | udelay(10); | ||
| 583 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | ||
| 584 | udelay(10); | ||
| 585 | printk("McBSP receiver not ready\n"); | ||
| 586 | return -EAGAIN; | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | /* Receiver is ready, let's read the dummy data */ | ||
| 591 | if (rx_word_length > OMAP_MCBSP_WORD_16) | ||
| 592 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); | ||
| 593 | word_lsb = OMAP_MCBSP_READ(io_base, DRR1); | ||
| 594 | |||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) | ||
| 599 | { | ||
| 600 | u32 io_base = mcbsp[id].io_base, clock_word = 0; | ||
| 601 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | ||
| 602 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | ||
| 603 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | ||
| 604 | |||
| 605 | if (tx_word_length != rx_word_length) | ||
| 606 | return -EINVAL; | ||
| 607 | |||
| 608 | /* First we wait for the transmitter to be ready */ | ||
| 609 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 610 | while (!(spcr2 & XRDY)) { | ||
| 611 | spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 612 | if (attempts++ > 1000) { | ||
| 613 | /* We must reset the transmitter */ | ||
| 614 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); | ||
| 615 | udelay(10); | ||
| 616 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | ||
| 617 | udelay(10); | ||
| 618 | printk("McBSP transmitter not ready\n"); | ||
| 619 | return -EAGAIN; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 623 | /* We first need to enable the bus clock */ | ||
| 624 | if (tx_word_length > OMAP_MCBSP_WORD_16) | ||
| 625 | OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16); | ||
| 626 | OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff); | ||
| 627 | |||
| 628 | /* We wait for the receiver to be ready */ | ||
| 629 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
| 630 | while (!(spcr1 & RRDY)) { | ||
| 631 | spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); | ||
| 632 | if (attempts++ > 1000) { | ||
| 633 | /* We must reset the receiver */ | ||
| 634 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); | ||
| 635 | udelay(10); | ||
| 636 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | ||
| 637 | udelay(10); | ||
| 638 | printk("McBSP receiver not ready\n"); | ||
| 639 | return -EAGAIN; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | /* Receiver is ready, there is something for us */ | ||
| 644 | if (rx_word_length > OMAP_MCBSP_WORD_16) | ||
| 645 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); | ||
| 646 | word_lsb = OMAP_MCBSP_READ(io_base, DRR1); | ||
| 647 | |||
| 648 | word[0] = (word_lsb | (word_msb << 16)); | ||
| 649 | |||
| 650 | return 0; | ||
| 651 | } | ||
| 652 | |||
| 653 | |||
| 464 | /* | 654 | /* |
| 465 | * Simple DMA based buffer rx/tx routines. | 655 | * Simple DMA based buffer rx/tx routines. |
| 466 | * Nothing fancy, just a single buffer tx/rx through DMA. | 656 | * Nothing fancy, just a single buffer tx/rx through DMA. |
| @@ -471,6 +661,9 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
| 471 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 661 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) |
| 472 | { | 662 | { |
| 473 | int dma_tx_ch; | 663 | int dma_tx_ch; |
| 664 | int src_port = 0; | ||
| 665 | int dest_port = 0; | ||
| 666 | int sync_dev = 0; | ||
| 474 | 667 | ||
| 475 | if (omap_mcbsp_check(id) < 0) | 668 | if (omap_mcbsp_check(id) < 0) |
| 476 | return -EINVAL; | 669 | return -EINVAL; |
| @@ -487,20 +680,27 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 487 | 680 | ||
| 488 | init_completion(&(mcbsp[id].tx_dma_completion)); | 681 | init_completion(&(mcbsp[id].tx_dma_completion)); |
| 489 | 682 | ||
| 683 | if (cpu_class_is_omap1()) { | ||
| 684 | src_port = OMAP_DMA_PORT_TIPB; | ||
| 685 | dest_port = OMAP_DMA_PORT_EMIFF; | ||
| 686 | } | ||
| 687 | if (cpu_is_omap24xx()) | ||
| 688 | sync_dev = mcbsp[id].dma_tx_sync; | ||
| 689 | |||
| 490 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, | 690 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, |
| 491 | OMAP_DMA_DATA_TYPE_S16, | 691 | OMAP_DMA_DATA_TYPE_S16, |
| 492 | length >> 1, 1, | 692 | length >> 1, 1, |
| 493 | OMAP_DMA_SYNC_ELEMENT, | 693 | OMAP_DMA_SYNC_ELEMENT, |
| 494 | 0, 0); | 694 | sync_dev, 0); |
| 495 | 695 | ||
| 496 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, | 696 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, |
| 497 | OMAP_DMA_PORT_TIPB, | 697 | src_port, |
| 498 | OMAP_DMA_AMODE_CONSTANT, | 698 | OMAP_DMA_AMODE_CONSTANT, |
| 499 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, | 699 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, |
| 500 | 0, 0); | 700 | 0, 0); |
| 501 | 701 | ||
| 502 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, | 702 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, |
| 503 | OMAP_DMA_PORT_EMIFF, | 703 | dest_port, |
| 504 | OMAP_DMA_AMODE_POST_INC, | 704 | OMAP_DMA_AMODE_POST_INC, |
| 505 | buffer, | 705 | buffer, |
| 506 | 0, 0); | 706 | 0, 0); |
| @@ -514,6 +714,9 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 514 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) | 714 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) |
| 515 | { | 715 | { |
| 516 | int dma_rx_ch; | 716 | int dma_rx_ch; |
| 717 | int src_port = 0; | ||
| 718 | int dest_port = 0; | ||
| 719 | int sync_dev = 0; | ||
| 517 | 720 | ||
| 518 | if (omap_mcbsp_check(id) < 0) | 721 | if (omap_mcbsp_check(id) < 0) |
| 519 | return -EINVAL; | 722 | return -EINVAL; |
| @@ -530,20 +733,27 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
| 530 | 733 | ||
| 531 | init_completion(&(mcbsp[id].rx_dma_completion)); | 734 | init_completion(&(mcbsp[id].rx_dma_completion)); |
| 532 | 735 | ||
| 736 | if (cpu_class_is_omap1()) { | ||
| 737 | src_port = OMAP_DMA_PORT_TIPB; | ||
| 738 | dest_port = OMAP_DMA_PORT_EMIFF; | ||
| 739 | } | ||
| 740 | if (cpu_is_omap24xx()) | ||
| 741 | sync_dev = mcbsp[id].dma_rx_sync; | ||
| 742 | |||
| 533 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 743 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, |
| 534 | OMAP_DMA_DATA_TYPE_S16, | 744 | OMAP_DMA_DATA_TYPE_S16, |
| 535 | length >> 1, 1, | 745 | length >> 1, 1, |
| 536 | OMAP_DMA_SYNC_ELEMENT, | 746 | OMAP_DMA_SYNC_ELEMENT, |
| 537 | 0, 0); | 747 | sync_dev, 0); |
| 538 | 748 | ||
| 539 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, | 749 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, |
| 540 | OMAP_DMA_PORT_TIPB, | 750 | src_port, |
| 541 | OMAP_DMA_AMODE_CONSTANT, | 751 | OMAP_DMA_AMODE_CONSTANT, |
| 542 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, | 752 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, |
| 543 | 0, 0); | 753 | 0, 0); |
| 544 | 754 | ||
| 545 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, | 755 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, |
| 546 | OMAP_DMA_PORT_EMIFF, | 756 | dest_port, |
| 547 | OMAP_DMA_AMODE_POST_INC, | 757 | OMAP_DMA_AMODE_POST_INC, |
| 548 | buffer, | 758 | buffer, |
| 549 | 0, 0); | 759 | 0, 0); |
| @@ -688,6 +898,23 @@ static const struct omap_mcbsp_info mcbsp_1610[] = { | |||
| 688 | }; | 898 | }; |
| 689 | #endif | 899 | #endif |
| 690 | 900 | ||
| 901 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
| 902 | static const struct omap_mcbsp_info mcbsp_24xx[] = { | ||
| 903 | [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), | ||
| 904 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
| 905 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
| 906 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
| 907 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
| 908 | }, | ||
| 909 | [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), | ||
| 910 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
| 911 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
| 912 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
| 913 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
| 914 | }, | ||
| 915 | }; | ||
| 916 | #endif | ||
| 917 | |||
| 691 | static int __init omap_mcbsp_init(void) | 918 | static int __init omap_mcbsp_init(void) |
| 692 | { | 919 | { |
| 693 | int mcbsp_count = 0, i; | 920 | int mcbsp_count = 0, i; |
| @@ -695,6 +922,7 @@ static int __init omap_mcbsp_init(void) | |||
| 695 | 922 | ||
| 696 | printk("Initializing OMAP McBSP system\n"); | 923 | printk("Initializing OMAP McBSP system\n"); |
| 697 | 924 | ||
| 925 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 698 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); | 926 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); |
| 699 | if (IS_ERR(mcbsp_dsp_ck)) { | 927 | if (IS_ERR(mcbsp_dsp_ck)) { |
| 700 | printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); | 928 | printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); |
| @@ -710,6 +938,29 @@ static int __init omap_mcbsp_init(void) | |||
| 710 | printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); | 938 | printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); |
| 711 | return PTR_ERR(mcbsp_dspxor_ck); | 939 | return PTR_ERR(mcbsp_dspxor_ck); |
| 712 | } | 940 | } |
| 941 | #endif | ||
| 942 | #ifdef CONFIG_ARCH_OMAP2 | ||
| 943 | mcbsp1_ick = clk_get(0, "mcbsp1_ick"); | ||
| 944 | if (IS_ERR(mcbsp1_ick)) { | ||
| 945 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); | ||
| 946 | return PTR_ERR(mcbsp1_ick); | ||
| 947 | } | ||
| 948 | mcbsp1_fck = clk_get(0, "mcbsp1_fck"); | ||
| 949 | if (IS_ERR(mcbsp1_fck)) { | ||
| 950 | printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); | ||
| 951 | return PTR_ERR(mcbsp1_fck); | ||
| 952 | } | ||
| 953 | mcbsp2_ick = clk_get(0, "mcbsp2_ick"); | ||
| 954 | if (IS_ERR(mcbsp2_ick)) { | ||
| 955 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); | ||
| 956 | return PTR_ERR(mcbsp2_ick); | ||
| 957 | } | ||
| 958 | mcbsp2_fck = clk_get(0, "mcbsp2_fck"); | ||
| 959 | if (IS_ERR(mcbsp2_fck)) { | ||
| 960 | printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); | ||
| 961 | return PTR_ERR(mcbsp2_fck); | ||
| 962 | } | ||
| 963 | #endif | ||
| 713 | 964 | ||
| 714 | #ifdef CONFIG_ARCH_OMAP730 | 965 | #ifdef CONFIG_ARCH_OMAP730 |
| 715 | if (cpu_is_omap730()) { | 966 | if (cpu_is_omap730()) { |
| @@ -718,7 +969,7 @@ static int __init omap_mcbsp_init(void) | |||
| 718 | } | 969 | } |
| 719 | #endif | 970 | #endif |
| 720 | #ifdef CONFIG_ARCH_OMAP15XX | 971 | #ifdef CONFIG_ARCH_OMAP15XX |
| 721 | if (cpu_is_omap1510()) { | 972 | if (cpu_is_omap15xx()) { |
| 722 | mcbsp_info = mcbsp_1510; | 973 | mcbsp_info = mcbsp_1510; |
| 723 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); | 974 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); |
| 724 | } | 975 | } |
| @@ -729,6 +980,19 @@ static int __init omap_mcbsp_init(void) | |||
| 729 | mcbsp_count = ARRAY_SIZE(mcbsp_1610); | 980 | mcbsp_count = ARRAY_SIZE(mcbsp_1610); |
| 730 | } | 981 | } |
| 731 | #endif | 982 | #endif |
| 983 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
| 984 | if (cpu_is_omap24xx()) { | ||
| 985 | mcbsp_info = mcbsp_24xx; | ||
| 986 | mcbsp_count = ARRAY_SIZE(mcbsp_24xx); | ||
| 987 | |||
| 988 | /* REVISIT: where's the right place? */ | ||
| 989 | omap2_mcbsp2_mux_setup(); | ||
| 990 | sys_ck = clk_get(0, "sys_ck"); | ||
| 991 | sys_clkout = clk_get(0, "sys_clkout"); | ||
| 992 | clk_set_parent(sys_clkout, sys_ck); | ||
| 993 | clk_enable(sys_clkout); | ||
| 994 | } | ||
| 995 | #endif | ||
| 732 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { | 996 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { |
| 733 | if (i >= mcbsp_count) { | 997 | if (i >= mcbsp_count) { |
| 734 | mcbsp[i].io_base = 0; | 998 | mcbsp[i].io_base = 0; |
| @@ -741,6 +1005,7 @@ static int __init omap_mcbsp_init(void) | |||
| 741 | mcbsp[i].dma_rx_lch = -1; | 1005 | mcbsp[i].dma_rx_lch = -1; |
| 742 | 1006 | ||
| 743 | mcbsp[i].io_base = mcbsp_info[i].virt_base; | 1007 | mcbsp[i].io_base = mcbsp_info[i].virt_base; |
| 1008 | mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ | ||
| 744 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; | 1009 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; |
| 745 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; | 1010 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; |
| 746 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; | 1011 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; |
| @@ -751,11 +1016,11 @@ static int __init omap_mcbsp_init(void) | |||
| 751 | return 0; | 1016 | return 0; |
| 752 | } | 1017 | } |
| 753 | 1018 | ||
| 754 | |||
| 755 | arch_initcall(omap_mcbsp_init); | 1019 | arch_initcall(omap_mcbsp_init); |
| 756 | 1020 | ||
| 757 | EXPORT_SYMBOL(omap_mcbsp_config); | 1021 | EXPORT_SYMBOL(omap_mcbsp_config); |
| 758 | EXPORT_SYMBOL(omap_mcbsp_request); | 1022 | EXPORT_SYMBOL(omap_mcbsp_request); |
| 1023 | EXPORT_SYMBOL(omap_mcbsp_set_io_type); | ||
| 759 | EXPORT_SYMBOL(omap_mcbsp_free); | 1024 | EXPORT_SYMBOL(omap_mcbsp_free); |
| 760 | EXPORT_SYMBOL(omap_mcbsp_start); | 1025 | EXPORT_SYMBOL(omap_mcbsp_start); |
| 761 | EXPORT_SYMBOL(omap_mcbsp_stop); | 1026 | EXPORT_SYMBOL(omap_mcbsp_stop); |
| @@ -763,4 +1028,6 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); | |||
| 763 | EXPORT_SYMBOL(omap_mcbsp_recv_word); | 1028 | EXPORT_SYMBOL(omap_mcbsp_recv_word); |
| 764 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); | 1029 | EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); |
| 765 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); | 1030 | EXPORT_SYMBOL(omap_mcbsp_recv_buffer); |
| 1031 | EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | ||
| 1032 | EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); | ||
| 766 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | 1033 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); |
