The patch number 8889 was added via Oliver Endriss <[EMAIL PROTECTED]>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [EMAIL PROTECTED]

------

From: Oliver Endriss  <[EMAIL PROTECTED]>
dvb-ttpci: Support full-ts hardware modification


Add support for the 'full-ts' hardware modification.

On full-featured cards the data throughput is limited by the hardware
design. The full-ts mod removes this bottleneck, i.e. the card is able
to deliver the complete transport stream of a transponder.

For details see http://www.escape-edv.de/endriss/dvb-full-ts-mod

Priority: normal

Signed-off-by: Oliver Endriss <[EMAIL PROTECTED]>


---

 linux/drivers/media/dvb/ttpci/av7110.c    |  115 +++++++++++++++++-----
 linux/drivers/media/dvb/ttpci/av7110.h    |    1 
 linux/drivers/media/dvb/ttpci/av7110_av.c |    3 
 3 files changed, 93 insertions(+), 26 deletions(-)

diff -r 4a2a172be07f -r e373455c395e linux/drivers/media/dvb/ttpci/av7110.c
--- a/linux/drivers/media/dvb/ttpci/av7110.c    Wed Sep 03 23:16:09 2008 +0200
+++ b/linux/drivers/media/dvb/ttpci/av7110.c    Thu Sep 04 00:15:27 2008 +0200
@@ -88,6 +88,7 @@ static int wss_cfg_4_3 = 0x4008;
 static int wss_cfg_4_3 = 0x4008;
 static int wss_cfg_16_9 = 0x0007;
 static int tv_standard;
+static int full_ts;
 
 module_param_named(debug, av7110_debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
@@ -106,6 +107,8 @@ MODULE_PARM_DESC(volume, "initial volume
 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)");
+module_param(full_ts, int, 0444);
+MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 
disable (default), 1 enable");
 module_param(wss_cfg_4_3, int, 0444);
 MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: 
burst mode, 13..0: wss data");
 module_param(wss_cfg_16_9, int, 0444);
@@ -116,6 +119,8 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static void restart_feeds(struct av7110 *av7110);
+static int budget_start_feed(struct dvb_demux_feed *feed);
+static int budget_stop_feed(struct dvb_demux_feed *feed);
 
 static int av7110_num;
 
@@ -806,6 +811,9 @@ static int StartHWFilter(struct dvb_demu
 
        dprintk(4, "%p\n", av7110);
 
+       if (av7110->full_ts)
+               return 0;
+
        if (dvbdmxfilter->type == DMX_TYPE_SEC) {
                if (hw_sections) {
                        buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
@@ -854,6 +862,9 @@ static int StopHWFilter(struct dvb_demux
 
        dprintk(4, "%p\n", av7110);
 
+       if (av7110->full_ts)
+               return 0;
+
        handle = dvbdmxfilter->hw_handle;
        if (handle >= 32) {
                printk("%s tried to stop invalid filter %04x, filter type = 
%x\n",
@@ -913,7 +924,7 @@ static int dvb_feed_start_pid(struct dvb
                                return ret;
                }
 
-       if ((dvbdmxfeed->ts_type & TS_PACKET)) {
+       if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) {
                if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
                        ret = av7110_av_start_record(av7110, RP_AUDIO, 
dvbdmxfeed);
                if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
@@ -974,7 +985,7 @@ static int av7110_start_feed(struct dvb_
        if (!demux->dmx.frontend)
                return -EINVAL;
 
-       if (feed->pid > 0x1fff)
+       if (!av7110->full_ts && feed->pid > 0x1fff)
                return -EINVAL;
 
        if (feed->type == DMX_TYPE_TS) {
@@ -1003,7 +1014,12 @@ static int av7110_start_feed(struct dvb_
                }
        }
 
-       else if (feed->type == DMX_TYPE_SEC) {
+       if (av7110->full_ts) {
+               budget_start_feed(feed);
+               return ret;
+       }
+
+       if (feed->type == DMX_TYPE_SEC) {
                int i;
 
                for (i = 0; i < demux->filternum; i++) {
@@ -1050,7 +1066,12 @@ static int av7110_stop_feed(struct dvb_d
                                ret = StopHWFilter(feed->filter);
        }
 
-       if (!ret && feed->type == DMX_TYPE_SEC) {
+       if (av7110->full_ts) {
+               budget_stop_feed(feed);
+               return ret;
+       }
+
+       if (feed->type == DMX_TYPE_SEC) {
                for (i = 0; i<demux->filternum; i++) {
                        if (demux->filter[i].state == DMX_STATE_GO &&
                            demux->filter[i].filter.parent == &feed->feed.sec) {
@@ -1074,6 +1095,7 @@ static void restart_feeds(struct av7110 
        struct dvb_demux *dvbdmx = &av7110->demux;
        struct dvb_demux_feed *feed;
        int mode;
+       int feeding;
        int i, j;
 
        dprintk(4, "%p\n", av7110);
@@ -1081,6 +1103,8 @@ static void restart_feeds(struct av7110 
        mode = av7110->playing;
        av7110->playing = 0;
        av7110->rec_mode = 0;
+
+       feeding = av7110->feeding1; /* full_ts mod */
 
        for (i = 0; i < dvbdmx->feednum; i++) {
                feed = &dvbdmx->feed[i];
@@ -1099,6 +1123,8 @@ static void restart_feeds(struct av7110 
                }
        }
 
+       av7110->feeding1 = feeding; /* full_ts mod */
+
        if (mode)
                av7110_av_start_play(av7110, mode);
 }
@@ -1197,8 +1223,9 @@ static int start_ts_capture(struct av711
 
        if (budget->feeding1)
                return ++budget->feeding1;
-       memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
+       memset(budget->grabbing, 0x00, TS_BUFLEN);
        budget->ttbp = 0;
+       SAA7146_ISR_CLEAR(budget->dev, MASK_10);  /* VPE */
        SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
        saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
        return ++budget->feeding1;
@@ -1239,12 +1266,8 @@ static void vpeirq(unsigned long 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();
-       }
+       struct dvb_demux *demux = budget->full_ts ? &budget->demux : 
&budget->demux1;
+
        /* nearest lower position divisible by 188 */
        newdma -= newdma % 188;
 
@@ -1268,11 +1291,11 @@ static void vpeirq(unsigned long data)
 
        if (newdma > olddma)
                /* no wraparound, dump olddma..newdma */
-               dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma 
- olddma) / 188);
+               dvb_dmx_swfilter_packets(demux, 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);
+               dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - 
olddma) / 188);
+               dvb_dmx_swfilter_packets(demux, mem, newdma / 188);
        }
 }
 
@@ -1294,8 +1317,8 @@ static int av7110_register(struct av7110
        for (i = 0; i < 32; i++)
                av7110->handle2filter[i] = NULL;
 
-       dvbdemux->filternum = 32;
-       dvbdemux->feednum = 32;
+       dvbdemux->filternum = (av7110->full_ts) ? 256 : 32;
+       dvbdemux->feednum = (av7110->full_ts) ? 256 : 32;
        dvbdemux->start_feed = av7110_start_feed;
        dvbdemux->stop_feed = av7110_stop_feed;
        dvbdemux->write_to_decoder = av7110_write_to_decoder;
@@ -1305,7 +1328,7 @@ static int av7110_register(struct av7110
        dvb_dmx_init(&av7110->demux);
        av7110->demux.dmx.get_stc = dvb_get_stc;
 
-       av7110->dmxdev.filternum = 32;
+       av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32;
        av7110->dmxdev.demux = &dvbdemux->dmx;
        av7110->dmxdev.capabilities = 0;
 
@@ -1422,7 +1445,6 @@ int i2c_writereg(struct av7110 *av7110, 
        return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
 }
 
-#if 0 /* keep */
 u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
 {
        u8 mm1[] = {0x00};
@@ -1439,7 +1461,6 @@ u8 i2c_readreg(struct av7110 *av7110, u8
 
        return mm2[0];
 }
-#endif
 
 /****************************************************************************
  * INITIALIZATION
@@ -2484,7 +2505,47 @@ static int __devinit av7110_attach(struc
                               av7110->dvb_adapter.proposed_mac);
        ret = -ENOMEM;
 
-       if (budgetpatch) {
+       /* full-ts mod? */
+       if (full_ts)
+               av7110->full_ts = true;
+
+       /* check for full-ts flag in eeprom */
+       if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 
1) == 0x45) {
+               u8 flags = i2c_readreg(av7110, 0xaa, 2);
+               if (flags != 0xff && (flags & 0x01))
+                       av7110->full_ts = true;
+       }
+
+       if (av7110->full_ts) {
+               printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 
port B\n");
+               spin_lock_init(&av7110->feedlock1);
+               av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
+                                                                &av7110->pt);
+               if (!av7110->grabbing)
+                       goto err_i2c_del_3;
+
+               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+               saa7146_write(dev, MC2, (MASK_10 | MASK_26));
+
+               saa7146_write(dev, DD1_INIT, 0x00000600);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | 
MASK_26));
+
+               saa7146_write(dev, BRS_CTRL, 0x60000000);
+               saa7146_write(dev, MC2, MASK_08 | MASK_24);
+
+               /* dma3 */
+               saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, 
PCI_BT_V1) & ~0x001f0000));
+               saa7146_write(dev, BASE_ODD3, 0);
+               saa7146_write(dev, BASE_EVEN3, 0);
+               saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
+               saa7146_write(dev, PITCH3, TS_WIDTH);
+               saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
+               saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | 
TS_WIDTH);
+               saa7146_write(dev, MC2, MASK_04 | MASK_20);
+
+               tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) 
av7110);
+
+       } else if (budgetpatch) {
                spin_lock_init(&av7110->feedlock1);
                av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
                                                                 &av7110->pt);
@@ -2710,11 +2771,13 @@ static int __devexit av7110_detach(struc
 #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
        av7110_ir_exit(av7110);
 #endif
-       if (budgetpatch) {
-               /* Disable RPS1 */
-               saa7146_write(saa, MC1, MASK_29);
-               /* VSYNC LOW (inactive) */
-               saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+       if (budgetpatch || av7110->full_ts) {
+               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);
@@ -2794,7 +2857,7 @@ static void av7110_irq(struct saa7146_de
                tasklet_schedule(&av7110->gpio_tasklet);
        }
 
-       if ((*isr & MASK_10) && budgetpatch)
+       if (*isr & MASK_10)
                tasklet_schedule(&av7110->vpe_tasklet);
 }
 
diff -r 4a2a172be07f -r e373455c395e linux/drivers/media/dvb/ttpci/av7110.h
--- a/linux/drivers/media/dvb/ttpci/av7110.h    Wed Sep 03 23:16:09 2008 +0200
+++ b/linux/drivers/media/dvb/ttpci/av7110.h    Thu Sep 04 00:15:27 2008 +0200
@@ -194,6 +194,7 @@ struct av7110 {
        unsigned char           *grabbing;
        struct saa7146_pgtable  pt;
        struct tasklet_struct   vpe_tasklet;
+       bool                    full_ts;
 
        int                     fe_synced;
        struct mutex            pid_mutex;
diff -r 4a2a172be07f -r e373455c395e linux/drivers/media/dvb/ttpci/av7110_av.c
--- a/linux/drivers/media/dvb/ttpci/av7110_av.c Wed Sep 03 23:16:09 2008 +0200
+++ b/linux/drivers/media/dvb/ttpci/av7110_av.c Thu Sep 04 00:15:27 2008 +0200
@@ -788,6 +788,9 @@ int av7110_write_to_decoder(struct dvb_d
 
        dprintk(2, "av7110:%p, \n", av7110);
 
+       if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
+               return 0;
+
        switch (feed->pes_type) {
        case 0:
                if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/e373455c395ec6f8cdb0f1907229ad0b40c4c495

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to