diff options
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e1d0440fd4a8..7e669c9744d8 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -489,7 +489,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | |||
489 | { | 489 | { |
490 | struct omap_mcbsp *mcbsp; | 490 | struct omap_mcbsp *mcbsp; |
491 | 491 | ||
492 | if (!cpu_is_omap34xx()) | 492 | if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) |
493 | return; | 493 | return; |
494 | 494 | ||
495 | if (!omap_mcbsp_check_valid_id(id)) { | 495 | if (!omap_mcbsp_check_valid_id(id)) { |
@@ -511,7 +511,7 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | |||
511 | { | 511 | { |
512 | struct omap_mcbsp *mcbsp; | 512 | struct omap_mcbsp *mcbsp; |
513 | 513 | ||
514 | if (!cpu_is_omap34xx()) | 514 | if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) |
515 | return; | 515 | return; |
516 | 516 | ||
517 | if (!omap_mcbsp_check_valid_id(id)) { | 517 | if (!omap_mcbsp_check_valid_id(id)) { |
@@ -560,6 +560,61 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) | |||
560 | } | 560 | } |
561 | EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); | 561 | EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); |
562 | 562 | ||
563 | #define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ | ||
564 | #define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ | ||
565 | /* | ||
566 | * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO | ||
567 | */ | ||
568 | u16 omap_mcbsp_get_tx_delay(unsigned int id) | ||
569 | { | ||
570 | struct omap_mcbsp *mcbsp; | ||
571 | u16 buffstat; | ||
572 | |||
573 | if (!omap_mcbsp_check_valid_id(id)) { | ||
574 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
575 | return -ENODEV; | ||
576 | } | ||
577 | mcbsp = id_to_mcbsp_ptr(id); | ||
578 | |||
579 | /* Returns the number of free locations in the buffer */ | ||
580 | buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); | ||
581 | |||
582 | /* Number of slots are different in McBSP ports */ | ||
583 | if (mcbsp->id == 2) | ||
584 | return MCBSP2_FIFO_SIZE - buffstat; | ||
585 | else | ||
586 | return MCBSP1345_FIFO_SIZE - buffstat; | ||
587 | } | ||
588 | EXPORT_SYMBOL(omap_mcbsp_get_tx_delay); | ||
589 | |||
590 | /* | ||
591 | * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO | ||
592 | * to reach the threshold value (when the DMA will be triggered to read it) | ||
593 | */ | ||
594 | u16 omap_mcbsp_get_rx_delay(unsigned int id) | ||
595 | { | ||
596 | struct omap_mcbsp *mcbsp; | ||
597 | u16 buffstat, threshold; | ||
598 | |||
599 | if (!omap_mcbsp_check_valid_id(id)) { | ||
600 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
601 | return -ENODEV; | ||
602 | } | ||
603 | mcbsp = id_to_mcbsp_ptr(id); | ||
604 | |||
605 | /* Returns the number of used locations in the buffer */ | ||
606 | buffstat = MCBSP_READ(mcbsp, RBUFFSTAT); | ||
607 | /* RX threshold */ | ||
608 | threshold = MCBSP_READ(mcbsp, THRSH1); | ||
609 | |||
610 | /* Return the number of location till we reach the threshold limit */ | ||
611 | if (threshold <= buffstat) | ||
612 | return 0; | ||
613 | else | ||
614 | return threshold - buffstat; | ||
615 | } | ||
616 | EXPORT_SYMBOL(omap_mcbsp_get_rx_delay); | ||
617 | |||
563 | /* | 618 | /* |
564 | * omap_mcbsp_get_dma_op_mode just return the current configured | 619 | * omap_mcbsp_get_dma_op_mode just return the current configured |
565 | * operating mode for the mcbsp channel | 620 | * operating mode for the mcbsp channel |
@@ -587,7 +642,7 @@ static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) | |||
587 | * Enable wakup behavior, smart idle and all wakeups | 642 | * Enable wakup behavior, smart idle and all wakeups |
588 | * REVISIT: some wakeups may be unnecessary | 643 | * REVISIT: some wakeups may be unnecessary |
589 | */ | 644 | */ |
590 | if (cpu_is_omap34xx()) { | 645 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { |
591 | u16 syscon; | 646 | u16 syscon; |
592 | 647 | ||
593 | syscon = MCBSP_READ(mcbsp, SYSCON); | 648 | syscon = MCBSP_READ(mcbsp, SYSCON); |
@@ -610,7 +665,7 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) | |||
610 | /* | 665 | /* |
611 | * Disable wakup behavior, smart idle and all wakeups | 666 | * Disable wakup behavior, smart idle and all wakeups |
612 | */ | 667 | */ |
613 | if (cpu_is_omap34xx()) { | 668 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { |
614 | u16 syscon; | 669 | u16 syscon; |
615 | 670 | ||
616 | syscon = MCBSP_READ(mcbsp, SYSCON); | 671 | syscon = MCBSP_READ(mcbsp, SYSCON); |
@@ -724,14 +779,17 @@ int omap_mcbsp_request(unsigned int id) | |||
724 | goto err_clk_disable; | 779 | goto err_clk_disable; |
725 | } | 780 | } |
726 | 781 | ||
727 | init_completion(&mcbsp->rx_irq_completion); | 782 | if (mcbsp->rx_irq) { |
728 | err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, | 783 | init_completion(&mcbsp->rx_irq_completion); |
784 | err = request_irq(mcbsp->rx_irq, | ||
785 | omap_mcbsp_rx_irq_handler, | ||
729 | 0, "McBSP", (void *)mcbsp); | 786 | 0, "McBSP", (void *)mcbsp); |
730 | if (err != 0) { | 787 | if (err != 0) { |
731 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " | 788 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " |
732 | "for McBSP%d\n", mcbsp->rx_irq, | 789 | "for McBSP%d\n", mcbsp->rx_irq, |
733 | mcbsp->id); | 790 | mcbsp->id); |
734 | goto err_free_irq; | 791 | goto err_free_irq; |
792 | } | ||
735 | } | 793 | } |
736 | } | 794 | } |
737 | 795 | ||
@@ -781,7 +839,8 @@ void omap_mcbsp_free(unsigned int id) | |||
781 | 839 | ||
782 | if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { | 840 | if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { |
783 | /* Free IRQs */ | 841 | /* Free IRQs */ |
784 | free_irq(mcbsp->rx_irq, (void *)mcbsp); | 842 | if (mcbsp->rx_irq) |
843 | free_irq(mcbsp->rx_irq, (void *)mcbsp); | ||
785 | free_irq(mcbsp->tx_irq, (void *)mcbsp); | 844 | free_irq(mcbsp->tx_irq, (void *)mcbsp); |
786 | } | 845 | } |
787 | 846 | ||
@@ -855,7 +914,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx) | |||
855 | MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7)); | 914 | MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7)); |
856 | } | 915 | } |
857 | 916 | ||
858 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 917 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { |
859 | /* Release the transmitter and receiver */ | 918 | /* Release the transmitter and receiver */ |
860 | w = MCBSP_READ_CACHE(mcbsp, XCCR); | 919 | w = MCBSP_READ_CACHE(mcbsp, XCCR); |
861 | w &= ~(tx ? XDISABLE : 0); | 920 | w &= ~(tx ? XDISABLE : 0); |
@@ -885,7 +944,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) | |||
885 | 944 | ||
886 | /* Reset transmitter */ | 945 | /* Reset transmitter */ |
887 | tx &= 1; | 946 | tx &= 1; |
888 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 947 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { |
889 | w = MCBSP_READ_CACHE(mcbsp, XCCR); | 948 | w = MCBSP_READ_CACHE(mcbsp, XCCR); |
890 | w |= (tx ? XDISABLE : 0); | 949 | w |= (tx ? XDISABLE : 0); |
891 | MCBSP_WRITE(mcbsp, XCCR, w); | 950 | MCBSP_WRITE(mcbsp, XCCR, w); |
@@ -895,7 +954,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) | |||
895 | 954 | ||
896 | /* Reset receiver */ | 955 | /* Reset receiver */ |
897 | rx &= 1; | 956 | rx &= 1; |
898 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 957 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { |
899 | w = MCBSP_READ_CACHE(mcbsp, RCCR); | 958 | w = MCBSP_READ_CACHE(mcbsp, RCCR); |
900 | w |= (rx ? RDISABLE : 0); | 959 | w |= (rx ? RDISABLE : 0); |
901 | MCBSP_WRITE(mcbsp, RCCR, w); | 960 | MCBSP_WRITE(mcbsp, RCCR, w); |