]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: Update McBSP
authorTony Lindgren <tony@atomide.com>
Mon, 9 May 2005 19:47:49 +0000 (12:47 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 9 May 2005 19:47:49 +0000 (12:47 -0700)
Sync with linux-omap tree. Fixes for clock framework,
DSP related updates, and optional polling read and write.

DSP updates by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
Polling read and write by Nishant Menon <x0nishan@ti.com>

Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap/mcbsp.c

index 7c4ad77130919b16381454d16d7be84ce11daaa8..26f966b16177554914a54a6334a2e1b463d455e6 100644 (file)
@@ -27,6 +27,7 @@
 #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>
@@ -66,6 +67,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 +177,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;
@@ -191,15 +193,13 @@ static int omap_mcbsp_check(unsigned int id)
 
 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()) {
+               omap_dsp_request_idle();
+               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);
                __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.
  */
@@ -625,10 +695,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()) {
@@ -643,7 +718,7 @@ static int __init omap_mcbsp_init(void)
        }
 #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);
        }