vserver 1.9.3
[linux-2.6.git] / drivers / media / video / bttv-risc.c
index c512416..3731d2c 100644 (file)
@@ -55,6 +55,8 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
        instructions += 2;
        if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
                return rc;
+       dprintk("bttv%d: risc packed: bpl %d lines %d instr %d size %d ptr %p\n",
+               btv->c.nr, bpl, lines, instructions, risc->size, risc->cpu);
 
        /* sync instruction */
        rp = risc->cpu;
@@ -99,8 +101,10 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
                        offset += todo;
                }
                offset += padding;
+               dprintk("bttv%d: risc packed:   line %d ptr %p\n",
+                       btv->c.nr, line, rp);
        }
-       dprintk("bttv%d: risc planar: %d sglist elems\n", btv->c.nr, (int)(sg-sglist));
+       dprintk("bttv%d: risc packed: %d sglist elems\n", btv->c.nr, (int)(sg-sglist));
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
@@ -121,6 +125,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
        struct scatterlist *ysg;
        struct scatterlist *usg;
        struct scatterlist *vsg;
+       int topfield = (0 == yoffset);
        int rc;
 
        /* estimate risc mem: worst case is one write per page border +
@@ -145,11 +150,26 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
                    (line >= (ylines - VCR_HACK_LINES)))
                        continue;
                switch (vshift) {
-               case 0:  chroma = 1;           break;
-               case 1:  chroma = !(line & 1); break;
-               case 2:  chroma = !(line & 3); break;
-               default: chroma = 0;
+               case 0:
+                       chroma = 1;
+                       break;
+               case 1:
+                       if (topfield)
+                               chroma = (line & 1) == 0;
+                       else
+                               chroma = (line & 1) == 1;
+                       break;
+               case 2:
+                       if (topfield)
+                               chroma = (line & 3) == 0;
+                       else
+                               chroma = (line & 3) == 2;
+                       break;
+               default:
+                       chroma = 0;
+                       break;
                }
+
                for (todo = ybpl; todo > 0; todo -= ylen) {
                        /* go to next sg entry if needed */
                        while (yoffset && yoffset >= sg_dma_len(ysg)) {
@@ -379,7 +399,7 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags)
        btv->cap_ctl = 0;
        if (NULL != btv->curr.top)      btv->cap_ctl |= 0x02;
        if (NULL != btv->curr.bottom)   btv->cap_ctl |= 0x01;
-       if (NULL != btv->curr.vbi)      btv->cap_ctl |= 0x0c;
+       if (NULL != btv->cvbi)          btv->cap_ctl |= 0x0c;
 
        capctl  = 0;
        capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;  /* capture  */
@@ -389,9 +409,9 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags)
        d2printk(KERN_DEBUG
                 "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
                 btv->c.nr,capctl,irqflags,
-                btv->curr.vbi     ? (unsigned long long)btv->curr.vbi->top.dma        : 0,
+                btv->cvbi         ? (unsigned long long)btv->cvbi->top.dma            : 0,
                 btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
-                btv->curr.vbi     ? (unsigned long long)btv->curr.vbi->bottom.dma     : 0,
+                btv->cvbi         ? (unsigned long long)btv->cvbi->bottom.dma         : 0,
                 btv->curr.bottom  ? (unsigned long long)btv->curr.bottom->bottom.dma  : 0);
        
        cmd = BT848_RISC_JUMP;
@@ -399,6 +419,8 @@ bttv_set_dma(struct bttv *btv, int override, int irqflags)
                cmd |= BT848_RISC_IRQ;
                cmd |= (irqflags  & 0x0f) << 16;
                cmd |= (~irqflags & 0x0f) << 20;
+       }
+       if (irqflags || btv->cvbi) {
                mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
        } else {
                del_timer(&btv->timeout);
@@ -501,20 +523,26 @@ bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
 }
 
 int
-bttv_buffer_set_activate(struct bttv *btv,
-                        struct bttv_buffer_set *set)
+bttv_buffer_activate_vbi(struct bttv *btv,
+                        struct bttv_buffer *vbi)
 {
        /* vbi capture */
-       if (set->vbi) {
-               set->vbi->vb.state = STATE_ACTIVE;
-               list_del(&set->vbi->vb.queue);
-               bttv_risc_hook(btv, RISC_SLOT_O_VBI, &set->vbi->top,    0);
-               bttv_risc_hook(btv, RISC_SLOT_E_VBI, &set->vbi->bottom, 0);
+       if (vbi) {
+               vbi->vb.state = STATE_ACTIVE;
+               list_del(&vbi->vb.queue);
+               bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top,    0);
+               bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
        } else {
                bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
                bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
        }
+       return 0;
+}
 
+int
+bttv_buffer_activate_video(struct bttv *btv,
+                          struct bttv_buffer_set *set)
+{
        /* video capture */
        if (NULL != set->top  &&  NULL != set->bottom) {
                if (set->top == set->bottom) {