[PATCH] powerpc: Allow for ppc_md restart, power_off, and halt to be NULL
[powerpc.git] / arch / arm / plat-omap / mcbsp.c
index 10c3f22..be0e0f3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/arch/dma.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/irqs.h>
+#include <asm/arch/dsp_common.h>
 #include <asm/arch/mcbsp.h>
 
-#include <asm/hardware/clock.h>
-
 #ifdef CONFIG_MCBSP_DEBUG
 #define DBG(x...)      printk(x)
 #else
@@ -66,6 +66,7 @@ struct omap_mcbsp {
 static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
 static struct clk *mcbsp_dsp_ck = 0;
 static struct clk *mcbsp_api_ck = 0;
+static struct clk *mcbsp_dspxor_ck = 0;
 
 
 static void omap_mcbsp_dump_reg(u8 id)
@@ -175,7 +176,7 @@ static int omap_mcbsp_check(unsigned int id)
                return 0;
        }
 
-       if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
                if (id > OMAP_MAX_MCBSP_COUNT) {
                        printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
                        return -1;
@@ -186,20 +187,19 @@ static int omap_mcbsp_check(unsigned int id)
        return -1;
 }
 
-#define EN_XORPCK              1
-#define DSP_RSTCT2              0xe1008014
-
 static void omap_mcbsp_dsp_request(void)
 {
-       if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
-               omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)),
-                           ARM_RSTCT1);
-               clk_enable(mcbsp_dsp_ck);
-               clk_enable(mcbsp_api_ck);
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+               clk_use(mcbsp_dsp_ck);
+               clk_use(mcbsp_api_ck);
 
                /* enable 12MHz clock to mcbsp 1 & 3 */
-               __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK),
-                            DSP_IDLECT2);
+               clk_use(mcbsp_dspxor_ck);
+
+               /*
+                * DSP external peripheral reset
+                * FIXME: This should be moved to dsp code
+                */
                __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
                             DSP_RSTCT2);
        }
@@ -207,10 +207,13 @@ static void omap_mcbsp_dsp_request(void)
 
 static void omap_mcbsp_dsp_free(void)
 {
-       /* Useless for now */
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+               clk_unuse(mcbsp_dspxor_ck);
+               clk_unuse(mcbsp_dsp_ck);
+               clk_unuse(mcbsp_api_ck);
+       }
 }
 
-
 int omap_mcbsp_request(unsigned int id)
 {
        int err;
@@ -350,6 +353,73 @@ void omap_mcbsp_stop(unsigned int id)
 }
 
 
+/* polled mcbsp i/o operations */
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+{
+       u32 base = mcbsp[id].io_base;
+       writew(buf, base + OMAP_MCBSP_REG_DXR1);
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
+               /* clear error */
+               writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
+                      base + OMAP_MCBSP_REG_SPCR2);
+               /* resend */
+               return -1;
+       } else {
+               /* wait for transmit confirmation */
+               int attemps = 0;
+               while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
+                       if (attemps++ > 1000) {
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
+                                      (~XRST),
+                                      base + OMAP_MCBSP_REG_SPCR2);
+                               udelay(10);
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
+                                      (XRST),
+                                      base + OMAP_MCBSP_REG_SPCR2);
+                               udelay(10);
+                               printk(KERN_ERR
+                                      " Could not write to McBSP Register\n");
+                               return -2;
+                       }
+               }
+       }
+       return 0;
+}
+
+int omap_mcbsp_pollread(unsigned int id, u16 * buf)
+{
+       u32 base = mcbsp[id].io_base;
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
+               /* clear error */
+               writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
+                      base + OMAP_MCBSP_REG_SPCR1);
+               /* resend */
+               return -1;
+       } else {
+               /* wait for recieve confirmation */
+               int attemps = 0;
+               while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
+                       if (attemps++ > 1000) {
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
+                                      (~RRST),
+                                      base + OMAP_MCBSP_REG_SPCR1);
+                               udelay(10);
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
+                                      (RRST),
+                                      base + OMAP_MCBSP_REG_SPCR1);
+                               udelay(10);
+                               printk(KERN_ERR
+                                      " Could not read from McBSP Register\n");
+                               return -2;
+                       }
+               }
+       }
+       *buf = readw(base + OMAP_MCBSP_REG_DRR1);
+       return 0;
+}
+
 /*
  * IRQ based word transmission.
  */
@@ -420,17 +490,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
        omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
                                     OMAP_DMA_DATA_TYPE_S16,
                                     length >> 1, 1,
-                                    OMAP_DMA_SYNC_ELEMENT);
+                                    OMAP_DMA_SYNC_ELEMENT,
+                                    0, 0);
 
        omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
                                 OMAP_DMA_PORT_TIPB,
                                 OMAP_DMA_AMODE_CONSTANT,
-                                mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
+                                mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
+                                0, 0);
 
        omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
                                OMAP_DMA_PORT_EMIFF,
                                OMAP_DMA_AMODE_POST_INC,
-                               buffer);
+                               buffer,
+                               0, 0);
 
        omap_start_dma(mcbsp[id].dma_tx_lch);
        wait_for_completion(&(mcbsp[id].tx_dma_completion));
@@ -460,17 +533,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
        omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
                                     OMAP_DMA_DATA_TYPE_S16,
                                     length >> 1, 1,
-                                    OMAP_DMA_SYNC_ELEMENT);
+                                    OMAP_DMA_SYNC_ELEMENT,
+                                    0, 0);
 
        omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
                                OMAP_DMA_PORT_TIPB,
                                OMAP_DMA_AMODE_CONSTANT,
-                               mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
+                               mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
+                               0, 0);
 
        omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
                                 OMAP_DMA_PORT_EMIFF,
                                 OMAP_DMA_AMODE_POST_INC,
-                                buffer);
+                                buffer,
+                                0, 0);
 
        omap_start_dma(mcbsp[id].dma_rx_lch);
        wait_for_completion(&(mcbsp[id].rx_dma_completion));
@@ -572,7 +648,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = {
 };
 #endif
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static const struct omap_mcbsp_info mcbsp_1510[] = {
        [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
                .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
@@ -625,10 +701,15 @@ static int __init omap_mcbsp_init(void)
                return PTR_ERR(mcbsp_dsp_ck);
        }
        mcbsp_api_ck = clk_get(0, "api_ck");
-       if (IS_ERR(mcbsp_dsp_ck)) {
+       if (IS_ERR(mcbsp_api_ck)) {
                printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
                return PTR_ERR(mcbsp_api_ck);
        }
+       mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
+       if (IS_ERR(mcbsp_dspxor_ck)) {
+               printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
+               return PTR_ERR(mcbsp_dspxor_ck);
+       }
 
 #ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730()) {
@@ -636,14 +717,14 @@ static int __init omap_mcbsp_init(void)
                mcbsp_count = ARRAY_SIZE(mcbsp_730);
        }
 #endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap1510()) {
                mcbsp_info = mcbsp_1510;
                mcbsp_count = ARRAY_SIZE(mcbsp_1510);
        }
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
-       if (cpu_is_omap1610() || cpu_is_omap1710()) {
+       if (cpu_is_omap16xx()) {
                mcbsp_info = mcbsp_1610;
                mcbsp_count = ARRAY_SIZE(mcbsp_1610);
        }