2 bttv-risc.c -- interfaces to other kernel modules
4 bttv risc code handling
8 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/pci.h>
29 #include <linux/vmalloc.h>
30 #include <linux/interrupt.h>
32 #include <asm/pgtable.h>
36 #define VCR_HACK_LINES 4
38 /* ---------------------------------------------------------- */
39 /* risc code generators */
42 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
43 struct scatterlist *sglist,
44 unsigned int offset, unsigned int bpl,
45 unsigned int padding, unsigned int lines)
47 u32 instructions,line,todo;
48 struct scatterlist *sg;
52 /* estimate risc mem: worst case is one write per page border +
53 one write per scan line + sync + jump (all 2 dwords) */
54 instructions = (bpl * lines) / PAGE_SIZE + lines;
56 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
58 dprintk("bttv%d: risc packed: bpl %d lines %d instr %d size %d ptr %p\n",
59 btv->c.nr, bpl, lines, instructions, risc->size, risc->cpu);
61 /* sync instruction */
63 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
64 *(rp++) = cpu_to_le32(0);
68 for (line = 0; line < lines; line++) {
69 if ((btv->opt_vcr_hack) &&
70 (line >= (lines - VCR_HACK_LINES)))
72 while (offset && offset >= sg_dma_len(sg)) {
73 offset -= sg_dma_len(sg);
76 if (bpl <= sg_dma_len(sg)-offset) {
77 /* fits into current chunk */
78 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
80 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
83 /* scanline needs to be splitted */
85 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
86 (sg_dma_len(sg)-offset));
87 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
88 todo -= (sg_dma_len(sg)-offset);
91 while (todo > sg_dma_len(sg)) {
92 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
94 *(rp++)=cpu_to_le32(sg_dma_address(sg));
95 todo -= sg_dma_len(sg);
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
100 *(rp++)=cpu_to_le32(sg_dma_address(sg));
104 dprintk("bttv%d: risc packed: line %d ptr %p\n",
105 btv->c.nr, line, rp);
107 dprintk("bttv%d: risc packed: %d sglist elems\n", btv->c.nr, (int)(sg-sglist));
109 /* save pointer to jmp instruction address */
115 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
116 struct scatterlist *sglist,
117 unsigned int yoffset, unsigned int ybpl,
118 unsigned int ypadding, unsigned int ylines,
119 unsigned int uoffset, unsigned int voffset,
120 unsigned int hshift, unsigned int vshift,
121 unsigned int cpadding)
123 unsigned int instructions,line,todo,ylen,chroma;
125 struct scatterlist *ysg;
126 struct scatterlist *usg;
127 struct scatterlist *vsg;
128 int topfield = (0 == yoffset);
131 /* estimate risc mem: worst case is one write per page border +
132 one write per scan line (5 dwords)
133 plus sync + jump (2 dwords) */
134 instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
136 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
139 /* sync instruction */
141 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
142 *(rp++) = cpu_to_le32(0);
148 for (line = 0; line < ylines; line++) {
149 if ((btv->opt_vcr_hack) &&
150 (line >= (ylines - VCR_HACK_LINES)))
158 chroma = (line & 1) == 0;
160 chroma = (line & 1) == 1;
164 chroma = (line & 3) == 0;
166 chroma = (line & 3) == 2;
173 for (todo = ybpl; todo > 0; todo -= ylen) {
174 /* go to next sg entry if needed */
175 while (yoffset && yoffset >= sg_dma_len(ysg)) {
176 yoffset -= sg_dma_len(ysg);
179 while (uoffset && uoffset >= sg_dma_len(usg)) {
180 uoffset -= sg_dma_len(usg);
183 while (voffset && voffset >= sg_dma_len(vsg)) {
184 voffset -= sg_dma_len(vsg);
188 /* calculate max number of bytes we can write */
190 if (yoffset + ylen > sg_dma_len(ysg))
191 ylen = sg_dma_len(ysg) - yoffset;
193 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
194 ylen = (sg_dma_len(usg) - uoffset) << hshift;
195 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
196 ylen = (sg_dma_len(vsg) - voffset) << hshift;
197 ri = BT848_RISC_WRITE123;
199 ri = BT848_RISC_WRITE1S23;
202 ri |= BT848_RISC_SOL;
204 ri |= BT848_RISC_EOL;
206 /* write risc instruction */
207 *(rp++)=cpu_to_le32(ri | ylen);
208 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
210 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
213 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
214 uoffset += ylen >> hshift;
215 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
216 voffset += ylen >> hshift;
226 /* save pointer to jmp instruction address */
232 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
233 const struct bttv_format *fmt, struct bttv_overlay *ov,
234 int skip_even, int skip_odd)
236 int instructions,rc,line,maxy,start,end,skip,nskips;
237 struct btcx_skiplist *skips;
241 /* skip list for window clipping */
242 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
245 /* estimate risc mem: worst case is (clip+1) * lines instructions
246 + sync + jump (all 2 dwords) */
247 instructions = (ov->nclips + 1) *
248 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
250 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
255 /* sync instruction */
257 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
258 *(rp++) = cpu_to_le32(0);
260 addr = (unsigned long)btv->fbuf.base;
261 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
262 addr += (fmt->depth >> 3) * ov->w.left;
265 for (maxy = -1, line = 0; line < ov->w.height;
266 line++, addr += btv->fbuf.fmt.bytesperline) {
267 if ((btv->opt_vcr_hack) &&
268 (line >= (ov->w.height - VCR_HACK_LINES)))
270 if ((line%2) == 0 && skip_even)
272 if ((line%2) == 1 && skip_odd)
275 /* calculate clipping */
277 btcx_calc_skips(line, ov->w.width, &maxy,
278 skips, &nskips, ov->clips, ov->nclips);
280 /* write out risc code */
281 for (start = 0, skip = 0; start < ov->w.width; start = end) {
282 if (skip >= nskips) {
283 ri = BT848_RISC_WRITE;
285 } else if (start < skips[skip].start) {
286 ri = BT848_RISC_WRITE;
287 end = skips[skip].start;
289 ri = BT848_RISC_SKIP;
290 end = skips[skip].end;
293 if (BT848_RISC_WRITE == ri)
294 ra = addr + (fmt->depth>>3)*start;
299 ri |= BT848_RISC_SOL;
300 if (ov->w.width == end)
301 ri |= BT848_RISC_EOL;
302 ri |= (fmt->depth>>3) * (end-start);
304 *(rp++)=cpu_to_le32(ri);
306 *(rp++)=cpu_to_le32(ra);
310 /* save pointer to jmp instruction address */
316 /* ---------------------------------------------------------- */
319 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
320 int width, int height, int interleaved, int norm)
322 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
326 int swidth = tvnorm->swidth;
327 int totalwidth = tvnorm->totalwidth;
328 int scaledtwidth = tvnorm->scaledtwidth;
330 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
336 vdelay = tvnorm->vdelay;
338 if (vdelay < btv->vbi.lines*2)
339 vdelay = btv->vbi.lines*2;
342 xsf = (width*scaledtwidth)/swidth;
343 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
344 geo->hdelay = tvnorm->hdelayx1;
345 geo->hdelay = (geo->hdelay*width)/swidth;
346 geo->hdelay &= 0x3fe;
347 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
348 geo->vscale = (0x10000UL-sr) & 0x1fff;
349 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
350 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
351 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
352 geo->vdelay = vdelay;
354 geo->sheight = tvnorm->sheight;
355 geo->vtotal = tvnorm->vtotal;
357 if (btv->opt_combfilter) {
358 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
359 geo->comb = (width < 769) ? 1 : 0;
367 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
369 int off = odd ? 0x80 : 0x00;
372 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
374 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
376 btwrite(geo->vtc, BT848_E_VTC+off);
377 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
378 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
379 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
380 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
381 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
382 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
383 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
384 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
385 btwrite(geo->crop, BT848_E_CROP+off);
386 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
387 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
390 /* ---------------------------------------------------------- */
391 /* risc group / risc main loop / dma management */
394 bttv_set_dma(struct bttv *btv, int override, int irqflags)
400 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
401 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
402 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
405 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
406 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
410 "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
411 btv->c.nr,capctl,irqflags,
412 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
413 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
414 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
415 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
417 cmd = BT848_RISC_JUMP;
419 cmd |= BT848_RISC_IRQ;
420 cmd |= (irqflags & 0x0f) << 16;
421 cmd |= (~irqflags & 0x0f) << 20;
423 if (irqflags || btv->cvbi) {
424 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
426 del_timer(&btv->timeout);
428 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
430 btaor(capctl, ~0x0f, BT848_CAP_CTL);
434 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
435 btor(3, BT848_GPIO_DMA_CTL);
440 btand(~3, BT848_GPIO_DMA_CTL);
447 bttv_risc_init_main(struct bttv *btv)
451 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
453 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
454 btv->c.nr,(unsigned long long)btv->main.dma);
456 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
457 BT848_FIFO_STATUS_VRE);
458 btv->main.cpu[1] = cpu_to_le32(0);
459 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
460 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
463 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
464 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
465 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
466 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
468 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
469 BT848_FIFO_STATUS_VRO);
470 btv->main.cpu[9] = cpu_to_le32(0);
473 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
474 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
475 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
476 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
478 /* jump back to top field */
479 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
480 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
486 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
490 unsigned long next = btv->main.dma + ((slot+2) << 2);
493 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
494 btv->c.nr,risc,slot);
495 btv->main.cpu[slot+1] = cpu_to_le32(next);
497 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
498 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
499 cmd = BT848_RISC_JUMP;
501 cmd |= BT848_RISC_IRQ;
502 cmd |= (irqflags & 0x0f) << 16;
503 cmd |= (~irqflags & 0x0f) << 20;
505 risc->jmp[0] = cpu_to_le32(cmd);
506 risc->jmp[1] = cpu_to_le32(next);
507 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
513 bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
517 videobuf_waiton(&buf->vb,0,0);
518 videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
519 videobuf_dma_free(&buf->vb.dma);
520 btcx_riscmem_free(btv->c.pci,&buf->bottom);
521 btcx_riscmem_free(btv->c.pci,&buf->top);
522 buf->vb.state = STATE_NEEDS_INIT;
526 bttv_buffer_activate_vbi(struct bttv *btv,
527 struct bttv_buffer *vbi)
531 vbi->vb.state = STATE_ACTIVE;
532 list_del(&vbi->vb.queue);
533 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
534 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
536 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
537 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
543 bttv_buffer_activate_video(struct bttv *btv,
544 struct bttv_buffer_set *set)
547 if (NULL != set->top && NULL != set->bottom) {
548 if (set->top == set->bottom) {
549 set->top->vb.state = STATE_ACTIVE;
550 if (set->top->vb.queue.next)
551 list_del(&set->top->vb.queue);
553 set->top->vb.state = STATE_ACTIVE;
554 set->bottom->vb.state = STATE_ACTIVE;
555 if (set->top->vb.queue.next)
556 list_del(&set->top->vb.queue);
557 if (set->bottom->vb.queue.next)
558 list_del(&set->bottom->vb.queue);
560 bttv_apply_geo(btv, &set->top->geo, 1);
561 bttv_apply_geo(btv, &set->bottom->geo,0);
562 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, set->topirq);
563 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
564 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
565 ~0xff, BT848_COLOR_FMT);
566 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
567 ~0x0f, BT848_COLOR_CTL);
568 } else if (NULL != set->top) {
569 set->top->vb.state = STATE_ACTIVE;
570 if (set->top->vb.queue.next)
571 list_del(&set->top->vb.queue);
572 bttv_apply_geo(btv, &set->top->geo,1);
573 bttv_apply_geo(btv, &set->top->geo,0);
574 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 0);
575 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
576 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
577 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
578 } else if (NULL != set->bottom) {
579 set->bottom->vb.state = STATE_ACTIVE;
580 if (set->bottom->vb.queue.next)
581 list_del(&set->bottom->vb.queue);
582 bttv_apply_geo(btv, &set->bottom->geo,1);
583 bttv_apply_geo(btv, &set->bottom->geo,0);
584 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
585 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
586 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
587 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
589 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
590 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
595 /* ---------------------------------------------------------- */
597 /* calculate geometry, build risc code */
599 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
601 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
604 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
605 btv->c.nr, v4l2_field_names[buf->vb.field],
606 buf->fmt->name, buf->vb.width, buf->vb.height);
608 /* packed pixel modes */
609 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
610 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
611 int bpf = bpl * (buf->vb.height >> 1);
613 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
614 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
616 switch (buf->vb.field) {
618 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
619 0,bpl,0,buf->vb.height);
621 case V4L2_FIELD_BOTTOM:
622 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
623 0,bpl,0,buf->vb.height);
625 case V4L2_FIELD_INTERLACED:
626 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
627 0,bpl,bpl,buf->vb.height >> 1);
628 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
629 bpl,bpl,bpl,buf->vb.height >> 1);
631 case V4L2_FIELD_SEQ_TB:
632 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
633 0,bpl,0,buf->vb.height >> 1);
634 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
635 bpf,bpl,0,buf->vb.height >> 1);
643 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
644 int uoffset, voffset;
645 int ypadding, cpadding, lines;
647 /* calculate chroma offsets */
648 uoffset = buf->vb.width * buf->vb.height;
649 voffset = buf->vb.width * buf->vb.height;
650 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
651 /* Y-Cr-Cb plane order */
652 uoffset >>= buf->fmt->hshift;
653 uoffset >>= buf->fmt->vshift;
656 /* Y-Cb-Cr plane order */
657 voffset >>= buf->fmt->hshift;
658 voffset >>= buf->fmt->vshift;
662 switch (buf->vb.field) {
664 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
665 buf->vb.height,0,buf->tvnorm);
666 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
667 0,buf->vb.width,0,buf->vb.height,
668 uoffset,voffset,buf->fmt->hshift,
671 case V4L2_FIELD_BOTTOM:
672 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
673 buf->vb.height,0,buf->tvnorm);
674 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
675 0,buf->vb.width,0,buf->vb.height,
676 uoffset,voffset,buf->fmt->hshift,
679 case V4L2_FIELD_INTERLACED:
680 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
681 buf->vb.height,1,buf->tvnorm);
682 lines = buf->vb.height >> 1;
683 ypadding = buf->vb.width;
684 cpadding = buf->vb.width >> buf->fmt->hshift;
685 bttv_risc_planar(btv,&buf->top,
687 0,buf->vb.width,ypadding,lines,
692 bttv_risc_planar(btv,&buf->bottom,
694 ypadding,buf->vb.width,ypadding,lines,
701 case V4L2_FIELD_SEQ_TB:
702 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
703 buf->vb.height,1,buf->tvnorm);
704 lines = buf->vb.height >> 1;
705 ypadding = buf->vb.width;
706 cpadding = buf->vb.width >> buf->fmt->hshift;
707 bttv_risc_planar(btv,&buf->top,
709 0,buf->vb.width,0,lines,
715 bttv_risc_planar(btv,&buf->bottom,
717 lines * ypadding,buf->vb.width,0,lines,
718 lines * ypadding + (uoffset >> 1),
719 lines * ypadding + (voffset >> 1),
730 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
731 /* build risc code */
732 buf->vb.field = V4L2_FIELD_SEQ_TB;
733 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
735 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
736 0, RAW_BPL, 0, RAW_LINES);
737 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
738 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
741 /* copy format info */
742 buf->btformat = buf->fmt->btformat;
743 buf->btswap = buf->fmt->btswap;
747 /* ---------------------------------------------------------- */
749 /* calculate geometry, build risc code */
751 bttv_overlay_risc(struct bttv *btv,
752 struct bttv_overlay *ov,
753 const struct bttv_format *fmt,
754 struct bttv_buffer *buf)
756 /* check interleave, bottom+top fields */
758 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
759 btv->c.nr, v4l2_field_names[buf->vb.field],
760 fmt->name,ov->w.width,ov->w.height);
762 /* calculate geometry */
763 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
764 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
766 /* build risc code */
769 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
771 case V4L2_FIELD_BOTTOM:
772 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
774 case V4L2_FIELD_INTERLACED:
776 bttv_risc_overlay(btv, &buf->top, fmt, ov, 1, 0);
777 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
779 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
780 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
787 /* copy format info */
788 buf->btformat = fmt->btformat;
789 buf->btswap = fmt->btswap;
790 buf->vb.field = ov->field;