1 // SPDX-License-Identifier: GPL-2.0-or-later
4 bttv-risc.c -- interfaces to other kernel modules
6 bttv risc code handling
10 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/pci.h>
21 #include <linux/vmalloc.h>
22 #include <linux/interrupt.h>
23 #include <linux/pgtable.h>
25 #include <media/v4l2-ioctl.h>
29 #define VCR_HACK_LINES 4
31 /* ---------------------------------------------------------- */
32 /* risc code generators */
35 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
36 struct scatterlist *sglist,
37 unsigned int offset, unsigned int bpl,
38 unsigned int padding, unsigned int skip_lines,
39 unsigned int store_lines)
41 u32 instructions,line,todo;
42 struct scatterlist *sg;
46 /* estimate risc mem: worst case is one write per page border +
47 one write per scan line + sync + jump (all 2 dwords). padding
48 can cause next bpl to start close to a page border. First DMA
49 region may be smaller than PAGE_SIZE */
50 instructions = skip_lines * 4;
51 instructions += (1 + ((bpl + padding) * store_lines)
52 / PAGE_SIZE + store_lines) * 8;
53 instructions += 2 * 8;
54 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
57 /* sync instruction */
59 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
60 *(rp++) = cpu_to_le32(0);
62 while (skip_lines-- > 0) {
63 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
64 BT848_RISC_EOL | bpl);
69 for (line = 0; line < store_lines; line++) {
70 if ((btv->opt_vcr_hack) &&
71 (line >= (store_lines - VCR_HACK_LINES)))
73 while (offset && offset >= sg_dma_len(sg)) {
74 offset -= sg_dma_len(sg);
77 if (bpl <= sg_dma_len(sg)-offset) {
78 /* fits into current chunk */
79 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
81 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
84 /* scanline needs to be split */
86 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
87 (sg_dma_len(sg)-offset));
88 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
89 todo -= (sg_dma_len(sg)-offset);
92 while (todo > sg_dma_len(sg)) {
93 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
95 *(rp++)=cpu_to_le32(sg_dma_address(sg));
96 todo -= sg_dma_len(sg);
99 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
101 *(rp++)=cpu_to_le32(sg_dma_address(sg));
107 /* save pointer to jmp instruction address */
109 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
114 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
115 struct scatterlist *sglist,
116 unsigned int yoffset, unsigned int ybpl,
117 unsigned int ypadding, unsigned int ylines,
118 unsigned int uoffset, unsigned int voffset,
119 unsigned int hshift, unsigned int vshift,
120 unsigned int cpadding)
122 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 = ((3 + (ybpl + ypadding) * ylines * 2)
135 / PAGE_SIZE) + ylines;
137 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
140 /* sync instruction */
142 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
143 *(rp++) = cpu_to_le32(0);
149 for (line = 0; line < ylines; line++) {
150 if ((btv->opt_vcr_hack) &&
151 (line >= (ylines - VCR_HACK_LINES)))
159 chroma = ((line & 1) == 0);
161 chroma = ((line & 1) == 1);
165 chroma = ((line & 3) == 0);
167 chroma = ((line & 3) == 2);
174 for (todo = ybpl; todo > 0; todo -= ylen) {
175 /* go to next sg entry if needed */
176 while (yoffset && yoffset >= sg_dma_len(ysg)) {
177 yoffset -= sg_dma_len(ysg);
181 /* calculate max number of bytes we can write */
183 if (yoffset + ylen > sg_dma_len(ysg))
184 ylen = sg_dma_len(ysg) - yoffset;
186 while (uoffset && uoffset >= sg_dma_len(usg)) {
187 uoffset -= sg_dma_len(usg);
190 while (voffset && voffset >= sg_dma_len(vsg)) {
191 voffset -= sg_dma_len(vsg);
195 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
196 ylen = (sg_dma_len(usg) - uoffset) << hshift;
197 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
198 ylen = (sg_dma_len(vsg) - voffset) << hshift;
199 ri = BT848_RISC_WRITE123;
201 ri = BT848_RISC_WRITE1S23;
204 ri |= BT848_RISC_SOL;
206 ri |= BT848_RISC_EOL;
208 /* write risc instruction */
209 *(rp++)=cpu_to_le32(ri | ylen);
210 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
212 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
215 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
216 uoffset += ylen >> hshift;
217 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
218 voffset += ylen >> hshift;
228 /* save pointer to jmp instruction address */
230 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
234 /* ---------------------------------------------------------- */
237 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
238 int width, int height, int interleaved,
239 const struct bttv_tvnorm *tvnorm)
244 int swidth = tvnorm->swidth;
245 int totalwidth = tvnorm->totalwidth;
246 int scaledtwidth = tvnorm->scaledtwidth;
248 if (btv->input == btv->dig) {
254 vdelay = tvnorm->vdelay;
256 xsf = (width*scaledtwidth)/swidth;
257 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
258 geo->hdelay = tvnorm->hdelayx1;
259 geo->hdelay = (geo->hdelay*width)/swidth;
260 geo->hdelay &= 0x3fe;
261 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
262 geo->vscale = (0x10000UL-sr) & 0x1fff;
263 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
264 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
265 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
266 geo->vdelay = vdelay;
268 geo->sheight = tvnorm->sheight;
269 geo->vtotal = tvnorm->vtotal;
271 if (btv->opt_combfilter) {
272 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
273 geo->comb = (width < 769) ? 1 : 0;
281 bttv_calc_geo (struct bttv * btv,
282 struct bttv_geometry * geo,
286 const struct bttv_tvnorm * tvnorm,
287 const struct v4l2_rect * crop)
289 unsigned int c_width;
290 unsigned int c_height;
293 if ((crop->left == tvnorm->cropcap.defrect.left
294 && crop->top == tvnorm->cropcap.defrect.top
295 && crop->width == tvnorm->cropcap.defrect.width
296 && crop->height == tvnorm->cropcap.defrect.height
297 && width <= tvnorm->swidth /* see PAL-Nc et al */)
298 || btv->input == btv->dig) {
299 bttv_calc_geo_old(btv, geo, width, height,
300 both_fields, tvnorm);
304 /* For bug compatibility the image size checks permit scale
305 factors > 16. See bttv_crop_calc_limits(). */
306 c_width = min((unsigned int) crop->width, width * 16);
307 c_height = min((unsigned int) crop->height, height * 16);
310 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
311 /* Even to store Cb first, odd for Cr. */
312 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
314 geo->sheight = c_height;
315 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
316 sr = c_height >> !both_fields;
317 sr = (sr * 512U + (height >> 1)) / height - 512;
318 geo->vscale = (0x10000UL - sr) & 0x1fff;
319 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
320 geo->vtotal = tvnorm->vtotal;
322 geo->crop = (((geo->width >> 8) & 0x03) |
323 ((geo->hdelay >> 6) & 0x0c) |
324 ((geo->sheight >> 4) & 0x30) |
325 ((geo->vdelay >> 2) & 0xc0));
327 if (btv->opt_combfilter) {
328 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
329 geo->comb = (width < 769) ? 1 : 0;
337 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
339 int off = odd ? 0x80 : 0x00;
342 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
344 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
346 btwrite(geo->vtc, BT848_E_VTC+off);
347 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
348 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
349 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
350 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
351 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
352 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
353 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
354 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
355 btwrite(geo->crop, BT848_E_CROP+off);
356 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
357 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
360 /* ---------------------------------------------------------- */
361 /* risc group / risc main loop / dma management */
364 bttv_set_dma(struct bttv *btv, int override)
370 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
371 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
372 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
375 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
376 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
379 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
380 btv->c.nr,capctl,btv->loop_irq,
381 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
382 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
383 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
384 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
386 cmd = BT848_RISC_JUMP;
388 cmd |= BT848_RISC_IRQ;
389 cmd |= (btv->loop_irq & 0x0f) << 16;
390 cmd |= (~btv->loop_irq & 0x0f) << 20;
392 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
393 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
395 del_timer(&btv->timeout);
397 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
399 btaor(capctl, ~0x0f, BT848_CAP_CTL);
403 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
404 btor(3, BT848_GPIO_DMA_CTL);
409 btand(~3, BT848_GPIO_DMA_CTL);
416 bttv_risc_init_main(struct bttv *btv)
420 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
422 dprintk("%d: risc main @ %08llx\n",
423 btv->c.nr, (unsigned long long)btv->main.dma);
425 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
426 BT848_FIFO_STATUS_VRE);
427 btv->main.cpu[1] = cpu_to_le32(0);
428 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
429 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
432 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
433 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
434 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
435 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
437 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
438 BT848_FIFO_STATUS_VRO);
439 btv->main.cpu[9] = cpu_to_le32(0);
442 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
443 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
444 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
445 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
447 /* jump back to top field */
448 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
449 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
455 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
459 unsigned long next = btv->main.dma + ((slot+2) << 2);
462 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
463 btv->main.cpu[slot+1] = cpu_to_le32(next);
465 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
466 btv->c.nr, risc, slot,
467 (unsigned long long)risc->dma, irqflags);
468 cmd = BT848_RISC_JUMP;
470 cmd |= BT848_RISC_IRQ;
471 cmd |= (irqflags & 0x0f) << 16;
472 cmd |= (~irqflags & 0x0f) << 20;
474 risc->jmp[0] = cpu_to_le32(cmd);
475 risc->jmp[1] = cpu_to_le32(next);
476 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
482 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
484 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
486 videobuf_waiton(q, &buf->vb, 0, 0);
487 videobuf_dma_unmap(q->dev, dma);
488 videobuf_dma_free(dma);
489 btcx_riscmem_free(btv->c.pci,&buf->bottom);
490 btcx_riscmem_free(btv->c.pci,&buf->top);
491 buf->vb.state = VIDEOBUF_NEEDS_INIT;
495 bttv_buffer_activate_vbi(struct bttv *btv,
496 struct bttv_buffer *vbi)
498 struct btcx_riscmem *top;
499 struct btcx_riscmem *bottom;
501 int bottom_irq_flags;
506 bottom_irq_flags = 0;
509 unsigned int crop, vdelay;
511 vbi->vb.state = VIDEOBUF_ACTIVE;
512 list_del(&vbi->vb.queue);
514 /* VDELAY is start of video, end of VBI capturing. */
515 crop = btread(BT848_E_CROP);
516 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
518 if (vbi->geo.vdelay > vdelay) {
519 vdelay = vbi->geo.vdelay & 0xfe;
520 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
522 btwrite(vdelay, BT848_E_VDELAY_LO);
523 btwrite(crop, BT848_E_CROP);
524 btwrite(vdelay, BT848_O_VDELAY_LO);
525 btwrite(crop, BT848_O_CROP);
528 if (vbi->vbi_count[0] > 0) {
533 if (vbi->vbi_count[1] > 0) {
535 bottom = &vbi->bottom;
536 bottom_irq_flags = 4;
540 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
541 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
547 bttv_buffer_activate_video(struct bttv *btv,
548 struct bttv_buffer_set *set)
551 if (NULL != set->top && NULL != set->bottom) {
552 if (set->top == set->bottom) {
553 set->top->vb.state = VIDEOBUF_ACTIVE;
554 if (set->top->vb.queue.next)
555 list_del(&set->top->vb.queue);
557 set->top->vb.state = VIDEOBUF_ACTIVE;
558 set->bottom->vb.state = VIDEOBUF_ACTIVE;
559 if (set->top->vb.queue.next)
560 list_del(&set->top->vb.queue);
561 if (set->bottom->vb.queue.next)
562 list_del(&set->bottom->vb.queue);
564 bttv_apply_geo(btv, &set->top->geo, 1);
565 bttv_apply_geo(btv, &set->bottom->geo,0);
566 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
568 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
570 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
571 ~0xff, BT848_COLOR_FMT);
572 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
573 ~0x0f, BT848_COLOR_CTL);
574 } else if (NULL != set->top) {
575 set->top->vb.state = VIDEOBUF_ACTIVE;
576 if (set->top->vb.queue.next)
577 list_del(&set->top->vb.queue);
578 bttv_apply_geo(btv, &set->top->geo,1);
579 bttv_apply_geo(btv, &set->top->geo,0);
580 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
582 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
583 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
584 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
585 } else if (NULL != set->bottom) {
586 set->bottom->vb.state = VIDEOBUF_ACTIVE;
587 if (set->bottom->vb.queue.next)
588 list_del(&set->bottom->vb.queue);
589 bttv_apply_geo(btv, &set->bottom->geo,1);
590 bttv_apply_geo(btv, &set->bottom->geo,0);
591 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
592 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
594 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
595 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
597 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
598 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
603 /* ---------------------------------------------------------- */
605 /* calculate geometry, build risc code */
607 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
609 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
610 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
612 dprintk("%d: buffer field: %s format: 0x%08x size: %dx%d\n",
613 btv->c.nr, v4l2_field_names[buf->vb.field],
614 buf->fmt->fourcc, buf->vb.width, buf->vb.height);
616 /* packed pixel modes */
617 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
618 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
619 int bpf = bpl * (buf->vb.height >> 1);
621 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
622 V4L2_FIELD_HAS_BOTH(buf->vb.field),
625 switch (buf->vb.field) {
627 bttv_risc_packed(btv,&buf->top,dma->sglist,
629 /* padding */ 0,/* skip_lines */ 0,
632 case V4L2_FIELD_BOTTOM:
633 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
634 0,bpl,0,0,buf->vb.height);
636 case V4L2_FIELD_INTERLACED:
637 bttv_risc_packed(btv,&buf->top,dma->sglist,
638 0,bpl,bpl,0,buf->vb.height >> 1);
639 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
640 bpl,bpl,bpl,0,buf->vb.height >> 1);
642 case V4L2_FIELD_SEQ_TB:
643 bttv_risc_packed(btv,&buf->top,dma->sglist,
644 0,bpl,0,0,buf->vb.height >> 1);
645 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
646 bpf,bpl,0,0,buf->vb.height >> 1);
654 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
655 int uoffset, voffset;
656 int ypadding, cpadding, lines;
658 /* calculate chroma offsets */
659 uoffset = buf->vb.width * buf->vb.height;
660 voffset = buf->vb.width * buf->vb.height;
661 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
662 /* Y-Cr-Cb plane order */
663 uoffset >>= buf->fmt->hshift;
664 uoffset >>= buf->fmt->vshift;
667 /* Y-Cb-Cr plane order */
668 voffset >>= buf->fmt->hshift;
669 voffset >>= buf->fmt->vshift;
673 switch (buf->vb.field) {
675 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
676 buf->vb.height,/* both_fields */ 0,
678 bttv_risc_planar(btv, &buf->top, dma->sglist,
679 0,buf->vb.width,0,buf->vb.height,
680 uoffset,voffset,buf->fmt->hshift,
683 case V4L2_FIELD_BOTTOM:
684 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
687 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
688 0,buf->vb.width,0,buf->vb.height,
689 uoffset,voffset,buf->fmt->hshift,
692 case V4L2_FIELD_INTERLACED:
693 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
696 lines = buf->vb.height >> 1;
697 ypadding = buf->vb.width;
698 cpadding = buf->vb.width >> buf->fmt->hshift;
699 bttv_risc_planar(btv,&buf->top,
701 0,buf->vb.width,ypadding,lines,
706 bttv_risc_planar(btv,&buf->bottom,
708 ypadding,buf->vb.width,ypadding,lines,
715 case V4L2_FIELD_SEQ_TB:
716 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
719 lines = buf->vb.height >> 1;
720 ypadding = buf->vb.width;
721 cpadding = buf->vb.width >> buf->fmt->hshift;
722 bttv_risc_planar(btv,&buf->top,
724 0,buf->vb.width,0,lines,
730 bttv_risc_planar(btv,&buf->bottom,
732 lines * ypadding,buf->vb.width,0,lines,
733 lines * ypadding + (uoffset >> 1),
734 lines * ypadding + (voffset >> 1),
745 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
746 /* build risc code */
747 buf->vb.field = V4L2_FIELD_SEQ_TB;
748 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
749 1,tvnorm,&buf->crop);
750 bttv_risc_packed(btv, &buf->top, dma->sglist,
751 /* offset */ 0, RAW_BPL, /* padding */ 0,
752 /* skip_lines */ 0, RAW_LINES);
753 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
754 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
757 /* copy format info */
758 buf->btformat = buf->fmt->btformat;
759 buf->btswap = buf->fmt->btswap;