I'll try that again :)

On Mon, Sep 26, 2005 at 12:03:52PM +0100, Martin Habets wrote:
> > You mean this one : FYI: Fixes to ALSA DBRI driver ?
> > Does it apply also to the CS4231 chipset ?
> 
> Could not see the patch from Christopher Zimmermann in the sparclinux 
> archives.
> Maybe because sparclinux only was on the cc. I've attached it below.
> DBRI are not relevant to CS4231.
--- linux-2.6.13.1/sound/sparc/cs4231.c 2005-09-10 04:42:58.000000000 +0200
+++ linux-2.6.13.1_patched/sound/sparc/cs4231.c 2005-09-14 17:09:49.000000000 
+0200
@@ -173,7 +173,7 @@
 
 #define CS4231_GLOBALIRQ       0x01    /* IRQ is active */
 
-/* definitions for codec irq status */
+/* definitions for codec irq status - CS4231_IRQ_STATUS        */
 
 #define CS4231_PLAYBACK_IRQ    0x10
 #define CS4231_RECORD_IRQ      0x20
@@ -402,7 +402,7 @@
                udelay(100);
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
-               snd_printk("outm: auto calibration time out - reg = 0x%x, value 
= 0x%x\n", reg, value);
+               snd_printdd("outm: auto calibration time out - reg = 0x%x, 
value = 0x%x\n", reg, value);
 #endif
        if (chip->calibrate_mute) {
                chip->image[reg] &= mask;
@@ -425,6 +425,10 @@
             timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & 
CS4231_INIT);
             timeout--)
                udelay(100);
+#ifdef CONFIG_SND_DEBUG
+       if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
+               snd_printdd("out: auto calibration time out - reg = 0x%x, value 
= 0x%x\n", reg, value);
+#endif
        __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
        __cs4231_writeb(chip, value, CS4231P(chip, REG));
        mb();
@@ -440,14 +444,14 @@
                udelay(100);
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
-               snd_printk("out: auto calibration time out - reg = 0x%x, value 
= 0x%x\n", reg, value);
+               snd_printdd("out: auto calibration time out - reg = 0x%x, value 
= 0x%x\n", reg, value);
 #endif
        __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
        __cs4231_writeb(chip, value, CS4231P(chip, REG));
        chip->image[reg] = value;
        mb();
 #if 0
-       printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
+       snd_printdd("codec out - reg 0x%x = 0x%x | timeout = %d\n", 
chip->mce_bit | reg, value, timeout);
 #endif
 }
 
@@ -462,13 +466,13 @@
                udelay(100);
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
-               snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
+               snd_printdd("in: auto calibration time out - reg = 0x%x\n", 
reg);
 #endif
        __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
        mb();
        ret = __cs4231_readb(chip, CS4231P(chip, REG));
 #if 0
-       printk("codec in - reg 0x%x = 0x%x\n", chip->mce_bit | reg, ret);
+       snd_printdd("codec in - reg 0x%x = 0x%x\n", chip->mce_bit | reg, ret);
 #endif
        return ret;
 }
@@ -477,42 +481,42 @@
 
 static void snd_cs4231_debug(cs4231_t *chip)
 {
-       printk("CS4231 REGS:      INDEX = 0x%02x  ",
+       snd_printdd("CS4231 REGS:      INDEX = 0x%02x\n",
               __cs4231_readb(chip, CS4231P(chip, REGSEL)));
-       printk("                 STATUS = 0x%02x\n",
+       snd_printdd("                 STATUS = 0x%02x\n",
               __cs4231_readb(chip, CS4231P(chip, STATUS)));
-       printk("  0x00: left input      = 0x%02x  ", snd_cs4231_in(chip, 0x00));
-       printk("  0x10: alt 1 (CFIG 2)  = 0x%02x\n", snd_cs4231_in(chip, 0x10));
-       printk("  0x01: right input     = 0x%02x  ", snd_cs4231_in(chip, 0x01));
-       printk("  0x11: alt 2 (CFIG 3)  = 0x%02x\n", snd_cs4231_in(chip, 0x11));
-       printk("  0x02: GF1 left input  = 0x%02x  ", snd_cs4231_in(chip, 0x02));
-       printk("  0x12: left line in    = 0x%02x\n", snd_cs4231_in(chip, 0x12));
-       printk("  0x03: GF1 right input = 0x%02x  ", snd_cs4231_in(chip, 0x03));
-       printk("  0x13: right line in   = 0x%02x\n", snd_cs4231_in(chip, 0x13));
-       printk("  0x04: CD left input   = 0x%02x  ", snd_cs4231_in(chip, 0x04));
-       printk("  0x14: timer low       = 0x%02x\n", snd_cs4231_in(chip, 0x14));
-       printk("  0x05: CD right input  = 0x%02x  ", snd_cs4231_in(chip, 0x05));
-       printk("  0x15: timer high      = 0x%02x\n", snd_cs4231_in(chip, 0x15));
-       printk("  0x06: left output     = 0x%02x  ", snd_cs4231_in(chip, 0x06));
-       printk("  0x16: left MIC (PnP)  = 0x%02x\n", snd_cs4231_in(chip, 0x16));
-       printk("  0x07: right output    = 0x%02x  ", snd_cs4231_in(chip, 0x07));
-       printk("  0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17));
-       printk("  0x08: playback format = 0x%02x  ", snd_cs4231_in(chip, 0x08));
-       printk("  0x18: IRQ status      = 0x%02x\n", snd_cs4231_in(chip, 0x18));
-       printk("  0x09: iface (CFIG 1)  = 0x%02x  ", snd_cs4231_in(chip, 0x09));
-       printk("  0x19: left line out   = 0x%02x\n", snd_cs4231_in(chip, 0x19));
-       printk("  0x0a: pin control     = 0x%02x  ", snd_cs4231_in(chip, 0x0a));
-       printk("  0x1a: mono control    = 0x%02x\n", snd_cs4231_in(chip, 0x1a));
-       printk("  0x0b: init & status   = 0x%02x  ", snd_cs4231_in(chip, 0x0b));
-       printk("  0x1b: right line out  = 0x%02x\n", snd_cs4231_in(chip, 0x1b));
-       printk("  0x0c: revision & mode = 0x%02x  ", snd_cs4231_in(chip, 0x0c));
-       printk("  0x1c: record format   = 0x%02x\n", snd_cs4231_in(chip, 0x1c));
-       printk("  0x0d: loopback        = 0x%02x  ", snd_cs4231_in(chip, 0x0d));
-       printk("  0x1d: var freq (PnP)  = 0x%02x\n", snd_cs4231_in(chip, 0x1d));
-       printk("  0x0e: ply upr count   = 0x%02x  ", snd_cs4231_in(chip, 0x0e));
-       printk("  0x1e: rec upr count   = 0x%02x\n", snd_cs4231_in(chip, 0x1e));
-       printk("  0x0f: ply lwr count   = 0x%02x  ", snd_cs4231_in(chip, 0x0f));
-       printk("  0x1f: rec lwr count   = 0x%02x\n", snd_cs4231_in(chip, 0x1f));
+       snd_printdd("  0x00: left input      = 0x%02x\n", snd_cs4231_in(chip, 
0x00));
+       snd_printdd("  0x10: alt 1 (CFIG 2)  = 0x%02x\n", snd_cs4231_in(chip, 
0x10));
+       snd_printdd("  0x01: right input     = 0x%02x\n", snd_cs4231_in(chip, 
0x01));
+       snd_printdd("  0x11: alt 2 (CFIG 3)  = 0x%02x\n", snd_cs4231_in(chip, 
0x11));
+       snd_printdd("  0x02: GF1 left input  = 0x%02x\n", snd_cs4231_in(chip, 
0x02));
+       snd_printdd("  0x12: left line in    = 0x%02x\n", snd_cs4231_in(chip, 
0x12));
+       snd_printdd("  0x03: GF1 right input = 0x%02x\n", snd_cs4231_in(chip, 
0x03));
+       snd_printdd("  0x13: right line in   = 0x%02x\n", snd_cs4231_in(chip, 
0x13));
+       snd_printdd("  0x04: CD left input   = 0x%02x\n", snd_cs4231_in(chip, 
0x04));
+       snd_printdd("  0x14: timer low       = 0x%02x\n", snd_cs4231_in(chip, 
0x14));
+       snd_printdd("  0x05: CD right input  = 0x%02x\n", snd_cs4231_in(chip, 
0x05));
+       snd_printdd("  0x15: timer high      = 0x%02x\n", snd_cs4231_in(chip, 
0x15));
+       snd_printdd("  0x06: left output     = 0x%02x\n", snd_cs4231_in(chip, 
0x06));
+       snd_printdd("  0x16: left MIC (PnP)  = 0x%02x\n", snd_cs4231_in(chip, 
0x16));
+       snd_printdd("  0x07: right output    = 0x%02x\n", snd_cs4231_in(chip, 
0x07));
+       snd_printdd("  0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 
0x17));
+       snd_printdd("  0x08: playback format = 0x%02x\n", snd_cs4231_in(chip, 
0x08));
+       snd_printdd("  0x18: IRQ status      = 0x%02x\n", snd_cs4231_in(chip, 
0x18));
+       snd_printdd("  0x09: iface (CFIG 1)  = 0x%02x\n", snd_cs4231_in(chip, 
0x09));
+       snd_printdd("  0x19: left line out   = 0x%02x\n", snd_cs4231_in(chip, 
0x19));
+       snd_printdd("  0x0a: pin control     = 0x%02x\n", snd_cs4231_in(chip, 
0x0a));
+       snd_printdd("  0x1a: mono control    = 0x%02x\n", snd_cs4231_in(chip, 
0x1a));
+       snd_printdd("  0x0b: init & status   = 0x%02x\n", snd_cs4231_in(chip, 
0x0b));
+       snd_printdd("  0x1b: right line out  = 0x%02x\n", snd_cs4231_in(chip, 
0x1b));
+       snd_printdd("  0x0c: revision & mode = 0x%02x\n", snd_cs4231_in(chip, 
0x0c));
+       snd_printdd("  0x1c: record format   = 0x%02x\n", snd_cs4231_in(chip, 
0x1c));
+       snd_printdd("  0x0d: loopback        = 0x%02x\n", snd_cs4231_in(chip, 
0x0d));
+       snd_printdd("  0x1d: var freq (PnP)  = 0x%02x\n", snd_cs4231_in(chip, 
0x1d));
+       snd_printdd("  0x0e: ply upr count   = 0x%02x\n", snd_cs4231_in(chip, 
0x0e));
+       snd_printdd("  0x1e: rec upr count   = 0x%02x\n", snd_cs4231_in(chip, 
0x1e));
+       snd_printdd("  0x0f: ply lwr count   = 0x%02x\n", snd_cs4231_in(chip, 
0x0f));
+       snd_printdd("  0x1f: rec lwr count   = 0x%02x\n", snd_cs4231_in(chip, 
0x1f));
 }
 
 #endif
@@ -528,11 +532,17 @@
        /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) 
*/
        for (timeout = 5; timeout > 0; timeout--)
                __cs4231_readb(chip, CS4231P(chip, REGSEL));
+#if 0
+       snd_printdd("(0) timeout = %i\n", timeout);
+#endif
        /* end of cleanup sequence */
-       for (timeout = 250;
+       for (timeout = 500;
             timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & 
CS4231_INIT);
             timeout--)
-               udelay(100);
+               udelay(1000);
+#if 0
+       snd_printdd("(1) timeout = %i\n", timeout);
+#endif
 }
 
 static void snd_cs4231_mce_up(cs4231_t *chip)
@@ -545,12 +555,12 @@
                udelay(100);
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
-               snd_printk("mce_up - auto calibration time out (0)\n");
+               snd_printdd("mce_up - auto calibration time out (0)\n");
 #endif
        chip->mce_bit |= CS4231_MCE;
        timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
        if (timeout == 0x80)
-               snd_printk("mce_up [%p]: serious init problem - codec still 
busy\n", chip->port);
+               snd_printdd("mce_up [%p]: serious init problem - codec still 
busy\n", chip->port);
        if (!(timeout & CS4231_MCE))
                __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), 
CS4231P(chip, REGSEL));
        spin_unlock_irqrestore(&chip->lock, flags);
@@ -568,13 +578,13 @@
 #endif
 #ifdef CONFIG_SND_DEBUG
        if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
-               snd_printk("mce_down [%p] - auto calibration time out (0)\n", 
CS4231P(chip, REGSEL));
+               snd_printdd("mce_down [%p] - auto calibration time out (0)\n", 
CS4231P(chip, REGSEL));
 #endif
        chip->mce_bit &= ~CS4231_MCE;
        timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
        __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, 
REGSEL));
        if (timeout == 0x80)
-               snd_printk("mce_down [%p]: serious init problem - codec still 
busy\n", chip->port);
+               snd_printdd("mce_down [%p]: serious init problem - codec still 
busy\n", chip->port);
        if ((timeout & CS4231_MCE) == 0) {
                spin_unlock_irqrestore(&chip->lock, flags);
                return;
@@ -591,7 +601,7 @@
                return;
        }
 #if 0
-       printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
+       snd_printdd("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
 #endif
        /* in 10ms increments, check condition, up to 250ms */
        timeout = 25;
@@ -605,7 +615,7 @@
                spin_lock_irqsave(&chip->lock, flags);
        }
 #if 0
-       printk("(3) jiffies = %li\n", jiffies);
+       snd_printdd("(3) jiffies = %li\n", jiffies);
 #endif
        /* in 10ms increments, check condition, up to 100ms */
        timeout = 10;
@@ -620,8 +630,8 @@
        }
        spin_unlock_irqrestore(&chip->lock, flags);
 #if 0
-       printk("(4) jiffies = %li\n", jiffies);
-       snd_printk("mce_down - exit = 0x%x\n", __cs4231_readb(chip, 
CS4231P(chip, REGSEL)));
+       snd_printdd("(4) jiffies = %li\n", jiffies);
+       snd_printdd("mce_down - exit = 0x%x\n", __cs4231_readb(chip, 
CS4231P(chip, REGSEL)));
 #endif
 }
 
@@ -648,25 +658,59 @@
        snd_pcm_runtime_t *runtime = substream->runtime;
 
        while (1) {
-               unsigned int dma_size = snd_pcm_lib_period_bytes(substream);
-               unsigned int offset = dma_size * (*periods_sent);
+               unsigned int period_size = snd_pcm_lib_period_bytes(substream);
+               unsigned int offset = period_size * (*periods_sent);
 
-               if (dma_size >= (1 << 24))
+               if (period_size >= (1 << 24))
                        BUG();
 
-               if (ebus_dma_request(p, runtime->dma_addr + offset, dma_size))
+               if (ebus_dma_request(p, runtime->dma_addr + offset, 
period_size))
                        return;
 #if 0
-               printk("ebus_advance: Sent period %u (size[%x] offset[%x])\n",
-                      (*periods_sent), dma_size, offset);
+               snd_printdd("ebus_advance: Sent period %u (size[%x] 
offset[%x])\n",
+                      (*periods_sent), period_size, offset);
 #endif
                (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
        }
 }
 #endif
 
-static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on)
+#ifdef SBUS_SUPPORT
+static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, 
unsigned int *periods_sent)
+{
+       cs4231_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
+
+       unsigned int period_size = snd_pcm_lib_period_bytes(substream);
+       unsigned int offset = period_size * (*periods_sent % runtime->periods);
+
+       if(runtime->period_size > 0xffff + 1)
+               BUG();
+
+#if 0
+       snd_printdd("sbus_advance: period_size: %#x | runtime->dma_addr: %#x | 
offset: %#x | total: %#x\n",
+                       period_size, runtime->dma_addr, offset, 
runtime->dma_addr + offset);
+#endif
+
+       switch(substream->stream) {
+       case SNDRV_PCM_STREAM_PLAYBACK:
+               sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA);
+               sbus_writel(period_size, chip->port + APCPNC);
+               break;
+       case SNDRV_PCM_STREAM_CAPTURE:
+               sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA);
+               sbus_writel(period_size, chip->port + APCCNC);
+               break;
+       }
+
+       (*periods_sent) = (*periods_sent + 1) % runtime->periods;
+}
+#endif
+
+static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int 
what, int on)
 {
+       cs4231_t *chip = snd_pcm_substream_chip(substream);
+
 #ifdef EBUS_SUPPORT
        if (chip->flags & CS4231_FLAG_EBUS) {
                if (what & CS4231_PLAYBACK_ENABLE) {
@@ -694,6 +738,64 @@
        } else {
 #endif
 #ifdef SBUS_SUPPORT
+       u32 csr = sbus_readl(chip->port + APCCSR);
+       /* I don't know why, but on sbus the period counter must
+        * only start counting after the first period is sent.
+        * Therefore this dummy thing. */
+       unsigned int dummy = 0;
+#if 0
+       snd_printdd("cs4231: DMA trigger\n");
+#endif
+
+       switch(what) {
+       case CS4231_PLAYBACK_ENABLE:
+               if(on) {
+                       csr &= ~APC_XINT_PLAY;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       csr &= ~APC_PPAUSE;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       snd_cs4231_sbus_advance_dma(substream, &dummy);
+
+                       csr |=  APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
+                               APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL |
+                               APC_XINT_PENA | APC_PDMA_READY;
+                       sbus_writel(csr, chip->port + APCCSR);
+               }
+               else {
+                       csr |= APC_PPAUSE;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       csr &= ~APC_PDMA_READY;
+                       sbus_writel(csr, chip->port + APCCSR);
+               }
+               break;
+       case CS4231_RECORD_ENABLE:
+               if(on) {
+                       csr &= ~APC_XINT_CAPT;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       csr &= ~APC_CPAUSE;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       snd_cs4231_sbus_advance_dma(substream, &dummy);
+
+                       csr |=  APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
+                               APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL |
+                               APC_CDMA_READY;
+
+                       sbus_writel(csr, chip->port + APCCSR);
+               }
+               else {
+                       csr |= APC_CPAUSE;
+                       sbus_writel(csr, chip->port + APCCSR);
+
+                       csr &= ~APC_CDMA_READY;
+                       sbus_writel(csr, chip->port + APCCSR);
+               }
+               break;
+       }
 #endif
 #ifdef EBUS_SUPPORT
        }
@@ -705,6 +807,10 @@
        cs4231_t *chip = snd_pcm_substream_chip(substream);
        int result = 0;
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_trigger.\n");
+#endif
+
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_STOP:
@@ -726,24 +832,16 @@
                }
 
 #if 0
-               printk("TRIGGER: what[%x] on(%d)\n",
+               snd_printdd("TRIGGER: what[%x] on(%d)\n",
                       what, (cmd == SNDRV_PCM_TRIGGER_START));
 #endif
 
                spin_lock_irqsave(&chip->lock, flags);
                if (cmd == SNDRV_PCM_TRIGGER_START) {
-                       cs4231_dma_trigger(chip, what, 1);
+                       cs4231_dma_trigger(substream, what, 1);
                        chip->image[CS4231_IFACE_CTRL] |= what;
-                       if (what & CS4231_PLAYBACK_ENABLE) {
-                               snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, 0xff);
-                               snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, 0xff);
-                       }
-                       if (what & CS4231_RECORD_ENABLE) {
-                               snd_cs4231_out(chip, CS4231_REC_LWR_CNT, 0xff);
-                               snd_cs4231_out(chip, CS4231_REC_UPR_CNT, 0xff);
-                       }
                } else {
-                       cs4231_dma_trigger(chip, what, 0);
+                       cs4231_dma_trigger(substream, what, 0);
                        chip->image[CS4231_IFACE_CTRL] &= ~what;
                }
                snd_cs4231_out(chip, CS4231_IFACE_CTRL,
@@ -791,7 +889,7 @@
        if (channels > 1)
                rformat |= CS4231_STEREO;
 #if 0
-       snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
+       snd_printdd("get_format: 0x%x\n", format);
 #endif
        return rformat;
 }
@@ -944,7 +1042,7 @@
        snd_cs4231_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-       snd_printk("init: (1)\n");
+       snd_printdd("init: (1)\n");
 #endif
        snd_cs4231_mce_up(chip);
        spin_lock_irqsave(&chip->lock, flags);
@@ -957,7 +1055,7 @@
        snd_cs4231_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-       snd_printk("init: (2)\n");
+       snd_printdd("init: (2)\n");
 #endif
 
        snd_cs4231_mce_up(chip);
@@ -967,7 +1065,7 @@
        snd_cs4231_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-       snd_printk("init: (3) - afei = 0x%x\n", 
chip->image[CS4231_ALT_FEATURE_1]);
+       snd_printdd("init: (3) - afei = 0x%x\n", 
chip->image[CS4231_ALT_FEATURE_1]);
 #endif
 
        spin_lock_irqsave(&chip->lock, flags);
@@ -981,7 +1079,7 @@
        snd_cs4231_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-       snd_printk("init: (4)\n");
+       snd_printdd("init: (4)\n");
 #endif
 
        snd_cs4231_mce_up(chip);
@@ -991,7 +1089,7 @@
        snd_cs4231_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-       snd_printk("init: (5)\n");
+       snd_printdd("init: (5)\n");
 #endif
 }
 
@@ -999,6 +1097,10 @@
 {
        unsigned long flags;
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_open.\n");
+#endif
+
        down(&chip->open_mutex);
        if ((chip->mode & mode)) {
                up(&chip->open_mutex);
@@ -1022,6 +1124,11 @@
                       CS4231_RECORD_IRQ |
                       CS4231_TIMER_IRQ);
        snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
+
+#if 0
+       snd_cs4231_debug(chip);
+#endif
+
        spin_unlock_irqrestore(&chip->lock, flags);
 
        chip->mode = mode;
@@ -1117,6 +1224,10 @@
        unsigned char new_pdfr;
        int err;
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_playback_hw_params.\n");
+#endif
+
        if ((err = snd_pcm_lib_malloc_pages(substream,
                                            params_buffer_bytes(hw_params))) < 
0)
                return err;
@@ -1136,11 +1247,29 @@
 static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
 {
        cs4231_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
        unsigned long flags;
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_playback_prepare.\n");
+#endif
+
        spin_lock_irqsave(&chip->lock, flags);
+
        chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
                                            CS4231_PLAYBACK_PIO);
+
+       if(runtime->period_size > 0xffff + 1)
+               BUG();
+
+       snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 
0x00ff);
+       snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 
8 & 0x00ff);
+       chip->p_periods_sent = 0;
+
+#if 0
+       snd_cs4231_debug(chip);
+#endif
+
        spin_unlock_irqrestore(&chip->lock, flags);
 
        return 0;
@@ -1172,12 +1301,16 @@
 static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
 {
        cs4231_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
        unsigned long flags;
 
        spin_lock_irqsave(&chip->lock, flags);
        chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
                                            CS4231_RECORD_PIO);
 
+       snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 
0x00ff);
+       snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 
8 & 0x00ff);
+
        spin_unlock_irqrestore(&chip->lock, flags);
 
        return 0;
@@ -1196,53 +1329,91 @@
                chip->capture_substream->runtime->overrange++;
 }
 
-static void snd_cs4231_generic_interrupt(cs4231_t *chip)
+static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip)
 {
        unsigned long flags;
        unsigned char status;
 
+       /*This is IRQ is not raised by the cs4231*/
+       if(!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
+               return IRQ_NONE;
+
        status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
-       if (!status)
-               return;
 
-       if (status & CS4231_TIMER_IRQ) {
+#if 0
+       snd_printdd("cs4231: snd_cs4231_generic_interruptIRQ, status=%#.2x.\n", 
status);
+#endif
+
+       if(status & CS4231_TIMER_IRQ) {
                if (chip->timer)
                        snd_timer_interrupt(chip->timer, chip->timer->sticks);
        }               
-       if (status & CS4231_PLAYBACK_IRQ)
-               snd_pcm_period_elapsed(chip->playback_substream);
-       if (status & CS4231_RECORD_IRQ) {
+
+#if 0
+       if(status & 0x0f)
+               snd_printdd("cs4231: snd_cs4231_generic_interruptIRQ under- or 
overrun, status=%#.2x.\n", status);
+#endif
+       
+#if 0
+       if(status & CS4231_PLAYBACK_IRQ)
+               ;
+#endif
+
+       if(status & CS4231_RECORD_IRQ)
                snd_cs4231_overrange(chip);
-               snd_pcm_period_elapsed(chip->capture_substream);
-       }
 
        /* ACK the CS4231 interrupt. */
        spin_lock_irqsave(&chip->lock, flags);
        snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
        spin_unlock_irqrestore(&chip->lock, flags);
+
+       return 0;
 }
 
 #ifdef SBUS_SUPPORT
 static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct 
pt_regs *regs)
 {
        cs4231_t *chip = dev_id;
-       u32 csr;
-
-       csr = sbus_readl(chip->port + APCCSR);
-       if (!(csr & (APC_INT_PENDING |
-                    APC_PLAY_INT |
-                    APC_CAPT_INT |
-                    APC_GENL_INT |
-                    APC_XINT_PEMP |
-                    APC_XINT_CEMP)))
-               return IRQ_NONE;
 
        /* ACK the APC interrupt. */
+       u32 csr = sbus_readl(chip->port + APCCSR);
+#if 0
+       static unsigned int irqcount;
+       snd_printdd("cs4231: snd_cs4231_sbus_interruptIRQ No%u, csr=%#.8x.\n", 
irqcount++, csr);
+       /*snd_cs4231_debug(chip);*/
+#endif
        sbus_writel(csr, chip->port + APCCSR);
 
-       snd_cs4231_generic_interrupt(chip);
+#if 0
+       if(csr & APC_XINT_PEMP || csr & APC_XINT_PEMP)
+               snd_printdd("cs4231: snd_cs4231_sbus_interruptIRQ DMA underrun, 
csr=%#.8x.\n", csr);
+#endif
 
-       return IRQ_HANDLED;
+       if(
+               chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE &&
+               csr & APC_PLAY_INT &&
+               csr & APC_XINT_PNVA &&
+               !(csr & APC_XINT_EMPT))
+       {
+               snd_cs4231_sbus_advance_dma(chip->playback_substream, 
&chip->p_periods_sent);
+               snd_pcm_period_elapsed(chip->playback_substream);
+       }
+
+       if(
+               chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE &&
+               csr & APC_CAPT_INT &&
+               csr & APC_XINT_CNVA)
+       {
+               snd_cs4231_sbus_advance_dma(chip->capture_substream, 
&chip->c_periods_sent);
+               snd_pcm_period_elapsed(chip->capture_substream);
+       }
+
+#if 0
+       if(csr & APC_XINT_CEMP)
+               ;
+#endif
+
+       return snd_cs4231_generic_interrupt(chip);
 }
 #endif
 
@@ -1290,7 +1461,17 @@
 #ifdef EBUS_SUPPORT
        }
 #endif
-       ptr += (period_bytes - residue);
+#if 0
+       snd_printdd("Residue: %u\n", (unsigned)residue);
+#endif
+       ptr += period_bytes - residue;
+
+#if 0
+       snd_printdd("cs4231: snd_cs4231_playback_pointer: residue: %#x | ptr: 
%#x\n",
+                       (unsigned)bytes_to_frames(substream->runtime, residue),
+                       (unsigned)bytes_to_frames(substream->runtime, ptr));
+#endif
+
        return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1314,7 +1495,10 @@
 #ifdef EBUS_SUPPORT
        }
 #endif
-       ptr += (period_bytes - residue);
+       ptr += period_bytes - residue;
+#if 0
+       snd_cs4231_debug(chip);
+#endif
        return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1458,6 +1642,10 @@
        snd_pcm_runtime_t *runtime = substream->runtime;
        int err;
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_playback_open.\n");
+#endif
+
        runtime->hw = snd_cs4231_playback;
 
        if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) {
@@ -1496,6 +1684,10 @@
 {
        cs4231_t *chip = snd_pcm_substream_chip(substream);
 
+#if 0
+       snd_printdd("cs4231: snd_cs4231_playback_close.\n");
+#endif
+
        chip->playback_substream = NULL;
        snd_cs4231_close(chip, CS4231_MODE_PLAY);
 
@@ -1982,13 +2174,13 @@
        chip->port = sbus_ioremap(&sdev->resource[0], 0,
                                  chip->regs_size, "cs4231");
        if (!chip->port) {
-               snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
+               snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
                return -EIO;
        }
 
        if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
                        SA_SHIRQ, "cs4231", chip)) {
-               snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n",
+               snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n",
                           dev,
                           __irq_itoa(sdev->irqs[0]));
                snd_cs4231_sbus_free(chip);
@@ -2110,29 +2302,29 @@
        chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10);
        if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) {
                snd_cs4231_ebus_free(chip);
-               snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
+               snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
                return -EIO;
        }
 
        if (ebus_dma_register(&chip->eb2c)) {
                snd_cs4231_ebus_free(chip);
-               snd_printk("cs4231-%d: Unable to register EBUS capture DMA\n", 
dev);
+               snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", 
dev);
                return -EBUSY;
        }
        if (ebus_dma_irq_enable(&chip->eb2c, 1)) {
                snd_cs4231_ebus_free(chip);
-               snd_printk("cs4231-%d: Unable to enable EBUS capture IRQ\n", 
dev);
+               snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", 
dev);
                return -EBUSY;
        }
 
        if (ebus_dma_register(&chip->eb2p)) {
                snd_cs4231_ebus_free(chip);
-               snd_printk("cs4231-%d: Unable to register EBUS play DMA\n", 
dev);
+               snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", 
dev);
                return -EBUSY;
        }
        if (ebus_dma_irq_enable(&chip->eb2p, 1)) {
                snd_cs4231_ebus_free(chip);
-               snd_printk("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
+               snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
                return -EBUSY;
        }
 
@@ -2190,6 +2382,10 @@
 
        found = 0;
 
+#if 0
+       snd_printdd("cs4231: XXX\n");
+#endif
+
 #ifdef SBUS_SUPPORT
        for_all_sbusdev(sdev, sbus) {
                if (!strcmp(sdev->prom_name, "SUNW,CS4231")) {

Reply via email to