Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=59fd8f8d8ee9f7539758419965381bcccfa6f798
Commit:     59fd8f8d8ee9f7539758419965381bcccfa6f798
Parent:     5ba862b77e2d7f9e6e2cb133c43be32ac612aea5
Author:     Trent Piepho <[EMAIL PROTECTED]>
AuthorDate: Sat Aug 18 22:09:42 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 22:05:55 2007 -0300

    V4L/DVB (6066): cx88-alsa: Change order of interrupt enabling, fix spurious 
IRQs
    
    Currently the driver turns on audio interrupts, then sets the audio 
interrupt
    mask to select which interrupts to get.  One could received unwanted
    interrupts since the mask is set _after_ interrupts have already been turned
    on.  Change the order of the operations, and clear any audio interrupt 
status
    bits that are already set for good measure.
    
    Before changing the SRAM FIFO parameters, make sure the FIFO isn't being 
used.
    This shouldn't happen with just the ALSA driver, as it should never try to
    turn on FIFO/RISC/DMA while they are already on.  However, the V4L driver
    needs to turn the audio FIFO on for analog audio output to work 
(undocumented
    cx88 bug).  The FIFO parameters are in an inconsistent state while they are
    updated, and this results in many FIFO sync error IRQs if the FIFO is in use
    while it's in this inconsistent state.
    
    Also create and use a bunch of symbolic constants for audio interrupt mask
    bits.
    
    Signed-off-by: Trent Piepho <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/cx88/cx88-alsa.c |   42 ++++++++++++++++-----------------
 drivers/media/video/cx88/cx88-reg.h  |   13 ++++++++++
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/cx88/cx88-alsa.c 
b/drivers/media/video/cx88/cx88-alsa.c
index 76a8c01..ecb9a74 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -136,12 +136,11 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
        struct cx88_core *core=chip->core;
        struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
 
-
-       dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at 
address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, 
audio_ch->fifo_start);
+       /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
+       cx_clear(MO_AUD_DMACNTRL, 0x11);
 
        /* setup fifo + format - out channel */
-       cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
-                               buf->bpl, buf->risc.dma);
+       cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma);
 
        /* sets bpl size */
        cx_write(MO_AUDD_LNGTH, buf->bpl);
@@ -149,27 +148,30 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
        /* reset counter */
        cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
 
+       dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d lines/irq, "
+               "%d B/irq\n", buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1,
+               chip->num_periods, buf->bpl * chip->num_periods);
+
        dprintk(1, "Enabling IRQ, setting mask from 0x%x to 0x%x\n",
                chip->core->pci_irqmask,
                chip->core->pci_irqmask | PCI_INT_AUDINT);
-       /* enable irqs */
-       cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
-
 
        /* Enables corresponding bits at AUD_INT_STAT */
-       cx_write(MO_AUD_INTMSK,
-                       (1<<16)|
-                       (1<<12)|
-                       (1<<4)|
-                       (1<<0)
-                       );
+       cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
+                               AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
+
+       /* Clean any pending interrupt bits already set */
+       cx_write(MO_AUD_INTSTAT, ~0);
+
+       /* enable audio irqs */
+       cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
 
        /* start dma */
        cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
        cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable 
*/
 
        if (debug)
-               cx88_sram_channel_dump(chip->core, 
&cx88_sram_channels[SRAM_CH25]);
+               cx88_sram_channel_dump(chip->core, audio_ch);
 
        return 0;
 }
@@ -187,12 +189,8 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
 
        /* disable irqs */
        cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
-       cx_clear(MO_AUD_INTMSK,
-                       (1<<16)|
-                       (1<<12)|
-                       (1<<4)|
-                       (1<<0)
-                       );
+       cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
+                               AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
 
        if (debug)
                cx88_sram_channel_dump(chip->core, 
&cx88_sram_channels[SRAM_CH25]);
@@ -239,14 +237,14 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
                                   cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
                                   status, mask);
        /* risc op code error */
-       if (status & (1 << 16)) {
+       if (status & AUD_INT_OPC_ERR) {
                printk(KERN_WARNING "%s/0: audio risc op code 
error\n",core->name);
                cx_clear(MO_AUD_DMACNTRL, 0x11);
                cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
        }
 
        /* risc1 downstream */
-       if (status & 0x01) {
+       if (status & AUD_INT_DN_RISCI1) {
                spin_lock(&chip->reg_lock);
                count = cx_read(MO_AUDD_GPCNT);
                spin_unlock(&chip->reg_lock);
diff --git a/drivers/media/video/cx88/cx88-reg.h 
b/drivers/media/video/cx88/cx88-reg.h
index 2b1d102..2ec52d1 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -612,6 +612,19 @@
 #define SEL_FMRADIO  0x20
 
 // AUD_CTL
+#define AUD_INT_DN_RISCI1      (1 <<  0)
+#define AUD_INT_UP_RISCI1      (1 <<  1)
+#define AUD_INT_RDS_DN_RISCI1  (1 <<  2)
+#define AUD_INT_DN_RISCI2      (1 <<  4) /* yes, 3 is skipped */
+#define AUD_INT_UP_RISCI2      (1 <<  5)
+#define AUD_INT_RDS_DN_RISCI2  (1 <<  6)
+#define AUD_INT_DN_SYNC                (1 << 12)
+#define AUD_INT_UP_SYNC                (1 << 13)
+#define AUD_INT_RDS_DN_SYNC    (1 << 14)
+#define AUD_INT_OPC_ERR                (1 << 16)
+#define AUD_INT_BER_IRQ                (1 << 20)
+#define AUD_INT_MCHG_IRQ       (1 << 21)
+
 #define EN_BTSC_FORCE_MONO      0
 #define EN_BTSC_FORCE_STEREO    1
 #define EN_BTSC_FORCE_SAP       2
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to