Mailing List archive

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

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



> 
> I would prefer dvbA_N where A is adapter number (like it is now)
> and N is simply incremented regardless of whether it's net0 or net1.

Implemented it's dvb000 model, with special case of net0
where middle 0 is replaced as _ so we have old format
dvb0_0 for single demux cards.

> MiHu agreed that it would be better to enable the master
> reset in saa7146_init_one() and add a black list for the
> few cards which must not be reset.

Autodetect implemented, needs reset in the code.
Time from reset to autodetection matters.

There's module parameter:
budgetpatch=0 (default) don't use it
budgetpatch=1 autodetect
budgetpatch=2 always (force using it)

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	2005-01-05 01:35:30.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2005-01-05 12:32:24.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;
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c~
Only in dvb-kernel/linux/drivers/media/dvb/ttpci: DEADJOE
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	2005-01-05 01:35:30.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c	2005-01-05 15:33:55.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,119 @@ 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);
+	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 +1315,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 +2104,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 +2241,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 +2522,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 +2598,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 +2654,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	2005-01-05 01:35:30.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.h	2005-01-05 02:05:20.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;
 
Only in dvb-kernel/linux/drivers/media/dvb/ttpci: av7110.h~

Home | Main Index | Thread Index