diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_net.c | 21 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 406 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.h | 21 |
3 files changed, 426 insertions, 22 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index 707ad80ab..64977ba4b 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -123,7 +123,7 @@ static void hexdump( const unsigned char *buf, unsigned short len ) struct dvb_net_priv { int in_use; struct net_device_stats stats; - char name[6]; + char name[7]; u16 pid; struct dvb_net *host; struct dmx_demux *demux; @@ -1157,19 +1157,29 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) struct dvb_net_priv *priv; int result; int if_num; - + char name[20]; + + memset(name, 0, sizeof(name)); + if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE) return -EINVAL; if ((if_num = get_if(dvbnet)) < 0) return -EINVAL; - net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", + sprintf(name, "dvb%1d%1d%1d", + dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num); + /* compatibility fix to keep dvb0_0 format */ + if(name[4] == '0') + name[4] = '_'; + + net = alloc_netdev(sizeof(struct dvb_net_priv), name, dvb_net_setup); if (!net) return -ENOMEM; - sprintf(net->name, "dvb%d_%d", dvbnet->dvbdev->adapter->num, if_num); - + sprintf(net->name, "%s", name); + printk("dvb_net: created network interface %s\n", net->name); + net->addr_len = 6; memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6); @@ -1211,6 +1221,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) dvb_net_stop(net); flush_scheduled_work(); + printk("dvb_net: removed network interface %s\n", net->name); unregister_netdev(net); dvbnet->state[num]=0; dvbnet->device[num] = NULL; diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index a59937924..433fc6449 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -66,6 +66,10 @@ #include "av7110_av.h" #include "av7110_ca.h" #include "av7110_ipack.h" +#define TS_WIDTH (376) +#define TS_HEIGHT (512) +#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) +#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE) int av7110_debug; @@ -76,6 +80,7 @@ static int adac = DVB_ADAC_TI; static int hw_sections; static int rgb_on; static int volume = 255; +static int budgetpatch = 0; module_param_named(debug, av7110_debug, int, 0644); MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); @@ -92,6 +97,8 @@ MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); module_param(volume, int, 0444); MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); +module_param(budgetpatch, int, 0444); +MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); static void restart_feeds(struct av7110 *av7110); @@ -1136,11 +1143,106 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe, return 0; } +/* simplified code from budget-core.c */ +static int stop_ts_capture(struct av7110 *budget) +{ + dprintk(2, "budget: %p\n", budget); + + if (--budget->feeding1) + return budget->feeding1; + saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off + SAA7146_IER_DISABLE(budget->dev, MASK_10); + return 0; +} + +static int start_ts_capture(struct av7110 *budget) +{ + struct saa7146_dev *dev = budget->dev; + + dprintk(2, "budget: %p\n", budget); + + if (budget->feeding1) + return ++budget->feeding1; + memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); + budget->tsf = 0xff; + budget->ttbp = 0; + saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on + SAA7146_IER_ENABLE(budget->dev, MASK_10); // VPE + return ++budget->feeding1; +} + +static int budget_start_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct av7110 *budget = (struct av7110 *) demux->priv; + int status; + + dprintk(2, "av7110: %p\n", budget); + + spin_lock(&budget->feedlock1); + feed->pusi_seen = 0; /* have a clean section start */ + status = start_ts_capture(budget); + spin_unlock(&budget->feedlock1); + return status; +} + +static int budget_stop_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct av7110 *budget = (struct av7110 *) demux->priv; + int status; + + dprintk(2, "budget: %p\n", budget); + + spin_lock(&budget->feedlock1); + status = stop_ts_capture(budget); + spin_unlock(&budget->feedlock1); + return status; +} + +static void vpeirq(unsigned long data) +{ + struct av7110 *budget = (struct av7110 *) data; + u8 *mem = (u8 *) (budget->grabbing); + u32 olddma = budget->ttbp; + u32 newdma = saa7146_read(budget->dev, PCI_VDP3); + + if(budgetpatch == 0) { + printk("av7110.c: vpeirq() called while budgetpatch disabled!" + " check saa7146 IER register\n"); + return; + } + /* nearest lower position divisible by 188 */ + newdma -= newdma % 188; + + if (newdma >= TS_BUFLEN) + return; + + budget->ttbp = newdma; + + if (budget->feeding1 == 0 || newdma == olddma) + return; + +#if 0 + /* track rps1 activity */ + printk("vpeirq: %02x Event Counter 1 0x%04x\n", + mem[olddma], + saa7146_read(budget->dev, EC1R) & 0x3fff ); +#endif + + if (newdma > olddma) /* no wraparound, dump olddma..newdma */ + dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188); + else { /* wraparound, dump olddma..buflen and 0..newdma */ + dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188); + dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188); + } +} static int av7110_register(struct av7110 *av7110) { int ret, i; struct dvb_demux *dvbdemux = &av7110->demux; + struct dvb_demux *dvbdemux1 = &av7110->demux1; dprintk(4, "%p\n", av7110); @@ -1200,6 +1302,36 @@ static int av7110_register(struct av7110 *av7110) dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); + if(budgetpatch) { + /* initialize software demux1 without its own frontend + * demux1 hardware is connected to frontend0 of demux0 + */ + dvbdemux1->priv = (void *) av7110; + + dvbdemux1->filternum = 256; + dvbdemux1->feednum = 256; + dvbdemux1->start_feed = budget_start_feed; + dvbdemux1->stop_feed = budget_stop_feed; + dvbdemux1->write_to_decoder = NULL; + + dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | + DMX_MEMORY_BASED_FILTERING); + + dvb_dmx_init(&av7110->demux1); + + av7110->dmxdev1.filternum = 256; + av7110->dmxdev1.demux = &dvbdemux1->dmx; + av7110->dmxdev1.capabilities = 0; + + dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter); + + /* demux1 is without it's own frontend */ + + dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); + printk("dvb-ttpci: additional demux1 for budget-patch registered\n"); + + /* end software demux1 */ + } return 0; } @@ -1207,12 +1339,20 @@ static int av7110_register(struct av7110 *av7110) static void dvb_unregister(struct av7110 *av7110) { struct dvb_demux *dvbdemux = &av7110->demux; + struct dvb_demux *dvbdemux1 = &av7110->demux1; dprintk(4, "%p\n", av7110); if (!av7110->registered) return; + if (budgetpatch) { + dvb_net_release(&av7110->dvb_net1); + dvbdemux->dmx.close(&dvbdemux1->dmx); + dvb_dmxdev_release(&av7110->dmxdev1); + dvb_dmx_release(&av7110->demux1); + } + dvb_net_release(&av7110->dvb_net); dvbdemux->dmx.close(&dvbdemux->dmx); @@ -1942,12 +2082,168 @@ static void frontend_init(struct av7110 *av7110) } } +/* Budgetpatch note: + * Original hardware design by Roberto Deza: + * There is a DVB_Wiki at + * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page + * where is described this 'DVB TT Budget Patch', on Card Modding: + * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch + * On the short description there is also a link to a external file, + * with more details: + * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip + * + * New software triggering design by Emard that works on + * original Roberto Deza's hardware: + * + * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin. + * GPIO3 is in budget-patch hardware connectd to port B VSYNC + * HS is an internal event of 7146, accessible with RPS + * and temporarily raised high every n lines + * (n in defined in the RPS_THRESH1 counter threshold) + * I think HS is raised high on the beginning of the n-th line + * and remains high until this n-th line that triggered + * it is completely received. When the receiption of n-th line + * ends, HS is lowered. + * + * To transmit data over DMA, 7146 needs changing state at + * port B VSYNC pin. Any changing of port B VSYNC will + * cause some DMA data transfer, with more or less packets loss. + * It depends on the phase and frequency of VSYNC and + * the way of 7146 is instructed to trigger on port B (defined + * in DD1_INIT register, 3rd nibble from the right valid + * numbers are 0-7, see datasheet) + * + * The correct triggering can minimize packet loss, + * dvbtraffic should give this stable bandwidths: + * 22k transponder = 33814 kbit/s + * 27.5k transponder = 38045 kbit/s + * by experiment it is found that the best results + * (stable bandwidths and almost no packet loss) + * are obtained using DD1_INIT triggering number 2 + * (Va at rising edge of VS Fa = HS x VS-failing forced toggle) + * and a VSYNC phase that occurs in the middle of DMA transfer + * (about byte 188*512=96256 in the DMA window). + * + * Phase of HS is still not clear to me how to control, + * It just happens to be so. It can be seen if one enables + * RPS_IRQ and print Event Counter 1 in vpeirq(). Every + * time RPS_INTERRUPT is called, the Event Counter 1 will + * increment. That's how the 7146 is programmed to do event + * counting in this budget-patch.c + * I *think* HPS setting has something to do with the phase + * of HS but I cant be 100% sure in that. + * + * hardware debug note: a working budget card (including budget patch) + * with vpeirq() interrupt setup in mode "0x90" (every 64K) will + * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes + * and that means 3*25=75 Hz of interrupt freqency, as seen by + * watch cat /proc/interrupts + * + * If this frequency is 3x lower (and data received in the DMA + * buffer don't start with 0x47, but in the middle of packets, + * whose lengths appear to be like 188 292 188 104 etc. + * this means VSYNC line is not connected in the hardware. + * (check soldering pcb and pins) + * The same behaviour of missing VSYNC can be duplicated on budget + * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. + */ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { struct av7110 *av7110 = NULL; + int length = TS_WIDTH * TS_HEIGHT; int ret = 0; + int count = 0; dprintk(4, "dev: %p\n", dev); + + /* Set RPS_IRQ to 1 to track rps1 activity. + * Enabling this won't send any interrupt to PC CPU. + */ +#define RPS_IRQ 0 + + if(budgetpatch == 1) { + budgetpatch = 0; + /* autodetect the presence of budget patch + * this only works if saa7146 has been recently + * reset with with MASK_31 to MC1 + * + * will wait for VBI_B event (vertical blank at port B) + * and will reset GPIO3 after VBI_B is detected. + * (GPIO3 should be raised high by CPU to + * test if GPIO3 will generate vertical blank signal + * in budget patch GPIO3 is connected to VSYNC_B + */ + + /* RESET SAA7146 */ + saa7146_write(dev, MC1, MASK_31); + /* autodetection success seems to be time-dependend after reset */ + + /* Fix VSYNC level */ + saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); + /* set vsync_b triggering */ + saa7146_write(dev, DD1_STREAM_B, 0); + /* port B VSYNC at rising edge */ + saa7146_write(dev, DD1_INIT, 0x00000200); + saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI + saa7146_write(dev, MC2, + 1 * (MASK_08 | MASK_24) | // BRS control + 0 * (MASK_09 | MASK_25) | // a + 1 * (MASK_10 | MASK_26) | // b + 0 * (MASK_06 | MASK_22) | // HPS_CTRL1 + 0 * (MASK_05 | MASK_21) | // HPS_CTRL2 + 0 * (MASK_01 | MASK_15) // DEBI + ); + + /* start writing RPS1 code from beginning */ + count = 0; + /* Disable RPS1 */ + saa7146_write(dev, MC1, MASK_29); + /* RPS1 timeout disable */ + saa7146_write(dev, RPS_TOV1, 0); + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B)); + WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); + WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); + WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); +#if RPS_IRQ + /* issue RPS1 interrupt to increment counter */ + WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); +#endif + WRITE_RPS1(cpu_to_le32(CMD_STOP)); + /* Jump to begin of RPS program as safety measure (p37) */ + WRITE_RPS1(cpu_to_le32(CMD_JUMP)); + WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); + +#if RPS_IRQ + /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) + * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled + * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called + */ + saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); + /* set event counter 1 treshold to maximum allowed value (rEC p55) */ + saa7146_write(dev, ECT1R, 0x3fff ); +#endif + /* Set RPS1 Address register to point to RPS code (r108 p42) */ + saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); + /* Enable RPS1, (rFC p33) */ + saa7146_write(dev, MC1, (MASK_13 | MASK_29 )); + + mdelay(10); + /* now send VSYNC_B to rps1 by rising GPIO3 */ + saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); + mdelay(10); + /* if rps1 responded by lowering the GPIO3, + * then we have budgetpatch hardware + */ + if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) { + budgetpatch |= 1; + printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n"); + } + /* Disable RPS1 */ + saa7146_write(dev, MC1, ( MASK_29 )); +#if RPS_IRQ + printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff ); +#endif + } /* prepare the av7110 device struct */ if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) { @@ -1989,18 +2285,101 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac); - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - saa7146_write(dev, BCS_CTRL, 0x80400040); + if(budgetpatch) { + if (NULL == + (av7110->grabbing = + saa7146_vmalloc_build_pgtable(dev->pci, length, &av7110->pt))) + return -ENOMEM; + saa7146_write(dev, PCI_BT_V1, 0x1c1c101f); + saa7146_write(dev, BCS_CTRL, 0x80400040); + /* set dd1 stream a & b */ + saa7146_write(dev, DD1_STREAM_B, 0x00000000); + saa7146_write(dev, DD1_INIT, 0x03000200); + saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); + saa7146_write(dev, BRS_CTRL, 0x60000000); + saa7146_write(dev, BASE_ODD3, 0); + saa7146_write(dev, BASE_EVEN3, 0); + saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); + saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); + + saa7146_write(dev, PITCH3, TS_WIDTH); + saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); + + /* upload all */ + saa7146_write(dev, MC2, 0x077c077c); + saa7146_write(dev, GPIO_CTRL, 0x000000); +#if RPS_IRQ + /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) + * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled + * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called + */ + saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); + /* set event counter 1 treshold to maximum allowed value (rEC p55) */ + saa7146_write(dev, ECT1R, 0x3fff ); +#endif + /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */ + count = 0; + + /* Wait Source Line Counter Threshold (p36) */ + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); + /* Set GPIO3=1 (p42) */ + WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); + WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); + WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); +#if RPS_IRQ + /* issue RPS1 interrupt */ + WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); +#endif + /* Wait reset Source Line Counter Threshold (p36) */ + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); + /* Set GPIO3=0 (p42) */ + WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); + WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); + WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); +#if RPS_IRQ + /* issue RPS1 interrupt */ + WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); +#endif + /* Jump to begin of RPS program (p37) */ + WRITE_RPS1(cpu_to_le32(CMD_JUMP)); + WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); + + /* Fix VSYNC level */ + saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); + /* Set RPS1 Address register to point to RPS code (r108 p42) */ + saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); + /* Set Source Line Counter Threshold, using BRS (rCC p43) + * It generates HS event every TS_HEIGHT lines + * this is related to TS_WIDTH set in register + * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits + * are set to TS_WIDTH bytes (TS_WIDTH=2*188), + * then RPS_THRESH1 should be set to trigger + * every TS_HEIGHT (512) lines. + */ + saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 ); + + /* Enable RPS1 (rFC p33) */ + saa7146_write(dev, MC1, (MASK_13 | MASK_29)); + + /* end of budgetpatch register initialization */ + } else { + saa7146_write(dev, PCI_BT_V1, 0x1c00101f); + saa7146_write(dev, BCS_CTRL, 0x80400040); - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x03000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); + /* set dd1 stream a & b */ + saa7146_write(dev, DD1_STREAM_B, 0x00000000); + saa7146_write(dev, DD1_INIT, 0x03000000); + saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - /* upload all */ - saa7146_write(dev, MC2, 0x077c077c); - saa7146_write(dev, GPIO_CTRL, 0x000000); + /* upload all */ + saa7146_write(dev, MC2, 0x077c077c); + saa7146_write(dev, GPIO_CTRL, 0x000000); + } + + if(budgetpatch) + spin_lock_init(&av7110->feedlock1); + tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); @@ -2115,6 +2494,10 @@ static int av7110_detach (struct saa7146_dev* saa) return 0; } + tasklet_kill(&av7110->vpe_tasklet); + if(budgetpatch) + saa7146_pgtable_free(saa->pci, &av7110->pt); + av7110_exit_v4l(av7110); av7110->arm_rmmod = 1; @@ -2187,6 +2570,9 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr) //printk("av7110_irq: GPIO\n"); tasklet_schedule(&av7110->gpio_tasklet); } + + if (*isr & MASK_10) + tasklet_schedule(&av7110->vpe_tasklet); } @@ -2238,7 +2624,7 @@ static struct saa7146_extension av7110_extension = { .attach = av7110_attach, .detach = av7110_detach, - .irq_mask = MASK_19 | MASK_03, + .irq_mask = MASK_19 | MASK_03 | MASK_10, .irq_func = av7110_irq, }; diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index 019998055..ba45214d1 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -75,7 +75,7 @@ struct av7110 { /* devices */ struct dvb_device dvb_dev; - struct dvb_net dvb_net; + struct dvb_net dvb_net, dvb_net1; struct video_device *v4l_dev; struct video_device *vbi_dev; @@ -152,12 +152,19 @@ struct av7110 { ca_slot_info_t ci_slot[2]; int vidmode; - struct dmxdev dmxdev; - struct dvb_demux demux; - - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - + struct dmxdev dmxdev, dmxdev1; + struct dvb_demux demux, demux1; + spinlock_t feedlock1; /* for budget mode demux1 */ + int feeding1; + u8 tsf; + u32 ttbp; + unsigned char *grabbing; + struct saa7146_pgtable pt; + struct tasklet_struct vpe_tasklet; + + struct dmx_frontend hw_frontend, hw_frontend1; + struct dmx_frontend mem_frontend, mem_frontend1; + int fe_synced; struct semaphore pid_mutex; |