Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: [PATCH] dvb-ttpci+budgetpatch integrated v32



HI

This patch is just keeping up-to-date with 
recent pusi_seen fix included in the CVS

This budgetpatch is working stable during
all my tests. Anybody can suggest some astra
transponder that has both video and ip pids? 
I'd be glad to try how they work at the same 
time over 2 simultaneous DMA channels on the
same 7146.

Emard
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c	2004-12-13 14:34:55.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2005-01-06 13:47:40.000000000 +0100
@@ -123,7 +123,7 @@ static void hexdump( const unsigned char
 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
 	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_
 
 	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 -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c	2004-12-31 16:34:44.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c	2005-01-06 13:48:16.000000000 +0100
@@ -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 DV
 		" 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,120 @@ static int av7110_diseqc_send_burst(stru
 	return 0;
 }
 
+/* By Emard:
+ * copy/pasted those budget routines from
+ * budget-core.c with struct names slightly accomodated. 
+ * I would link it in makefile with the budget-core.c
+ * but the struct's of av7110 and budget aren't yet
+ * interchangeable
+ */
+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 +1316,50 @@ static int av7110_register(struct 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, so here #if 0 */
+#if 0
+		av7110->hw_frontend1.source = DMX_FRONTEND_0;
+		ret = dvbdemux1->dmx.add_frontend(&dvbdemux1->dmx, &av7110->hw_frontend1);
+		if (ret < 0)
+			return ret;
+		av7110->mem_frontend1.source = DMX_MEMORY_FE;
+		ret = dvbdemux1->dmx.add_frontend(&dvbdemux1->dmx, &av7110->mem_frontend1);
+		if (ret < 0)
+			return ret;
+		ret = dvbdemux1->dmx.connect_frontend(&dvbdemux1->dmx, &av7110->hw_frontend1);
+		if (ret < 0)
+			return ret;
+#endif
+
+		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;
 }
 
@@ -1945,9 +2105,102 @@ static void frontend_init(struct av7110 
 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 +2242,173 @@ static int av7110_attach(struct saa7146_
 
 	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
 
-	/* 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);
+/*      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:
+ *
+ *      this rps1 code 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.
+ */
+
+                /* Setup 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 in budget-core.c. 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));
+
+		/* 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 +2523,10 @@ static int av7110_detach (struct saa7146
 		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 +2599,11 @@ static void av7110_irq(struct saa7146_de
 		//printk("av7110_irq: GPIO\n");
 		tasklet_schedule(&av7110->gpio_tasklet);
 	}
+
+	if (*isr & MASK_10)
+	{
+		tasklet_schedule(&av7110->vpe_tasklet);
+	}
 }
 
 
@@ -2238,7 +2655,7 @@ static struct saa7146_extension av7110_e
 	.attach		= av7110_attach,
 	.detach		= av7110_detach,
 
-	.irq_mask	= MASK_19 | MASK_03,
+	.irq_mask	= MASK_19 | MASK_03 | MASK_10,
 	.irq_func	= av7110_irq,
 };
 
Only in dvb-kernel/linux/drivers/media/dvb/ttpci: av7110.c~
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.h dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.h
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.h	2004-12-26 03:16:13.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.h	2005-01-06 13:47:40.000000000 +0100
@@ -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;
 

Home | Main Index | Thread Index