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); |