Merge branch 'topic/asoc' into for-linus
[pandora-kernel.git] / arch / arm / plat-omap / mcbsp.c
index e1d0440..7e669c9 100644 (file)
@@ -489,7 +489,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
 {
        struct omap_mcbsp *mcbsp;
 
-       if (!cpu_is_omap34xx())
+       if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
                return;
 
        if (!omap_mcbsp_check_valid_id(id)) {
@@ -511,7 +511,7 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
 {
        struct omap_mcbsp *mcbsp;
 
-       if (!cpu_is_omap34xx())
+       if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
                return;
 
        if (!omap_mcbsp_check_valid_id(id)) {
@@ -560,6 +560,61 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
 }
 EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
 
+#define MCBSP2_FIFO_SIZE       0x500 /* 1024 + 256 locations */
+#define MCBSP1345_FIFO_SIZE    0x80  /* 128 locations */
+/*
+ * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
+ */
+u16 omap_mcbsp_get_tx_delay(unsigned int id)
+{
+       struct omap_mcbsp *mcbsp;
+       u16 buffstat;
+
+       if (!omap_mcbsp_check_valid_id(id)) {
+               printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return -ENODEV;
+       }
+       mcbsp = id_to_mcbsp_ptr(id);
+
+       /* Returns the number of free locations in the buffer */
+       buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
+
+       /* Number of slots are different in McBSP ports */
+       if (mcbsp->id == 2)
+               return MCBSP2_FIFO_SIZE - buffstat;
+       else
+               return MCBSP1345_FIFO_SIZE - buffstat;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_tx_delay);
+
+/*
+ * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
+ * to reach the threshold value (when the DMA will be triggered to read it)
+ */
+u16 omap_mcbsp_get_rx_delay(unsigned int id)
+{
+       struct omap_mcbsp *mcbsp;
+       u16 buffstat, threshold;
+
+       if (!omap_mcbsp_check_valid_id(id)) {
+               printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return -ENODEV;
+       }
+       mcbsp = id_to_mcbsp_ptr(id);
+
+       /* Returns the number of used locations in the buffer */
+       buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
+       /* RX threshold */
+       threshold = MCBSP_READ(mcbsp, THRSH1);
+
+       /* Return the number of location till we reach the threshold limit */
+       if (threshold <= buffstat)
+               return 0;
+       else
+               return threshold - buffstat;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_rx_delay);
+
 /*
  * omap_mcbsp_get_dma_op_mode just return the current configured
  * operating mode for the mcbsp channel
@@ -587,7 +642,7 @@ static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
         * Enable wakup behavior, smart idle and all wakeups
         * REVISIT: some wakeups may be unnecessary
         */
-       if (cpu_is_omap34xx()) {
+       if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                u16 syscon;
 
                syscon = MCBSP_READ(mcbsp, SYSCON);
@@ -610,7 +665,7 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
        /*
         * Disable wakup behavior, smart idle and all wakeups
         */
-       if (cpu_is_omap34xx()) {
+       if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                u16 syscon;
 
                syscon = MCBSP_READ(mcbsp, SYSCON);
@@ -724,14 +779,17 @@ int omap_mcbsp_request(unsigned int id)
                        goto err_clk_disable;
                }
 
-               init_completion(&mcbsp->rx_irq_completion);
-               err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
+               if (mcbsp->rx_irq) {
+                       init_completion(&mcbsp->rx_irq_completion);
+                       err = request_irq(mcbsp->rx_irq,
+                                       omap_mcbsp_rx_irq_handler,
                                        0, "McBSP", (void *)mcbsp);
-               if (err != 0) {
-                       dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
-                                       "for McBSP%d\n", mcbsp->rx_irq,
-                                       mcbsp->id);
-                       goto err_free_irq;
+                       if (err != 0) {
+                               dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
+                                               "for McBSP%d\n", mcbsp->rx_irq,
+                                               mcbsp->id);
+                               goto err_free_irq;
+                       }
                }
        }
 
@@ -781,7 +839,8 @@ void omap_mcbsp_free(unsigned int id)
 
        if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
                /* Free IRQs */
-               free_irq(mcbsp->rx_irq, (void *)mcbsp);
+               if (mcbsp->rx_irq)
+                       free_irq(mcbsp->rx_irq, (void *)mcbsp);
                free_irq(mcbsp->tx_irq, (void *)mcbsp);
        }
 
@@ -855,7 +914,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
                MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
        }
 
-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
                /* Release the transmitter and receiver */
                w = MCBSP_READ_CACHE(mcbsp, XCCR);
                w &= ~(tx ? XDISABLE : 0);
@@ -885,7 +944,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
 
        /* Reset transmitter */
        tx &= 1;
-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
                w = MCBSP_READ_CACHE(mcbsp, XCCR);
                w |= (tx ? XDISABLE : 0);
                MCBSP_WRITE(mcbsp, XCCR, w);
@@ -895,7 +954,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
 
        /* Reset receiver */
        rx &= 1;
-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
                w = MCBSP_READ_CACHE(mcbsp, RCCR);
                w |= (rx ? RDISABLE : 0);
                MCBSP_WRITE(mcbsp, RCCR, w);