summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorAndreas Oberritter <devnull@localhost>2005-05-14 16:32:34 +0000
committerAndreas Oberritter <devnull@localhost>2005-05-14 16:32:34 +0000
commit46ea498a519401300c3d4617be685282a0e64a14 (patch)
treee68d6c0cf175abd0b465d9970fec62f712014990 /linux/drivers/media
parent0bdb469abc8fd016af47c1f236a642f1db3e9ff6 (diff)
downloadmediapointer-dvb-s2-46ea498a519401300c3d4617be685282a0e64a14.tar.gz
mediapointer-dvb-s2-46ea498a519401300c3d4617be685282a0e64a14.tar.bz2
generate an irq after max. 8 packets,
disable pid filtering if there are no users, complain if the number of received packets does not match 'nbpackets', print the card's serial number, Signed-off-by: Andreas Oberritter <obi@linuxtv.org>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/dvb/pluto2/pluto2.c81
1 files changed, 61 insertions, 20 deletions
diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c
index 5b89bcde9..2b29fa0b9 100644
--- a/linux/drivers/media/dvb/pluto2/pluto2.c
+++ b/linux/drivers/media/dvb/pluto2/pluto2.c
@@ -82,7 +82,7 @@
#define SLCS_OVR (0x0001 << 1)
#define SLCS_SWC (0x0001 << 0)
-#define TS_DMA_PACKETS (21)
+#define TS_DMA_PACKETS (8)
#define TS_DMA_BYTES (188 * TS_DMA_PACKETS)
#define I2C_ADDR_TDA10046 0x10
@@ -103,6 +103,7 @@ struct pluto {
struct dvb_frontend *fe;
struct dvb_net dvbnet;
unsigned int full_ts_users;
+ unsigned int users;
/* i2c */
struct i2c_algo_bit_data i2c_bit;
@@ -115,6 +116,7 @@ struct pluto {
/* dma */
dma_addr_t dma_addr;
u8 dma_buf[TS_DMA_BYTES];
+ u8 dummy[4096];
};
static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
@@ -240,6 +242,10 @@ static int pluto_start_feed(struct dvb_demux_feed *f)
{
struct pluto *pluto = feed_to_pluto(f);
+ /* enable PID filtering */
+ if (pluto->users++ == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
+
if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
else if (pluto->full_ts_users++ == 0)
@@ -252,6 +258,10 @@ static int pluto_stop_feed(struct dvb_demux_feed *f)
{
struct pluto *pluto = feed_to_pluto(f);
+ /* disable PID filtering */
+ if (--pluto->users == 0)
+ pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
+
if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
else if (--pluto->full_ts_users == 0)
@@ -274,23 +284,22 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
* although one packet has been transfered.
*/
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
- unsigned int i, valid = 0;
- for (i = 0; i < TS_DMA_BYTES; i += 188)
- if (pluto->dma_buf[i] == 0x47)
- valid++;
- /* bug [1] */
- if (valid == 0)
- return;
- /* bug [2] */
- if (valid != nbpackets)
+ unsigned int i = 0, valid;
+ while (pluto->dma_buf[i] == 0x47)
+ i += 188;
+ valid = i / 188;
+ if (nbpackets != valid) {
+ dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
+ nbpackets, valid);
nbpackets = valid;
+ }
}
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
/* clear the dma buffer. this is needed to be able to identify
* new valid ts packets above */
- memset(pluto->dma_buf, 0, TS_DMA_BYTES);
+ memset(pluto->dma_buf, 0, nbpackets * 188);
/* reset the dma address */
pluto_set_dma_addr(pluto);
@@ -310,6 +319,12 @@ static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
if (!(tscr & (TSCR_DE | TSCR_OVR)))
return IRQ_NONE;
+ if (tscr == 0xffffffff) {
+ // FIXME: maybe recover somehow
+ dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ return IRQ_HANDLED;
+ }
+
/* dma end interrupt */
if (tscr & TSCR_DE) {
pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
@@ -336,6 +351,9 @@ 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 */
@@ -381,9 +399,6 @@ static int __devinit pluto_hw_init(struct pluto *pluto)
/* reset TS logic */
pluto_reset_ts(pluto, 1);
- /* enable PID filtering */
- pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL | PID0_AFIL, 0);
-
return 0;
}
@@ -394,9 +409,6 @@ static void pluto_hw_exit(struct pluto *pluto)
pluto_reset_ts(pluto, 0);
- /* disable PID filtering */
- pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
-
/* LED: disable automatic control, enable yellow, disable green */
pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
@@ -495,7 +507,7 @@ static int __devinit frontend_init(struct pluto *pluto)
pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
if (!pluto->fe) {
- printk(KERN_ERR "pluto2: could not attach frontend\n");
+ dev_err(&pluto->pdev->dev, "could not attach frontend\n");
return -ENODEV;
}
@@ -534,6 +546,34 @@ static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
+static int __devinit pluto_read_serial(struct pluto *pluto)
+{
+ struct pci_dev *pdev = pluto->pdev;
+ unsigned int i, j;
+ u8 __iomem *cis;
+
+ cis = pci_iomap(pdev, 1, 0);
+ if (!cis)
+ return -EIO;
+
+ dev_info(&pdev->dev, "S/N ");
+
+ for (i = 0xe0; i < 0x100; i += 4) {
+ u32 val = readl(&cis[i]);
+ for (j = 0; j < 32; j += 8) {
+ if ((val & 0xff) == 0xff)
+ goto out;
+ printk("%c", val & 0xff);
+ val >>= 8;
+ }
+ }
+out:
+ printk("\n");
+ pci_iounmap(pdev, cis);
+
+ return 0;
+}
+
static int __devinit pluto2_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -610,11 +650,12 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
/* dvb */
ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE);
if (ret < 0)
- goto err_i2c_del_adapter;
+ goto err_i2c_bit_del_bus;
dvb_adapter = &pluto->dvb_adapter;
pluto_read_rev(pluto);
+ pluto_read_serial(pluto);
pluto_read_mac(pluto, dvb_adapter->proposed_mac);
dvbdemux = &pluto->demux;
@@ -671,7 +712,7 @@ err_dvb_dmx_release:
dvb_dmx_release(dvbdemux);
err_dvb_unregister_adapter:
dvb_unregister_adapter(dvb_adapter);
-err_i2c_del_adapter:
+err_i2c_bit_del_bus:
i2c_bit_del_bus(&pluto->i2c_adap);
err_pluto_hw_exit:
pluto_hw_exit(pluto);