]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/dvb/pluto2/pluto2.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / dvb / pluto2 / pluto2.c
index 2310b2bfed4e539fdd1ec16d148f6dd2eb99b94b..960ed5763ae1300f929538210bdbb509d36c4be0 100644 (file)
@@ -39,6 +39,8 @@
 #include "dvbdev.h"
 #include "tda1004x.h"
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define DRIVER_NAME            "pluto2"
 
 #define REG_PIDn(n)            ((n) << 2)      /* PID n pattern registers */
@@ -149,6 +151,15 @@ static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
        writel(val, &pluto->io_mem[reg]);
 }
 
+static void pluto_write_tscr(struct pluto *pluto, u32 val)
+{
+       /* set the number of packets */
+       val &= ~TSCR_ADEF;
+       val |= TS_DMA_PACKETS / 2;
+
+       pluto_writereg(pluto, REG_TSCR, val);
+}
+
 static void pluto_setsda(void *data, int state)
 {
        struct pluto *pluto = data;
@@ -213,11 +224,11 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable)
 
        if (val & TSCR_RSTN) {
                val &= ~TSCR_RSTN;
-               pluto_writereg(pluto, REG_TSCR, val);
+               pluto_write_tscr(pluto, val);
        }
        if (reenable) {
                val |= TSCR_RSTN;
-               pluto_writereg(pluto, REG_TSCR, val);
+               pluto_write_tscr(pluto, val);
        }
 }
 
@@ -284,12 +295,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
         *     but no packets have been transfered.
         * [2] Sometimes (actually very often) NBPACKETS stays at zero
         *     although one packet has been transfered.
+        * [3] Sometimes (actually rarely), the card gets into an erroneous
+        *     mode where it continuously generates interrupts, claiming it
+        *     has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+        *     has been transfered. Only a reset seems to solve this
         */
        if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
                unsigned int i = 0;
                while (pluto->dma_buf[i] == 0x47)
                        i += 188;
                nbpackets = i / 188;
+               if (i == 0) {
+                       pluto_reset_ts(pluto, 1);
+                       dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+               }
        }
 
        dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
@@ -306,7 +325,7 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
                        TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
 }
 
-static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pluto_irq(int irq, void *dev_id)
 {
        struct pluto *pluto = dev_id;
        u32 tscr;
@@ -339,7 +358,7 @@ static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
        }
 
        /* ACK the interrupt */
-       pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+       pluto_write_tscr(pluto, tscr | TSCR_IACK);
 
        return IRQ_HANDLED;
 }
@@ -348,9 +367,6 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
 {
        u32 val = pluto_readreg(pluto, REG_TSCR);
 
-       /* set the number of packets */
-       val &= ~TSCR_ADEF;
-       val |= TS_DMA_PACKETS / 2;
        /* disable AFUL and LOCK interrupts */
        val |= (TSCR_MSKA | TSCR_MSKL);
        /* enable DMA and OVERFLOW interrupts */
@@ -358,7 +374,7 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
        /* clear pending interrupts */
        val |= TSCR_IACK;
 
-       pluto_writereg(pluto, REG_TSCR, val);
+       pluto_write_tscr(pluto, val);
 }
 
 static void pluto_disable_irqs(struct pluto *pluto)
@@ -370,7 +386,7 @@ static void pluto_disable_irqs(struct pluto *pluto)
        /* clear pending interrupts */
        val |= TSCR_IACK;
 
-       pluto_writereg(pluto, REG_TSCR, val);
+       pluto_write_tscr(pluto, val);
 }
 
 static int __devinit pluto_hw_init(struct pluto *pluto)
@@ -648,9 +664,10 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
                goto err_pluto_hw_exit;
 
        /* dvb */
-       ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev);
+       ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME,
+                                  THIS_MODULE, &pdev->dev, adapter_nr);
        if (ret < 0)
-               goto err_i2c_bit_del_bus;
+               goto err_i2c_del_adapter;
 
        dvb_adapter = &pluto->dvb_adapter;
 
@@ -712,8 +729,8 @@ err_dvb_dmx_release:
        dvb_dmx_release(dvbdemux);
 err_dvb_unregister_adapter:
        dvb_unregister_adapter(dvb_adapter);
-err_i2c_bit_del_bus:
-       i2c_bit_del_bus(&pluto->i2c_adap);
+err_i2c_del_adapter:
+       i2c_del_adapter(&pluto->i2c_adap);
 err_pluto_hw_exit:
        pluto_hw_exit(pluto);
 err_free_irq:
@@ -748,7 +765,7 @@ static void __devexit pluto2_remove(struct pci_dev *pdev)
        dvb_dmxdev_release(&pluto->dmxdev);
        dvb_dmx_release(dvbdemux);
        dvb_unregister_adapter(dvb_adapter);
-       i2c_bit_del_bus(&pluto->i2c_adap);
+       i2c_del_adapter(&pluto->i2c_adap);
        pluto_hw_exit(pluto);
        free_irq(pdev->irq, pluto);
        pci_iounmap(pdev, pluto->io_mem);