Skip to contentSkip to conversation

2.6.11-rc2 DVB update

PATCH New Johannes Stezenbach 1 participant 9 messages Jan 22, 2005

Subsystems (2)
lore
Share & tools
lore
#1 lore raw

PATCH 1/9 fix RPS init race

In reply to Johannes Stezenbach

- [DVB] saa7146: explicitely disable RPS tasks in saa7146_init_one()

drivers/media/common/saa7146_core.c +2 -2
diff -uraNwB linux-2.6.11-rc2/drivers/media/common/saa7146_core.c linux-2.6.11-rc2-dvb/drivers/media/common/saa7146_core.c
@@ -380,8 +380,8 @@
 	/* disable all irqs */
 	saa7146_write(dev, IER, 0);
 
-	/* shut down all dma transfers */
-	saa7146_write(dev, MC1, 0x00ff0000);
+	/* shut down all dma transfers and rps tasks */
+	saa7146_write(dev, MC1, 0x30ff0000);
 
 	/* clear out any rps-signals pending */
 	saa7146_write(dev, MC2, 0xf8000000);
#0 lore raw

cover 2.6.11-rc2 DVB update

Hi Linus,

this is the usual batch of DVB updates from linuxtv.org CVS. The patches were prepared by Michael Hunold, I just rediffed them to apply cleanly against 2.6.11-rc2, and submit them on his behalf this time.

I realize it is actually a bit late in the 2.6.11 release cycle but I hope they can be included in 2.6.11 anyway, as they don't touch anything outside the DVB subsystem. If not I will factor out the important bug fixes and resubmit them.

1 saa7146 fix possible RPS init race
2 bt8xx support pinnacle pctv-sat, clean-ups
3 dibusb refactoring, support Yakumo/HAMA/Typhoon/HanfTek clones
4 misc support nxt2002 frontend, misc skystar2 fixes
5 dvb-core add ATSC support, misc fixes
6 dib3000 refactoring
7 frontends nxt2002: add ATSC support, misc fixes
8 ttpci dvb-ttpci: fix SMP race, budget: fix init race, misc fixes

Johannes

#8 lore raw

PATCH 8/9 dvb-ttpci: fix SMP race, budget: fixe init race, misc fixes

- [DVB] dvb-ttpci: re-added support for Fujitsu-Siemens DVB-S rev 1.6 0x13c2:0x0006
- [DVB] dvb-ttpci: finally clean up debi irq/tasklet handling to make it work on SMP
- [DVB] dvb-ttpci: misc. changes to av7110_send_fw_cmd() error handling done along the way
- [DVB] dvb-ttpci: budgetpatch integrated into dvb-ttpci: enables full ts option running in parallel with all previous functions of dvb-ttpci
- [DVB] dvb-ttpci: fix Oops provoked by insmod/rmmod test loop, patch by Emard
- [DVB] budget: Fixed start_ts_capture(): saa7146 will not issue a VPE interrupt
if VPE bit is set in PSR and VPE interrupts are enabled afterwards.
- [DVB] budget: enable satelco support. code was commented out, but actually it works, patch by Emard
- [DVB] budget: Budget patch improved driver, fixed slight packet loss by using different trigger mode

drivers/media/dvb/ttpci/av7110.c +507 -85
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttpci/av7110.c linux-2.6.11-rc2-dvb/drivers/media/dvb/ttpci/av7110.c
@@ -67,6 +67,12 @@
 #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;
 
 static int vidmode=CVBS_RGB_OUT;
@@ -75,6 +81,7 @@
 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)");
@@ -91,6 +98,8 @@
 		" 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);
 
@@ -349,27 +358,42 @@
 #endif
 }
 
+#define DEBI_READ 0
+#define DEBI_WRITE 1
+static inline void start_debi_dma(struct av7110 *av7110, int dir,
+				  unsigned long addr, unsigned int len)
+{
+	dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
+	if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+		printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
+		return;
+	}
+
+	SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
+	SAA7146_IER_ENABLE(av7110->dev, MASK_19);
+	if (len < 5)
+		len = 5; /* we want a real DEBI DMA */
+	if (dir == DEBI_WRITE)
+		iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
+	else
+		irdebi(av7110, DEBISWAB, addr, 0, len);
+}
+
 static void debiirq (unsigned long data)
 {
 	struct av7110 *av7110 = (struct av7110*) data;
         int type=av7110->debitype;
         int handle=(type>>8)&0x1f;
-	
-//	dprintk(4, "%p\n",av7110);
+	unsigned int xfer = 0;
 
         print_time("debi");
-	SAA7146_IER_DISABLE(av7110->dev, MASK_19);
-	SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
+	dprintk(4, "type 0x%04x\n", type);
 
         if (type==-1) {
 		printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
 		       jiffies, saa7146_read(av7110->dev, PSR),
 		       saa7146_read(av7110->dev, SSR));
-		spin_lock(&av7110->debilock);
-                ARM_ClearMailBox(av7110);
-                ARM_ClearIrq(av7110);
-		spin_unlock(&av7110->debilock);
-                return;
+		goto debi_done;
         }
         av7110->debitype=-1;
 
@@ -379,22 +403,16 @@
                 dvb_dmx_swfilter_packets(&av7110->demux, 
                                       (const u8 *)av7110->debi_virt, 
                                       av7110->debilen/188);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_PES_RECORD:
                 if (av7110->demux.recording) 
 			av7110_record_cb(&av7110->p2t[handle],
                                   (u8 *)av7110->debi_virt,
                                   av7110->debilen);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_IPMPE:
         case DATA_FSECTION:
@@ -404,11 +422,8 @@
                                              av7110->debilen, NULL, 0, 
                                              av7110->handle2filter[handle], 
                                              DMX_OK, av7110); 
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_CI_GET:
         {
@@ -425,11 +440,8 @@
                         ci_get_data(&av7110->ci_rbuffer, 
                                     av7110->debi_virt, 
                                     av7110->debilen);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
         }
 
         case DATA_COMMON_INTERFACE:
@@ -449,37 +461,35 @@
                 printk("\n");
         }
 #endif
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_DEBUG_MESSAGE:
                 ((s8*)av7110->debi_virt)[Reserved_SIZE-1]=0;
                 printk("%s\n", (s8 *)av7110->debi_virt);
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		xfer = RX_BUFF;
+		break;
 
         case DATA_CI_PUT:
+		dprintk(4, "debi DATA_CI_PUT\n");
         case DATA_MPEG_PLAY:
+		dprintk(4, "debi DATA_MPEG_PLAY\n");
         case DATA_BMP_LOAD:
-                spin_lock(&av7110->debilock);
-                iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
-                ARM_ClearMailBox(av7110);
-                spin_unlock(&av7110->debilock);
-                return;
+		dprintk(4, "debi DATA_BMP_LOAD\n");
+		xfer = TX_BUFF;
+		break;
         default:
                 break;
         }
+debi_done:
         spin_lock(&av7110->debilock);
+	if (xfer)
+		iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
         ARM_ClearMailBox(av7110);
         spin_unlock(&av7110->debilock);
 }
 
+/* irq from av7110 firmware writing the mailbox register in the DPRAM */
 static void gpioirq (unsigned long data)
 {
 	struct av7110 *av7110 = (struct av7110*) data;
@@ -487,27 +497,29 @@
         int len;
         
         if (av7110->debitype !=-1)
+		/* we shouldn't get any irq while a debi xfer is running */
 		printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
 		       jiffies, saa7146_read(av7110->dev, PSR),
 		       saa7146_read(av7110->dev, SSR));
        
-        spin_lock(&av7110->debilock);
+	if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
+		printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
+		BUG(); /* maybe we should try resetting the debi? */
+	}
 
+	spin_lock(&av7110->debilock);
 	ARM_ClearIrq(av7110);
 
-	SAA7146_IER_DISABLE(av7110->dev, MASK_19);
-	SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
-
+	/* see what the av7110 wants */
         av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
         av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
         rxbuf=irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
         txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
 	len = (av7110->debilen + 3) & ~3;
 
-//	dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen);
         print_time("gpio");
+	dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
 
-//	dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff);
         switch (av7110->debitype&0xff) {
 
         case DATA_TS_PLAY:
@@ -579,16 +591,12 @@
 
                 dvb_ringbuffer_read(cibuf,av7110->debi_virt,len,0);
 
-                wake_up(&cibuf->queue);
                 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
                 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-		if (len < 5)
-			len = 5; /* we want a real DEBI DMA */
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "DMA: CI\n");
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
                 spin_unlock(&av7110->debilock);
+		wake_up(&cibuf->queue);
                 return;
         }
 
@@ -620,22 +628,21 @@
 		dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
                 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
                 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "DMA: MPEG_PLAY\n");
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
         case DATA_BMP_LOAD:
                 len=av7110->debilen;
+		dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
                 if (!len) {
                         av7110->bmp_state=BMP_LOADED;
                         iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
                         iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
                         iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
                         wake_up(&av7110->bmpq);
+			dprintk(8, "gpio DATA_BMP_LOAD done\n");
                         break;
                 }
                 if (len>av7110->bmplen)
@@ -647,12 +654,8 @@
                 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
                 av7110->bmpp+=len;
                 av7110->bmplen-=len;
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19 );
-		if (len < 5)
-			len = 5; /* we want a real DEBI DMA */
-                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
+		dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
+		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
@@ -669,22 +672,17 @@
 
         case DATA_TS_RECORD:
         case DATA_PES_RECORD:
-		saa7146_wait_for_debi_done(av7110->dev, 0);
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19);
-                irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len);
+		dprintk(8, "DMA: TS_REC etc.\n");
+		start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
         case DATA_DEBUG_MESSAGE:
-		saa7146_wait_for_debi_done(av7110->dev, 0);
                 if (!len || len>0xff) {
                         iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
                         break;
                 }
-                saa7146_write(av7110->dev, IER, 
-                              saa7146_read(av7110->dev, IER) | MASK_19);
-                irdebi(av7110, DEBISWAB, Reserved, 0, len);
+		start_debi_dma(av7110, DEBI_READ, Reserved, len);
                 spin_unlock(&av7110->debilock);
                 return;
 
@@ -699,8 +697,8 @@
                        av7110->debitype, av7110->debilen);
                 break;
         }      
-        ARM_ClearMailBox(av7110);
         av7110->debitype=-1;
+	ARM_ClearMailBox(av7110);
         spin_unlock(&av7110->debilock);
 }
 
@@ -1145,11 +1144,107 @@
 	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);
+	SAA7146_ISR_CLEAR(budget->dev, MASK_10);
+	return 0;
+}
+
+static int start_ts_capture(struct av7110 *budget)
+{
+	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_IER_ENABLE(budget->dev, MASK_10); /* VPE */
+	saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
+	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) {
+		printk("av7110.c: vpeirq() called while budgetpatch disabled!"
+		       " check saa7146 IER register\n");
+		BUG();
+	}
+	/* nearest lower position divisible by 188 */
+	newdma -= newdma % 188;
+
+	if (newdma >= TS_BUFLEN)
+		return;
+
+	budget->ttbp = newdma;
+
+	if (!budget->feeding1 || (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);
 
@@ -1209,6 +1304,32 @@
         
         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);
+
+		dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
+		printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
+	}
 	return 0;
 }
 
@@ -1216,12 +1337,20 @@
 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);
@@ -1700,6 +1829,7 @@
 static struct stv0297_config nexusca_stv0297_config = {
 
 	.demod_address = 0x1C,
+	.invert = 1,
 	.pll_set = nexusca_stv0297_pll_set,
 };
 
@@ -1899,12 +2029,22 @@
                         av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
 			break;
 
+		case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
+			/* Grundig 29504-451 */
+			av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+			if (av7110->fe) {
+				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+				av7110->fe->ops->set_tone = av7110_set_tone;
+			}
+			break;
+
 		case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
 
 			av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
 			if (av7110->fe) {
 				/* set TDA9819 into DVB mode */
-				saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+				saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 				saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 
 				/* tuner on this needs a slower i2c bus speed */
@@ -1940,13 +2080,169 @@
 	}
 }
 
+/* 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))) {
 		dprintk(1, "out of memory\n");
@@ -1980,6 +2276,7 @@
 	saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
 
 	if (i2c_add_adapter(&av7110->i2c_adap) < 0) {
+err_no_mem:
 		dvb_unregister_adapter (av7110->dvb_adapter);
 		kfree(av7110);
 		return -ENOMEM;
@@ -1987,6 +2284,86 @@
 
 	ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac);
 
+	if (budgetpatch) {
+		spin_lock_init(&av7110->feedlock1);
+		av7110->grabbing = saa7146_vmalloc_build_pgtable(
+					 dev->pci, length, &av7110->pt);
+		if (!av7110->grabbing)
+			goto err_no_mem;
+		saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
+		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 */
+		tasklet_init (&av7110->vpe_tasklet,  vpeirq,  (unsigned long) av7110);
+	} else {
 	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
 	saa7146_write(dev, BCS_CTRL, 0x80400040);
 
@@ -1998,6 +2375,7 @@
 	/* upload all */
 	saa7146_write(dev, MC2, 0x077c077c);
         saa7146_write(dev, GPIO_CTRL, 0x000000);
+	}
 
 	tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
 	tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
@@ -2109,10 +2487,21 @@
 	struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
 	dprintk(4, "%p\n", av7110);
 	
-	if( 0 == av7110->device_initialized ) {
+	if (!av7110->device_initialized )
 		return 0;
-	}
 
+	if (budgetpatch) {
+		/* Disable RPS1 */
+		saa7146_write(saa, MC1, MASK_29);
+		/* VSYNC LOW (inactive) */
+		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+		saa7146_write(saa, MC1, MASK_20);	/* DMA3 off */
+		SAA7146_IER_DISABLE(saa, MASK_10);
+		SAA7146_ISR_CLEAR(saa, MASK_10);
+		msleep(50);
+		tasklet_kill(&av7110->vpe_tasklet);
+		saa7146_pgtable_free(saa->pci, &av7110->pt);
+	}
 	av7110_exit_v4l(av7110);
 
 	av7110->arm_rmmod=1;
@@ -2121,6 +2510,9 @@
 	while (av7110->arm_thread)
 		msleep(1);
 
+	tasklet_kill(&av7110->debi_tasklet);
+	tasklet_kill(&av7110->gpio_tasklet);
+
 	dvb_unregister(av7110);
 	
 	SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
@@ -2153,13 +2545,43 @@
 {
 	struct av7110 *av7110 = dev->ext_priv;
 
-	if (*isr & MASK_19)
+	//print_time("av7110_irq");
+
+	/* Note: Don't try to handle the DEBI error irq (MASK_18), in
+	 * intel mode the timeout is asserted all the time...
+	 */
+
+	if (*isr & MASK_19) {
+		//printk("av7110_irq: DEBI\n");
+		/* Note 1: The DEBI irq is level triggered: We must enable it
+		 * only after we started a DMA xfer, and disable it here
+		 * immediately, or it will be signalled all the time while
+		 * DEBI is idle.
+		 * Note 2: You would think that an irq which is masked is
+		 * not signalled by the hardware. Not so for the SAA7146:
+		 * An irq is signalled as long as the corresponding bit
+		 * in the ISR is set, and disabling irqs just prevents the
+		 * hardware from setting the ISR bit. This means a) that we
+		 * must clear the ISR *after* disabling the irq (which is why
+		 * we must do it here even though saa7146_core did it already),
+		 * and b) that if we were to disable an edge triggered irq
+		 * (like the gpio irqs sadly are) temporarily we would likely
+		 * loose some. This sucks :-(
+		 */
+		SAA7146_IER_DISABLE(av7110->dev, MASK_19);
+		SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
 		tasklet_schedule (&av7110->debi_tasklet);
+	}
 	
-	if (*isr & MASK_03)
+	if (*isr & MASK_03) {
+		//printk("av7110_irq: GPIO\n");
 		tasklet_schedule (&av7110->gpio_tasklet);
 }
 
+	if ((*isr & MASK_10) && budgetpatch)
+		tasklet_schedule(&av7110->vpe_tasklet);
+}
+
 
 static struct saa7146_extension av7110_extension;
 
@@ -2173,8 +2595,9 @@
 MAKE_AV7110_INFO(ttc_1_X,    "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
 MAKE_AV7110_INFO(ttc_2_X,    "Technotrend/Hauppauge WinTV DVB-C rev2.X");
 MAKE_AV7110_INFO(tts_2_X,    "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
-MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV Nexus-S rev1.3");
+MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(tts_1_X,   0x13c2, 0x0000),
@@ -2184,10 +2607,10 @@
 	MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
 	MAKE_EXTENSION_PCI(fsc,       0x110a, 0x0000),
 	MAKE_EXTENSION_PCI(ttc_1_X,   0x13c2, 0x000a),
+	MAKE_EXTENSION_PCI(fss,       0x13c2, 0x0006),
 
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
-/*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0006), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-S v????
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0008), UNDEFINED CARD */ // TT/Hauppauge WinTV DVB-T v????
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
 
@@ -2208,7 +2631,7 @@
 	.attach		= av7110_attach,
 	.detach		= av7110_detach,
 
-	.irq_mask	= MASK_19|MASK_03,
+	.irq_mask	= MASK_19 | MASK_03 | MASK_10,
 	.irq_func	= av7110_irq,
 };	
 
drivers/media/dvb/ttpci/av7110.h +13 -1
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttpci/av7110.h linux-2.6.11-rc2-dvb/drivers/media/dvb/ttpci/av7110.h
@@ -115,7 +115,7 @@
 
         int                     bmpp;
         int                     bmplen;
-        int                     bmp_state;
+	volatile int		bmp_state;
 #define BMP_NONE     0
 #define BMP_LOADING  1
 #define BMP_LOADINGS 2
@@ -158,6 +158,18 @@
         struct dmx_frontend	hw_frontend;
         struct dmx_frontend	mem_frontend;
 
+	/* for budget mode demux1 */
+	struct dmxdev		dmxdev1;
+	struct dvb_demux	demux1;
+	struct dvb_net		dvb_net1;
+	spinlock_t		feedlock1;
+	int			feeding1;
+	u8			tsf;
+	u32			ttbp;
+	unsigned char           *grabbing;
+	struct saa7146_pgtable  pt;
+	struct tasklet_struct   vpe_tasklet;
+
         int                     fe_synced; 
         struct semaphore        pid_mutex;
 
drivers/media/dvb/ttpci/av7110_hw.c +62 -30

259 lines not on this page · raw message

drivers/media/dvb/ttpci/av7110_v4l.c +2 -2
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttpci/av7110_v4l.c linux-2.6.11-rc2-dvb/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -250,7 +248,7 @@
 			if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
 				dprintk(1, "setting band in demodulator failed.\n");
 		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 			saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 		}
 	}
@@ -591,7 +589,7 @@
 			if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
 				dprintk(1, "setting band in demodulator failed.\n");
 		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-			saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+			saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
 			saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
 		}
 
drivers/media/dvb/ttpci/budget.c +3 -3
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttpci/budget.c linux-2.6.11-rc2-dvb/drivers/media/dvb/ttpci/budget.c
@@ -414,7 +412,7 @@
 {
 	switch(budget->dev->pci->subsystem_device) {
 	case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
-
+	case 0x1013:
 		// try the ALPS BSRV2 first of all
 		budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
@@ -522,14 +517,14 @@
 MAKE_BUDGET_INFO(ttbs,	"TT-Budget/WinTV-NOVA-S  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbc,	"TT-Budget/WinTV-NOVA-C  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbt,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
-/* MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC); UNDEFINED HARDWARE - mail linuxtv.org list */
+MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC);
 MAKE_BUDGET_INFO(fsacs, "Fujitsu Siemens Activy Budget-S PCI", BUDGET_FS_ACTIVY);
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
-/*	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), UNDEFINED HARDWARE */
+	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
 	MAKE_EXTENSION_PCI(fsacs, 0x1131, 0x4f61),
 	{
 		.vendor    = 0,
drivers/media/dvb/ttpci/budget-core.c +13 -4
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttpci/budget-core.c linux-2.6.11-rc2-dvb/drivers/media/dvb/ttpci/budget-core.c
@@ -89,11 +87,18 @@
 	 *	Pitch: 188, NumBytes3: 188, NumLines3: 1024
 	 */
 
-	if (budget->card->type == BUDGET_FS_ACTIVY) {
+        switch(budget->card->type) {
+	case BUDGET_FS_ACTIVY:
 		saa7146_write(dev, DD1_INIT, 0x04000000);
 		saa7146_write(dev, MC2, (MASK_09 | MASK_25));
 		saa7146_write(dev, BRS_CTRL, 0x00000000);
-	} else {
+		break;
+	case BUDGET_PATCH:
+		saa7146_write(dev, DD1_INIT, 0x00000200);
+		saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+		saa7146_write(dev, BRS_CTRL, 0x60000000);
+		break;
+	default:
 		if (budget->video_port == BUDGET_VIDEO_PORTA) {
 			saa7146_write(dev, DD1_INIT, 0x06000200);
 			saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
@@ -122,9 +127,10 @@
 	}
 
       	saa7146_write(dev, MC2, (MASK_04 | MASK_20));
-     	saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
 
-	SAA7146_IER_ENABLE(budget->dev, MASK_10);	// VPE
+	SAA7146_ISR_CLEAR(budget->dev, MASK_10);	/* VPE */
+	SAA7146_IER_ENABLE(budget->dev, MASK_10);	/* VPE */
+	saa7146_write(dev, MC1, (MASK_04 | MASK_20));	/* DMA3 on */
 
         return ++budget->feeding;
 }
@@ -249,6 +254,7 @@
                 return -EINVAL;
 
    	spin_lock(&budget->feedlock);   
+	feed->pusi_seen = 0; /* have a clean section start */
 	status = start_ts_capture (budget);
    	spin_unlock(&budget->feedlock);
 	return status;
drivers/media/dvb/ttpci/budget-patch.c +311 -35

440 lines not on this page · raw message

#5 lore raw

PATCH 5/9 add ATSC support, misc fixes

In reply to Johannes Stezenbach

- [DVB] dvb-core: vfree() checking cleanups, patch by Domen Puncer
- [DVB] dvb-core: fix handling of discontinuity indicator in section filter, bug reported by Frank Rosengart
- [DVB] dvb-core: handle PUSI in section filter correctly, patch by Emard, bug reported by Patrick Valsecchi
- [DVB] dvb-core: add support for ATSC/VSB frontends, patch by Taylor Jacob
- [DVB] dvb-core: removed semi-colon from a very wrong place; FE_ENABLE_HIGH_LNB_VOLTAGE kernel oops; thanks to Christophe Massiot
- [DVB] dvb-core: Fixed slow tuning problems, remove frequeny bending support from frontend code, code simplification

drivers/media/dvb/dvb-core/dvb_demux.c +40 -18
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dvb-core/dvb_demux.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -247,7 +249,22 @@
 		}
 
 /* 
-** Losless Section Demux 1.4 by Emard
+** Losless Section Demux 1.4.1 by Emard
+** Valsecchi Patrick:
+**  - middle of section A  (no PUSI)
+**  - end of section A and start of section B 
+**    (with PUSI pointing to the start of the second section)
+**  
+**  In this case, without feed->pusi_seen you'll receive a garbage section
+**  consisting of the end of section A. Basically because tsfeedp
+**  is incemented and the use=0 condition is not raised
+**  when the second packet arrives.
+**
+** Fix:
+** when demux is started, let feed->pusi_seen = 0 to
+** prevent initial feeding of garbage from the end of
+** previous section. When you for the first time see PUSI=1
+** then set feed->pusi_seen = 1
 */
 static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
 {
@@ -293,7 +310,12 @@
 		sec->seclen = seclen;
 		sec->crc_val = ~0;
 		/* dump [secbuf .. secbuf+seclen) */
+		if(feed->pusi_seen)
 		dvb_dmx_swfilter_section_feed(feed);
+#ifdef DVB_DEMUX_SECTION_LOSS_LOG
+		else
+			printk("dvb_demux.c pusi not seen, discarding section data\n");
+#endif
 		sec->secbufp += seclen; /* secbufp and secbuf moving together is */
 		sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
 		}
@@ -305,7 +327,7 @@
 static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 
 {
 	u8 p, count;
-	int ccok;
+	int ccok, dc_i = 0;
 	u8 cc;
 
 	count = payload(buf);
@@ -316,31 +338,41 @@
 	p = 188-count; /* payload start */
 
 	cc = buf[3] & 0x0f;
-	ccok = ((feed->cc+1) & 0x0f) == cc ? 1 : 0;
+	ccok = ((feed->cc + 1) & 0x0f) == cc;
 	feed->cc = cc;
-	if(ccok == 0)
-	{
+
+	if (buf[3] & 0x20) {
+		/* adaption field present, check for discontinuity_indicator */
+		if ((buf[4] > 0) && (buf[5] & 0x80))
+			dc_i = 1;
+	}
+
+	if (!ccok || dc_i) {
 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
 		printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
 		/* those bytes under sume circumstances will again be reported
 		** in the following dvb_dmx_swfilter_section_new
 		*/
 #endif
+		/* Discontinuity detected. Reset pusi_seen = 0 to
+		** stop feeding of suspicious data until next PUSI=1 arrives
+		*/
+		feed->pusi_seen = 0;
 		dvb_dmx_swfilter_section_new(feed);
 		return 0;
 	}
 
-	if(buf[1] & 0x40)
-	{
+	if (buf[1] & 0x40) {
 		// PUSI=1 (is set), section boundary is here
-		if(count > 1 && buf[p] < count)
-		{
+		if (count > 1 && buf[p] < count) {
 			const u8 *before = buf+p+1;
 			u8 before_len = buf[p];
 			const u8 *after = before+before_len;
 			u8 after_len = count-1-before_len;
 
 			dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
+			/* before start of new section, set pusi_seen = 1 */
+			feed->pusi_seen = 1;
 			dvb_dmx_swfilter_section_new(feed);
 			dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
 		}
@@ -349,9 +381,7 @@
 			if(count > 0)
 				printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
 #endif
-	}
-	else
-	{
+	} else {
 		// PUSI=0 (is not set), no section boundary
 		const u8 *entire = buf+p;
 		u8 entire_len = count;
@@ -784,10 +814,8 @@
 	}
 
 #ifndef NOBUFS
-	if (feed->buffer) { 
 		vfree(feed->buffer);
 		feed->buffer=0;
-	}
 #endif
 
 	feed->state = DMX_STATE_FREE;
@@ -1055,10 +1094,8 @@
 		return -EINVAL;
 	}
 #ifndef NOBUFS
-	if (dvbdmxfeed->buffer) {
 		vfree(dvbdmxfeed->buffer);
 		dvbdmxfeed->buffer=0;
-	}
 #endif
 	dvbdmxfeed->state=DMX_STATE_FREE;
 
@@ -1269,9 +1317,7 @@
 	struct dmx_demux *dmx = &dvbdemux->dmx;
 
 	dmx_unregister_demux(dmx);
-	if (dvbdemux->filter)
 		vfree(dvbdemux->filter);
-	if (dvbdemux->feed)
 		vfree(dvbdemux->feed);
 	return 0;
 }
drivers/media/dvb/dvb-core/dvb_demux.h +1 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dvb-core/dvb_demux.h linux-2.6.11-rc2-dvb/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -93,6 +93,7 @@
         enum dmx_ts_pes pes_type;
 
         int cc;
+        int pusi_seen; /* prevents feeding of garbage from previous section */
 
         u16 peslen;
 
drivers/media/dvb/dvb-core/dvb_frontend.c +198 -147

774 lines not on this page · raw message

drivers/media/dvb/dvb-core/dvb_frontend.h +1 -22
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dvb-core/dvb_frontend.h linux-2.6.11-rc2-dvb/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -115,28 +115,7 @@
 	struct dvb_frontend_ops* ops;
 	struct dvb_adapter *dvb;
 	void* demodulator_priv;
-
-	struct dvb_device *dvbdev;
-	struct dvb_frontend_parameters parameters;
-	struct dvb_fe_events events;
-	struct semaphore sem;
-	struct list_head list_head;
-	wait_queue_head_t wait_queue;
-	pid_t thread_pid;
-	unsigned long release_jiffies;
-	int state;
-	int bending;
-	int lnb_drift;
-	int inversion;
-	int auto_step;
-	int auto_sub_step;
-	int started_auto_step;
-	int min_delay;
-	int max_drift;
-	int step_size;
-	int exit;
-	int wakeup;
-	fe_status_t status;
+	void* frontend_priv;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter* dvb,
drivers/media/dvb/dvb-core/dvb_net.c +10 -4
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dvb-core/dvb_net.c
@@ -123,7 +123,6 @@
 struct dvb_net_priv {
 	int in_use;
         struct net_device_stats stats;
-        char name[6];
 	u16 pid;
 	struct dvb_net *host;
         struct dmx_demux *demux;
@@ -1165,12 +1162,17 @@
 	if ((if_num = get_if(dvbnet)) < 0)
 		return -EINVAL;
 
-	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb",
-			   dvb_net_setup);
+	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
 	if (!net)
 		return -ENOMEM;
 	
-	sprintf(net->name, "dvb%d_%d", dvbnet->dvbdev->adapter->num, if_num);
+	if (dvbnet->dvbdev->id)
+		snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
+			 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
+	else
+		/* compatibility fix to keep dvb0_0 format */
+		snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
+			 dvbnet->dvbdev->adapter->num, if_num);
 
 	net->addr_len  		= 6;
 	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
@@ -1196,6 +1198,7 @@
 		free_netdev(net);
 		return result;
 	}
+	printk("dvb_net: created network interface %s\n", net->name);
 
         return if_num;
 }
@@ -1214,6 +1216,7 @@
 
 	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;
drivers/media/dvb/ttusb-dec/ttusb_dec.c +3 -3
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/ttusb-dec/ttusb_dec.c linux-2.6.11-rc2-dvb/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -756,7 +755,7 @@
 
 	if (!dec->iso_stream_count) {
 		for (i = 0; i < ISO_BUF_COUNT; i++)
-			usb_unlink_urb(dec->iso_urb[i]);
+			usb_kill_urb(dec->iso_urb[i]);
 	}
 
 	up(&dec->iso_sem);
@@ -821,7 +820,7 @@
 				       "error %d\n", __FUNCTION__, i, result);
 
 				while (i) {
-					usb_unlink_urb(dec->iso_urb[i - 1]);
+					usb_kill_urb(dec->iso_urb[i - 1]);
 					i--;
 				}
 
@@ -1379,7 +1378,7 @@
 	dec->iso_stream_count = 0;
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
-		usb_unlink_urb(dec->iso_urb[i]);
+		usb_kill_urb(dec->iso_urb[i]);
 
 	ttusb_dec_free_iso_urbs(dec);
 }
include/linux/dvb/frontend.h +8 -3
diff -uraNwB linux-2.6.11-rc2/include/linux/dvb/frontend.h linux-2.6.11-rc2-dvb/include/linux/dvb/frontend.h
@@ -158,10 +158,11 @@
         QAM_64,
         QAM_128,
         QAM_256,
-	QAM_AUTO
+	QAM_AUTO,
+	VSB_8,
+	VSB_16
 } fe_modulation_t;
 
-
 typedef enum fe_transmit_mode {
 	TRANSMISSION_MODE_2K,
 	TRANSMISSION_MODE_8K,
@@ -206,6 +206,9 @@
         fe_modulation_t  modulation;  /* modulation type (see above) */
 };
 
+struct dvb_vsb_parameters {
+	fe_modulation_t	modulation;  /* modulation type (see above) */
+};
 
 struct dvb_ofdm_parameters {
         fe_bandwidth_t      bandwidth;
@@ -219,13 +222,14 @@
 
 
 struct dvb_frontend_parameters {
-        __u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM */
+	__u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
                                   /* intermediate frequency in kHz for QPSK */
 	fe_spectral_inversion_t inversion;
 	union {
 		struct dvb_qpsk_parameters qpsk;
 		struct dvb_qam_parameters  qam;
 		struct dvb_ofdm_parameters ofdm;
+		struct dvb_vsb_parameters vsb;
 	} u;
 };
 
include/linux/dvb/version.h +1 -0
diff -uraNwB linux-2.6.11-rc2/include/linux/dvb/version.h linux-2.6.11-rc2-dvb/include/linux/dvb/version.h
@@ -24,6 +24,7 @@
 #define _DVBVERSION_H_
 
 #define DVB_API_VERSION 3
+#define DVB_API_VERSION_MINOR 1
 
 #endif /*_DVBVERSION_H_*/
 
#4 lore raw

PATCH 4/9 support nxt2002 frontend, misc skystar2 fixes

In reply to Johannes Stezenbach

- [DVB] nxt2002: add support for nxt2002 frontend (firmware extraction, Kconfig, driver)
- [DVB] skystar2: misc cleanup, remove unneeded casts, remove unreachable code, patches by Francois Romieu
- [DVB] skystar2: fix mt352 clock setting for VHF (6 and 7 MHz bw channels), patch by Thomas Martin and Dieter Zander:
- [DVB] b2c2-usb-core: fix file permissions to be octal, ISO C90 compile fix, temporally repaired the request_types
- [DVB] remove remains of dibusb driver after splitup

Documentation/dvb/get_dvb_firmware +19 -1
diff -uraNwB linux-2.6.11-rc2/Documentation/dvb/get_dvb_firmware linux-2.6.11-rc2-dvb/Documentation/dvb/get_dvb_firmware
@@ -21,7 +21,8 @@
 use File::Temp qw/ tempdir /;
 use IO::Handle;
 
-@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", "dec2540t", "dec3000s", "vp7041", "dibusb" );
+@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
+		"dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002" );
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -233,6 +234,23 @@
 	$outfile;
 }
 
+sub nxt2002 {
+    my $sourcefile = "Broadband4PC_4_2_11.zip";
+    my $url = "http://www.bbti.us/download/windows/$sourcefile";
+    my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
+    my $outfile = "dvb-fe-nxt2002.fw";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+    checkstandard();
+    
+    wgetfile($sourcefile, $url);
+    unzip($sourcefile, $tmpdir);
+    verify("$tmpdir/SkyNETU.sys", $hash);
+    extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
+
+    $outfile;
+}
+
 # ---------------------------------------------------------------
 # Utilities
 
drivers/media/dvb/frontends/Makefile +2 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/Makefile linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/Makefile
@@ -24,3 +24,5 @@
 obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
+obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
+
drivers/media/dvb/frontends/Kconfig +12 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/Kconfig linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/Kconfig
@@ -46,6 +46,7 @@
 config DVB_SP8870
  	tristate "Spase sp8870 based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
  	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -56,6 +57,7 @@
 config DVB_SP887X
  	tristate "Spase sp887x based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -84,6 +86,7 @@
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
 	depends on DVB_CORE
+	select FW_LOADER
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -145,4 +148,13 @@
 	help
 	  A DVB-C tuner module. Say Y when you want to support this frontend.
 
+comment "ATSC (North American/Korean Terresterial DTV) frontends"
+	depends on DVB_CORE
+
+config DVB_NXT2002
+	tristate "Nxt2002 based"
+	depends on DVB_CORE
+	help
+	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
+
 endmenu
drivers/media/dvb/b2c2/Kconfig +4 -2
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/b2c2/Kconfig linux-2.6.11-rc2-dvb/drivers/media/dvb/b2c2/Kconfig
@@ -4,9 +4,11 @@
 	select DVB_STV0299
 	select DVB_MT352
 	select DVB_MT312
+	select DVB_NXT2002
 	help
 	  Support for the Skystar2 PCI DVB card by Technisat, which
-	  is equipped with the FlexCopII chipset by B2C2.
+	  is equipped with the FlexCopII chipset by B2C2, and
+	  for the B2C2/BBTI Air2PC-ATSC card.
 
 	  Say Y if you own such a device and want to use it.
 
@@ -17,7 +19,7 @@
 	select DVB_MT352
 	help
 	  Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
-	  this does nothing, but providing basic function for the used usb
+	  the does nothing, but providing basic function for the used usb 
 	  protocol.
 
 	  Say Y if you own such a device and want to use it.
drivers/media/dvb/b2c2/skystar2.c +193 -159

550 lines not on this page · raw message

drivers/media/dvb/b2c2/b2c2-usb-core.c +12 -2
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/b2c2/b2c2-usb-core.c linux-2.6.11-rc2-dvb/drivers/media/dvb/b2c2/b2c2-usb-core.c
@@ -33,7 +33,7 @@
 }
 
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
 
 #define deb_info(args...) dprintk(0x01,args)
@@ -89,12 +89,22 @@
 
 /* request types */
 typedef enum {
+
+/* something is wrong with this part
 	RTYPE_READ_DW         = (1 << 6),
 	RTYPE_WRITE_DW_1      = (3 << 6),
 	RTYPE_READ_V8_MEMORY  = (6 << 6),
 	RTYPE_WRITE_V8_MEMORY = (7 << 6),
 	RTYPE_WRITE_V8_FLASH  = (8 << 6),
 	RTYPE_GENERIC         = (9 << 6),
+*/
+	RTYPE_READ_DW = (3 << 6),
+	RTYPE_WRITE_DW_1 = (1 << 6),
+	
+	RTYPE_READ_V8_MEMORY  = (6 << 6),
+	RTYPE_WRITE_V8_MEMORY = (7 << 6),
+	RTYPE_WRITE_V8_FLASH  = (8 << 6),
+	RTYPE_GENERIC         = (9 << 6),
 } b2c2_usb_request_type_t;
 
 /* request */
@@ -391,9 +401,9 @@
 		}
 	/* initialising and submitting iso urbs */
 	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
-		deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
 		int frame_offset = 0;
 		struct urb *urb = b2c2->iso_urb[i];
+		deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
 
 		urb->dev = b2c2->udev;
 		urb->context = b2c2;
drivers/media/dvb/dibusb/dvb-dibusb.c +0 -1032

1,032 lines not on this page · raw message

#6 lore raw

PATCH 6/9 refactoring

In reply to Johannes Stezenbach

- [DVB] dib3000: driver refactoring, makes it easier to support device clones

drivers/media/dvb/frontends/dib3000-common.c +1 -63
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/dib3000-common.c linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/dib3000-common.c
@@ -2,7 +2,7 @@
 
 #ifdef CONFIG_DVB_DIBCOM_DEBUG
 static int debug;
-module_param(debug, int, 0x644);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
 #endif
 #define deb_info(args...) dprintk(0x01,args)
@@ -42,65 +41,6 @@
 	return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
-int dib3000_init_pid_list(struct dib3000_state *state, int num)
-{
-	int i;
-	if (state != NULL) {
-		state->pid_list = kmalloc(sizeof(struct dib3000_pid) * num,GFP_KERNEL);
-		if (state->pid_list == NULL)
-			return -ENOMEM;
-
-		deb_info("initializing %d pids for the pid_list.\n",num);
-		spin_lock_init(&state->pid_list_lock);
-		memset(state->pid_list,0,num*(sizeof(struct dib3000_pid)));
-		for (i=0; i < num; i++) {
-			state->pid_list[i].pid = 0;
-			state->pid_list[i].active = 0;
-		}
-		state->feedcount = 0;
-	} else
-		return -EINVAL;
-
-	return 0;
-}
-
-void dib3000_dealloc_pid_list(struct dib3000_state *state)
-{
-	if (state != NULL && state->pid_list != NULL)
-		kfree(state->pid_list);
-}
-
-/* fetch a pid from pid_list */
-int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids, int pid,
-		spinlock_t *pid_list_lock,int onoff)
-{
-	int i,ret = -1;
-	unsigned long flags;
-
-	spin_lock_irqsave(pid_list_lock,flags);
-	for (i=0; i < num_pids; i++)
-		if (onoff) {
-			if (!pid_list[i].active) {
-				pid_list[i].pid = pid;
-				pid_list[i].active = 1;
-				ret = i;
-				break;
-			}
-		} else {
-			if (pid_list[i].active && pid_list[i].pid == pid) {
-				pid_list[i].pid = 0;
-				pid_list[i].active = 0;
-				ret = i;
-				break;
-			}
-		}
-
-	deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off");
-
-	spin_unlock_irqrestore(pid_list_lock,flags);
-	return ret;
-}
-
 int dib3000_search_status(u16 irq,u16 lock)
 {
 	if (irq & 0x02) {
@@ -139,7 +79,4 @@
 
 EXPORT_SYMBOL(dib3000_read_reg);
 EXPORT_SYMBOL(dib3000_write_reg);
-EXPORT_SYMBOL(dib3000_init_pid_list);
-EXPORT_SYMBOL(dib3000_dealloc_pid_list);
-EXPORT_SYMBOL(dib3000_get_pid_index);
 EXPORT_SYMBOL(dib3000_search_status);
drivers/media/dvb/frontends/dib3000-common.h +11 -27
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/dib3000-common.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/dib3000-common.h
@@ -4,7 +4,7 @@
  *
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher ([email protected])
+ * Copyright (C) 2004-5 Patrick Boettcher ([email protected])
  *
  * based on GPL code from DibCom, which has
  *
@@ -29,19 +28,10 @@
 #include "dvb_frontend.h"
 #include "dib3000.h"
 
-/* info and err, taken from usb.h, if there is anything available like by default,
- * please change !
- */
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
-
-/* a PID for the pid_filter list, when in use */
-struct dib3000_pid
-{
-	u16 pid;
-	int active;
-};
+/* info and err, taken from usb.h, if there is anything available like by default. */
+#define err(format, arg...) printk(KERN_ERR "dib3000mX: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO "dib3000mX: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "dib3000mX: " format "\n" , ## arg)
 
 /* frontend state */
 struct dib3000_state {
@@ -52,25 +42,18 @@
 /* configuration settings */
 	struct dib3000_config config;
 
-	spinlock_t pid_list_lock;
-	struct dib3000_pid *pid_list;
-
-	int feedcount;
-
 	struct dvb_frontend frontend;
 	int timing_offset;
 	int timing_offset_comp_done;
+
+	fe_bandwidth_t last_tuned_bw;
+	u32 last_tuned_freq;
 };
 
 /* commonly used methods by the dib3000mb/mc/p frontend */
 extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
 extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
 
-extern int dib3000_init_pid_list(struct dib3000_state *state, int num);
-extern void dib3000_dealloc_pid_list(struct dib3000_state *state);
-extern int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids,
-	int pid, spinlock_t *pid_list_lock,int onoff);
-
 extern int dib3000_search_status(u16 irq,u16 lock);
 
 /* handy shortcuts */
@@ -81,7 +64,7 @@
 
 #define wr_foreach(a,v) { int i; \
 	if (sizeof(a) != sizeof(v)) \
-		err("sizeof: %zd %zd is different",sizeof(a),sizeof(v));\
+		err("sizeof: %d %d is different",sizeof(a),sizeof(v));\
 	for (i=0; i < sizeof(a)/sizeof(u16); i++) \
 		wr(a[i],v[i]); \
 	}
@@ -136,8 +119,8 @@
 #define DIB3000_DDS_INVERSION_OFF		(     0)
 #define DIB3000_DDS_INVERSION_ON		(     1)
 
-#define DIB3000_TUNER_WRITE_ENABLE(a)	(0xffff & (a << 7))
-#define DIB3000_TUNER_WRITE_DISABLE(a)	(0xffff & ((a << 7) | (1 << 7)))
+#define DIB3000_TUNER_WRITE_ENABLE(a)	(0xffff & (a << 8))
+#define DIB3000_TUNER_WRITE_DISABLE(a)	(0xffff & ((a << 8) | (1 << 7)))
 
 /* for auto search */
 extern u16 dib3000_seq[2][2][2];
drivers/media/dvb/frontends/dib3000.h +10 -11
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/dib3000.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/dib3000.h
@@ -2,7 +2,7 @@
  * public header file of the frontend drivers for mobile DVB-T demodulators
  * DiBcom 3000-MB and DiBcom 3000-MC/P (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004 Patrick Boettcher ([email protected])
+ * Copyright (C) 2004-5 Patrick Boettcher ([email protected])
  *
  * based on GPL code from DibCom, which has
  *
@@ -31,25 +31,24 @@
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
-	/* The i2c address of the PLL */
-	u8 pll_addr;
-
-	/* PLL maintenance */
-	int (*pll_init)(struct dvb_frontend *fe);
-	int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
+	/* PLL maintenance and the i2c address of the PLL */
+	u8 (*pll_addr)(struct dvb_frontend *fe);
+	int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
+	int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
 };
 
-struct dib3000_xfer_ops
+struct dib_fe_xfer_ops
 {
 	/* pid and transfer handling is done in the demodulator */
 	int (*pid_parse)(struct dvb_frontend *fe, int onoff);
 	int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
-	int (*pid_ctrl)(struct dvb_frontend *fe, int pid, int onoff);
+	int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
+	int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
 };
 
 extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-					     struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops);
+					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 
 extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
-					     struct i2c_adapter* i2c, struct dib3000_xfer_ops *xfer_ops);
+					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 #endif // DIB3000_H
drivers/media/dvb/frontends/dib3000mb.c +27 -25

137 lines not on this page · raw message

drivers/media/dvb/frontends/dib3000mc.c +300 -229

708 lines not on this page · raw message

drivers/media/dvb/frontends/dib3000mc_priv.h +23 -34

91 lines not on this page · raw message

#3 lore raw

PATCH 3/9 refactoring, support Yakumo/HAMA/Typhoon/HanfTek clones

In reply to Johannes Stezenbach

- [DVB] dvb-dibusb: refactoring of the dibusb driver, support for device clones from Yakumo/HAMA/Typhoon/HanfTek, update the documentation

Documentation/dvb/README.dibusb +44 -16
diff -uraNwB linux-2.6.11-rc2/Documentation/dvb/README.dibusb linux-2.6.11-rc2-dvb/Documentation/dvb/README.dibusb
@@ -26,7 +26,7 @@
 - HAMA DVB-T USB device
 	http://www.hama.de/portal/articleId*110620/action*2598
 
-- CTS Portable (Chinese Television System)
+- CTS Portable (Chinese Television System) (2)
 	http://www.2cts.tv/ctsportable/
 
 - Unknown USB DVB-T device with vendor ID Hyper-Paltek
@@ -46,16 +46,16 @@
 
 Others:
 -------
-- Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235)
+- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) 
 	http://82.161.246.249/products-tvbox.html
 
-- Compro Videomate DVB-U2000 - DVB-T USB
+- Compro Videomate DVB-U2000 - DVB-T USB (2)
 	http://www.comprousa.com/products/vmu2000.htm
 
 - Grandtec USB DVB-T
 	http://www.grand.com.tw/
 
-- Avermedia AverTV DVBT USB
+- Avermedia AverTV DVBT USB (2)
 	http://www.avermedia.com/
 
 - DiBcom USB DVB-T reference device (non-public)
@@ -63,16 +63,33 @@
 
 Supported devices USB2.0
 ========================
-- Twinhan MagicBox II
+- Twinhan MagicBox II (2)
 	http://www.twinhan.com/product_terrestrial_7.asp
 
-- Yakumo DVB-T mobile
+- Hanftek UMT-010 (1)
+	http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
+
+- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1)
 	http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T
 
+- Artec T1 USB TVBOX (FX2) (2)
+
 - DiBcom USB2.0 DVB-T reference device (non-public)
 
+1) It is working almost.
+2) No test reports received yet. 
+
 
 0. NEWS:
+  2004-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
+             - first almost working version for HanfTek UMT-010
+             - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek
+  2004-01-10 - refactoring completed, now everything is very delightful
+             - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
+               Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. 
+  2004-12-29 - after several days of struggling around bug of no returning URBs fixed.
+  2004-12-26 - refactored the dibusb-driver, splitted into separate files
+             - i2c-probing enabled
   2004-12-06 - possibility for demod i2c-address probing
              - new usb IDs (Compro,Artec)
   2004-11-23 - merged changes from DiB3000MC_ver2.1
@@ -115,13 +132,15 @@
 
 1. How to use?
 NOTE: This driver was developed using Linux 2.6.6.,
-it is working with 2.6.7, 2.6.8.1, 2.6.9 .
+it is working with 2.6.7 and above.
 
 Linux 2.4.x support is not planned, but patches are very welcome.
 
 NOTE: I'm using Debian testing, so the following explaination (especially
 the hotplug-path) needn't match your system, but probably it will :).
 
+The driver is included in the kernel since Linux 2.6.10.
+
 1.1. Firmware
 
 The USB driver needs to download a firmware to start working.
@@ -155,9 +174,13 @@
 first have a look, which debug level are available:
 
 modinfo dib3000mb
+modinfo dib3000-common
+modinfo dib3000mc
 modinfo dvb-dibusb
 
+modprobe dib3000-common debug=<level>
 modprobe dib3000mb debug=<level>
+modprobe dib3000mc debug=<level>
 modprobe dvb-dibusb debug=<level>
 
 should do the trick.
@@ -168,13 +191,11 @@
 
 At this point you should be able to start a dvb-capable application. For myself
 I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device
-as a slave device in vdr, was not working for me. Some work has to be done
-(patches and comments are very welcome).
+in vdr (at least the USB2.0 one) is working. 
 
 2. Known problems and bugs
 
-TODO:
-- signal-quality and strength calculations
+- none this time
 
 2.1. Adding support for devices 
 
@@ -202,9 +223,10 @@
 maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
 This is not enough for receiving the complete transport stream of a
 DVB-T channel (which can be about 16 MBit/s). Normally this is not a
-problem, if you only want to watch TV, but watching a channel while
-recording another channel on the same frequency simply does not work.
-This applies to all USB1.1 DVB-T devices.
+problem, if you only want to watch TV (this does not apply for HDTV),
+but watching a channel while recording another channel on the same 
+frequency simply does not work. This applies to all USB1.1 DVB-T 
+devices, not only dibusb)
 
 A special problem of the dibusb for the USB1.1 is, that the USB control
 IC has a problem with write accesses while having MPEG2-streaming
@@ -218,14 +240,20 @@
 these features is maybe a solution. Additionally this behaviour of VDR exceeds
 the USB1.1 bandwidth.
 
+Update:
+For the USB1.1 and VDR some work has been done (patches and comments are still 
+very welcome). Maybe the problem is solved in the meantime because I now use
+the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the
+linux-dvb software filter is able to get the best of the garbled TS.
+
 2.3. Comments
 
 Patches, comments and suggestions are very very welcome
 
 3. Acknowledgements
 	Amaury Demol ([email protected]) and Francois Kanounnikoff from DiBcom for
-	providing specs, code and help, on which the dvb-dibusb and dib3000mb are
-	based.
+    providing specs, code and help, on which the dvb-dibusb, dib3000mb and 
+    dib3000mc are based.
 
    David Matthews for identifying a new device type (Artec T1 with AN2235)
     and for extending dibusb with remote control event handling. Thank you.
drivers/media/dvb/dibusb/dvb-dibusb-core.c +471 -0

471 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-dvb.c +205 -0

205 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c +598 -0

598 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-firmware.c +85 -0

85 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb.h +228 -258

577 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-pid.c +80 -0

80 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-remote.c +197 -0

197 lines not on this page · raw message

drivers/media/dvb/dibusb/dvb-dibusb-usb.c +259 -0

259 lines not on this page · raw message

drivers/media/dvb/dibusb/Kconfig +9 -5
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/Kconfig linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Kconfig
@@ -1,12 +1,13 @@
 config DVB_DIBUSB
-	tristate "DiBcom USB DVB-T devices (see help for device list)"
+	tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
 	depends on DVB_CORE && USB
 	select FW_LOADER
 	select DVB_DIB3000MB
 	select DVB_DIB3000MC
+	select DVB_MT352
 	help
 	  Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
-	  DiBcom (<http://www.dibcom.fr>).
+	  DiBcom (http://www.dibcom.fr) and C&E.
 
 	  Devices supported by this driver:
 
@@ -14,12 +15,14 @@
 		TwinhanDTV Magic Box (VP7041e)
 	    KWorld V-Stream XPERT DTV - DVB-T USB
 	    Hama DVB-T USB-Box
-	    DiBcom reference device (non-public)
+	    DiBcom reference devices (non-public)
 	    Ultima Electronic/Artec T1 USB TVBOX
 	    Compro Videomate DVB-U2000 - DVB-T USB
 	    Grandtec DVB-T USB
 	    Avermedia AverTV DVBT USB
-	    Yakumo DVB-T mobile USB2.0
+	    Artec T1 USB1.1 and USB2.0 boxes
+	    Yakumo/Typhoon DVB-T USB2.0
+	    Hanftek UMT-010 USB2.0
 
 	  The VP7041 seems to be identical to "CTS Portable" (Chinese
 	  Television System).
@@ -27,7 +30,7 @@
 	  These devices can be understood as budget ones, they "only" deliver
 	  (a part of) the MPEG2 transport stream.
 
-	  A firmware is needed to get the device working. See <file:Documentation/dvb/README.dibusb>
+	  A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
 	  details.
 
 	  Say Y if you own such a device and want to use it. You should build it as
@@ -46,6 +49,7 @@
 	    0x0574:0x2235 (Artec T1 USB1.1, cold)
 	    0x04b4:0x8613 (Artec T1 USB2.0, cold)
 	    0x0574:0x1002 (Artec T1 USB2.0, warm)
+	    0x0574:0x2131 (aged DiBcom USB1.1 test device)
 
 	  Say Y if your device has one of the mentioned IDs.
 
drivers/media/dvb/dibusb/Makefile +8 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/Makefile linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Makefile
@@ -1,3 +1,11 @@
+dvb-dibusb-objs = dvb-dibusb-core.o \
+	dvb-dibusb-dvb.o \
+	dvb-dibusb-fe-i2c.o \
+	dvb-dibusb-firmware.o \
+	dvb-dibusb-remote.o \
+	dvb-dibusb-usb.o \
+	dvb-dibusb-pid.o
+
 obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
#2 lore raw

PATCH 2/9 support pinnacle pctv-sat, clean-ups

In reply to Johannes Stezenbach

- [DVB] dvb-bt8xx: add support for pinnacle pctv-sat, patch by Peter Hettkamp and Adam Szalkowski
- [DVB] dvb-bt8xx: minor code cleanups, patch by Arne Ahrend
- [DVB] dvb-bt8xx: make sure to compile all necessary frontend modules, remove misleading comment

drivers/media/dvb/bt8xx/dvb-bt8xx.c +80 -2
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-2.6.11-rc2-dvb/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -181,6 +181,70 @@
 	.pll_set = thomson_dtt7579_pll_set,
 };
 
+static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+   u32 freq = params->frequency;
+   
+   int i, a, n, pump; 
+   u32 band, pll;
+   
+   
+   u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
+               1576000,1718000,1856000,2036000,2150000};
+   u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
+               0x00102000,0x00104000,0x00108000,0x00110000,
+               0x00120000,0x00140000};
+   
+#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
+        printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
+        
+        /* This is really the bit driving the tuner chip cx24108 */
+        
+        if(freq<950000) freq=950000; /* kHz */
+        if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
+        
+        /* decide which VCO to use for the input frequency */
+        for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
+        printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
+        band=bandsel[i];
+        /* the gain values must be set by SetSymbolrate */
+        /* compute the pll divider needed, from Conexant data sheet,
+           resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
+           depending on the divider bit. It is set to /4 on the 2 lowest 
+           bands  */
+        n=((i<=2?2:1)*freq*10L)/(XTAL/100);
+        a=n%32; n/=32; if(a==0) n--;
+        pump=(freq<(osci[i-1]+osci[i])/2);
+        pll=0xf8000000|
+            ((pump?1:2)<<(14+11))|
+            ((n&0x1ff)<<(5+11))|
+            ((a&0x1f)<<11);
+        /* everything is shifted left 11 bits to left-align the bits in the
+           32bit word. Output to the tuner goes MSB-aligned, after all */
+        printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
+        cx24110_pll_write(fe,band);
+        /* set vga and vca to their widest-band settings, as a precaution.
+           SetSymbolrate might not be called to set this up */
+        cx24110_pll_write(fe,0x500c0000);
+        cx24110_pll_write(fe,0x83f1f800);
+        cx24110_pll_write(fe,pll);
+/*        writereg(client,0x56,0x7f);*/
+
+	return 0;
+}
+
+static int pinnsat_pll_init(struct dvb_frontend* fe)
+{
+   return 0;
+}
+
+
+static struct cx24110_config pctvsat_config = {
+
+	.demod_address = 0x55,
+	.pll_init = pinnsat_pll_init,
+	.pll_set = cx24108_pll_set,
+};
 
 
 static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -220,7 +284,7 @@
 	return request_firmware(fw, name, &bt->bt->dev->dev);
 }
 
-struct sp887x_config microtune_mt7202dtf_config = {
+static struct sp887x_config microtune_mt7202dtf_config = {
 
 	.demod_address = 0x70,
 	.pll_set = microtune_mt7202dtf_pll_set,
@@ -387,6 +451,13 @@
 			break;
 		}
 		break;
+	
+	case BTTV_PINNACLESAT:
+		card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
+		if (card->fe != NULL) {
+			break;
+		}
+		break;
 	}
 
 	if (card->fe == NULL) {
@@ -510,7 +581,14 @@
 
 	switch(sub->core->type)
 	{
-/*	case BTTV_PINNACLESAT: UNDEFINED HARDWARE */
+	case BTTV_PINNACLESAT:
+		card->gpio_mode = 0x0400c060;
+		/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
+		              BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
+		card->op_sync_orin = 0;
+		card->irq_err_ignore = 0;
+		break;
+		
 #ifdef BTTV_DVICO_DVBT_LITE
 	case BTTV_DVICO_DVBT_LITE:
 #endif
drivers/media/dvb/bt8xx/dvb-bt8xx.h +6 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/bt8xx/dvb-bt8xx.h linux-2.6.11-rc2-dvb/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -22,6 +22,9 @@
  *
  */
 
+#ifndef DVB_BT8XX_H
+#define DVB_BT8XX_H
+
 #include <linux/i2c.h>
 #include "dvbdev.h"
 #include "dvb_net.h"
@@ -30,6 +33,7 @@
 #include "sp887x.h"
 #include "dst.h"
 #include "nxt6000.h"
+#include "cx24110.h"
 
 struct dvb_bt8xx_card {
 	struct semaphore lock;
@@ -50,3 +54,5 @@
 				
 	struct dvb_frontend* fe;
 };
+
+#endif /* DVB_BT8XX_H */
drivers/media/dvb/bt8xx/Kconfig +2 -3
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/bt8xx/Kconfig linux-2.6.11-rc2-dvb/drivers/media/dvb/bt8xx/Kconfig
@@ -3,6 +3,8 @@
 	depends on DVB_CORE && PCI && VIDEO_BT848
 	select DVB_MT352
 	select DVB_SP887X
+	select DVB_NXT6000
+	select DVB_CX24110
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  the Nebula cards, the Pinnacle PCTV cards and Twinhan DST cards.
@@ -11,8 +13,5 @@
 	  only compressed MPEG data over the PCI bus, so you need
 	  an external software decoder to watch TV on your computer.
 
-	  If you have a Twinhan card, don't forget to select
-	  "Twinhan DST based DVB-S/-T frontend".
-
 	  Say Y if you own such a device and want to use it.
 
#7 lore raw

PATCH 7/9 nxt2002: add ATSC support, misc fixes

In reply to Johannes Stezenbach

- [DVB] mt352: exported a mt352_read_reg-function, implemented a single byte write_register function (needed for dibusb)
- [DVB] nxt2002: patch by Taylor Jacob to add support for ATSC/VSB frontends and the B2C2/BBTI Air2PC-ATSC card
- [DVB] stv0297: fix tuning problems and compile time warnings, patch by Markus Breitenberger
- [DVB] fix spelling errors in various frontend drivers

drivers/media/dvb/frontends/mt352.c +18 -6
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/mt352.c linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/mt352.c
@@ -58,16 +58,26 @@
 		if (debug) printk(KERN_DEBUG "mt352: " args); \
 } while (0)
 
-int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
 {
 	struct mt352_state* state = (struct mt352_state*) fe->demodulator_priv;
+	u8 buf[2] = { reg, val };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
-			       .buf = ibuf, .len = ilen };
+			       .buf = buf, .len = 2 };
 	int err = i2c_transfer(state->i2c, &msg, 1);
 	if (err != 1) {
-		dprintk("mt352_write() failed (err = %d)!\n", err);
+		dprintk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
 		return err;
 }
+	return 0; 
+}
+
+int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+{
+	int err,i;
+	for (i=0; i < ilen-1; i++)
+		if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1]))) 
+			return err;
 
 	return 0;
 }
@@ -92,9 +102,10 @@
 	return b1[0];
 }
 
-
-
-
+u8 mt352_read(struct dvb_frontend *fe, u8 reg)
+{
+	return mt352_read_register(fe->demodulator_priv,reg);
+}
 
 
 
@@ -556,3 +567,4 @@
 
 EXPORT_SYMBOL(mt352_attach);
 EXPORT_SYMBOL(mt352_write);
+EXPORT_SYMBOL(mt352_read);
drivers/media/dvb/frontends/mt352.h +1 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/mt352.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/mt352.h
@@ -54,5 +54,6 @@
 					 struct i2c_adapter* i2c);
 
 extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
+extern u8 mt352_read(struct dvb_frontend *fe, u8 reg);
 
 #endif // MT352_H
drivers/media/dvb/frontends/nxt2002.c +670 -0

670 lines not on this page · raw message

drivers/media/dvb/frontends/nxt2002.h +23 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/nxt2002.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/nxt2002.h
@@ -0,0 +1,23 @@
+/*
+   Driver for the Nxt2002 demodulator
+*/
+
+#ifndef NXT2002_H
+#define NXT2002_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct nxt2002_config
+{
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* request firmware for device */
+	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
+					  struct i2c_adapter* i2c);
+
+#endif // NXT2002_H
drivers/media/dvb/frontends/stv0297.c +63 -31

204 lines not on this page · raw message

drivers/media/dvb/frontends/stv0297.h +3 -0
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/stv0297.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/stv0297.h
@@ -29,6 +29,9 @@
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
+	/* does the "inversion" need inverted? */
+	u8 invert:1;
+
 	/* PLL maintenance */
 	int (*pll_init)(struct dvb_frontend* fe);
 	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
drivers/media/dvb/frontends/tda10021.c +1 -1
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/tda10021.c linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/tda10021.c
@@ -4,7 +4,7 @@
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <[email protected]>
     Copyright (C) 2004 Markus Schulz <[email protected]>
-                   Suppport for TDA10021
+                   Support for TDA10021
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
drivers/media/dvb/frontends/tda10021.h +1 -1
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/tda10021.h linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/tda10021.h
@@ -4,7 +4,7 @@
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <[email protected]>
     Copyright (C) 2004 Markus Schulz <[email protected]>
-                   Suppport for TDA10021
+                   Support for TDA10021
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
drivers/media/dvb/frontends/tda80xx.c +1 -1
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/frontends/tda80xx.c linux-2.6.11-rc2-dvb/drivers/media/dvb/frontends/tda80xx.c
@@ -27,10 +27,10 @@
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/irq.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"