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 ((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 WARN_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 WARN_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 */
363 static void bttv_set_risc_status(struct bttv *btv)
365 unsigned long cmd = BT848_RISC_JUMP;
367 cmd |= BT848_RISC_IRQ;
368 cmd |= (btv->loop_irq & 0x0f) << 16;
369 cmd |= (~btv->loop_irq & 0x0f) << 20;
371 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
374 static void bttv_set_irq_timer(struct bttv *btv)
376 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi)
377 mod_timer(&btv->timeout, jiffies + BTTV_TIMEOUT);
379 del_timer(&btv->timeout);
382 static int bttv_set_capture_control(struct bttv *btv, int start_capture)
386 if (btv->curr.top || btv->curr.bottom)
387 capctl = BT848_CAP_CTL_CAPTURE_ODD |
388 BT848_CAP_CTL_CAPTURE_EVEN;
391 capctl |= BT848_CAP_CTL_CAPTURE_VBI_ODD |
392 BT848_CAP_CTL_CAPTURE_VBI_EVEN;
394 capctl |= start_capture;
396 btaor(capctl, ~0x0f, BT848_CAP_CTL);
401 static void bttv_start_dma(struct bttv *btv)
405 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
406 btor(BT848_GPIO_DMA_CTL_RISC_ENABLE | BT848_GPIO_DMA_CTL_FIFO_ENABLE,
411 static void bttv_stop_dma(struct bttv *btv)
415 btand(~(BT848_GPIO_DMA_CTL_RISC_ENABLE |
416 BT848_GPIO_DMA_CTL_FIFO_ENABLE), BT848_GPIO_DMA_CTL);
420 void bttv_set_dma(struct bttv *btv, int start_capture)
424 bttv_set_risc_status(btv);
425 bttv_set_irq_timer(btv);
426 capctl = bttv_set_capture_control(btv, start_capture);
433 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
434 btv->c.nr,capctl,btv->loop_irq,
435 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
436 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
437 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
438 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
442 bttv_risc_init_main(struct bttv *btv)
446 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
448 dprintk("%d: risc main @ %08llx\n",
449 btv->c.nr, (unsigned long long)btv->main.dma);
451 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
452 BT848_FIFO_STATUS_VRE);
453 btv->main.cpu[1] = cpu_to_le32(0);
454 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
455 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
458 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
459 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
464 BT848_FIFO_STATUS_VRO);
465 btv->main.cpu[9] = cpu_to_le32(0);
468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
473 /* jump back to top field */
474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
481 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
485 unsigned long next = btv->main.dma + ((slot+2) << 2);
488 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
489 btv->main.cpu[slot+1] = cpu_to_le32(next);
491 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
492 btv->c.nr, risc, slot,
493 (unsigned long long)risc->dma, irqflags);
494 cmd = BT848_RISC_JUMP;
496 cmd |= BT848_RISC_IRQ;
497 cmd |= (irqflags & 0x0f) << 16;
498 cmd |= (~irqflags & 0x0f) << 20;
500 risc->jmp[0] = cpu_to_le32(cmd);
501 risc->jmp[1] = cpu_to_le32(next);
502 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
507 int bttv_buffer_risc_vbi(struct bttv *btv, struct bttv_buffer *buf)
511 unsigned int bpl = 2044; /* max. vbipack */
512 unsigned int padding = VBI_BPL - bpl;
513 unsigned int skip_lines0 = 0;
514 unsigned int skip_lines1 = 0;
515 unsigned int min_vdelay = MIN_VDELAY;
517 const struct bttv_tvnorm *tvnorm = btv->vbi_fmt.tvnorm;
518 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vbuf.vb2_buf, 0);
519 struct scatterlist *list = sgt->sgl;
521 if (btv->vbi_fmt.fmt.count[0] > 0)
522 skip_lines0 = max(0, (btv->vbi_fmt.fmt.start[0] -
523 tvnorm->vbistart[0]));
524 if (btv->vbi_fmt.fmt.count[1] > 0)
525 skip_lines1 = max(0, (btv->vbi_fmt.fmt.start[1] -
526 tvnorm->vbistart[1]));
528 if (btv->vbi_fmt.fmt.count[0] > 0) {
529 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, padding,
530 skip_lines0, btv->vbi_fmt.fmt.count[0]);
535 if (btv->vbi_fmt.fmt.count[1] > 0) {
536 offset = btv->vbi_fmt.fmt.count[0] * VBI_BPL;
537 r = bttv_risc_packed(btv, &buf->bottom, list, offset, bpl,
538 padding, skip_lines1,
539 btv->vbi_fmt.fmt.count[1]);
544 if (btv->vbi_fmt.end >= tvnorm->cropcap.bounds.top)
545 min_vdelay += btv->vbi_fmt.end - tvnorm->cropcap.bounds.top;
547 /* For bttv_buffer_activate_vbi(). */
548 buf->geo.vdelay = min_vdelay;
554 bttv_buffer_activate_vbi(struct bttv *btv,
555 struct bttv_buffer *vbi)
557 struct btcx_riscmem *top;
558 struct btcx_riscmem *bottom;
560 int bottom_irq_flags;
565 bottom_irq_flags = 0;
568 unsigned int crop, vdelay;
570 list_del(&vbi->list);
572 /* VDELAY is start of video, end of VBI capturing. */
573 crop = btread(BT848_E_CROP);
574 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
576 if (vbi->geo.vdelay > vdelay) {
577 vdelay = vbi->geo.vdelay & 0xfe;
578 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
580 btwrite(vdelay, BT848_E_VDELAY_LO);
581 btwrite(crop, BT848_E_CROP);
582 btwrite(vdelay, BT848_O_VDELAY_LO);
583 btwrite(crop, BT848_O_CROP);
586 if (btv->vbi_count[0] > 0) {
591 if (btv->vbi_count[1] > 0) {
593 bottom = &vbi->bottom;
594 bottom_irq_flags = 4;
598 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
599 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
605 bttv_buffer_activate_video(struct bttv *btv,
606 struct bttv_buffer_set *set)
609 if (NULL != set->top && NULL != set->bottom) {
610 if (set->top == set->bottom) {
611 if (set->top->list.next)
612 list_del(&set->top->list);
614 if (set->top->list.next)
615 list_del(&set->top->list);
616 if (set->bottom->list.next)
617 list_del(&set->bottom->list);
619 bttv_apply_geo(btv, &set->top->geo, 1);
620 bttv_apply_geo(btv, &set->bottom->geo,0);
621 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
623 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
625 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
626 ~0xff, BT848_COLOR_FMT);
627 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
628 ~0x0f, BT848_COLOR_CTL);
629 } else if (NULL != set->top) {
630 if (set->top->list.next)
631 list_del(&set->top->list);
632 bttv_apply_geo(btv, &set->top->geo,1);
633 bttv_apply_geo(btv, &set->top->geo,0);
634 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
636 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
637 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
638 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
639 } else if (NULL != set->bottom) {
640 if (set->bottom->list.next)
641 list_del(&set->bottom->list);
642 bttv_apply_geo(btv, &set->bottom->geo,1);
643 bttv_apply_geo(btv, &set->bottom->geo,0);
644 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
645 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
647 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
648 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
650 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
651 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
656 /* ---------------------------------------------------------- */
658 /* calculate geometry, build risc code */
660 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
663 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + btv->tvnorm;
664 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vbuf.vb2_buf, 0);
665 struct scatterlist *list = sgt->sgl;
666 unsigned long size = (btv->fmt->depth * btv->width * btv->height) >> 3;
668 /* packed pixel modes */
669 if (btv->fmt->flags & FORMAT_FLAGS_PACKED) {
670 int bpl = (btv->fmt->depth >> 3) * btv->width;
671 int bpf = bpl * (btv->height >> 1);
673 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height,
674 V4L2_FIELD_HAS_BOTH(buf->vbuf.field), tvnorm,
675 &btv->crop[!!btv->do_crop].rect);
676 switch (buf->vbuf.field) {
678 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, 0,
681 case V4L2_FIELD_BOTTOM:
682 r = bttv_risc_packed(btv, &buf->bottom, list, 0, bpl,
685 case V4L2_FIELD_INTERLACED:
686 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl,
687 bpl, 0, btv->height >> 1);
688 r = bttv_risc_packed(btv, &buf->bottom, list, bpl,
689 bpl, bpl, 0, btv->height >> 1);
691 case V4L2_FIELD_SEQ_TB:
692 r = bttv_risc_packed(btv, &buf->top, list, 0, bpl, 0,
693 0, btv->height >> 1);
694 r = bttv_risc_packed(btv, &buf->bottom, list, bpf,
695 bpl, 0, 0, btv->height >> 1);
703 if (btv->fmt->flags & FORMAT_FLAGS_PLANAR) {
704 int uoffset, voffset;
705 int ypadding, cpadding, lines;
707 /* calculate chroma offsets */
708 uoffset = btv->width * btv->height;
709 voffset = btv->width * btv->height;
710 if (btv->fmt->flags & FORMAT_FLAGS_CrCb) {
711 /* Y-Cr-Cb plane order */
712 uoffset >>= btv->fmt->hshift;
713 uoffset >>= btv->fmt->vshift;
716 /* Y-Cb-Cr plane order */
717 voffset >>= btv->fmt->hshift;
718 voffset >>= btv->fmt->vshift;
721 switch (buf->vbuf.field) {
723 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height,
725 &btv->crop[!!btv->do_crop].rect);
726 r = bttv_risc_planar(btv, &buf->top, list, 0,
727 btv->width, 0, btv->height,
730 btv->fmt->vshift, 0);
732 case V4L2_FIELD_BOTTOM:
733 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height,
735 &btv->crop[!!btv->do_crop].rect);
736 r = bttv_risc_planar(btv, &buf->bottom, list, 0,
737 btv->width, 0, btv->height,
740 btv->fmt->vshift, 0);
742 case V4L2_FIELD_INTERLACED:
743 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height,
745 &btv->crop[!!btv->do_crop].rect);
746 lines = btv->height >> 1;
747 ypadding = btv->width;
748 cpadding = btv->width >> btv->fmt->hshift;
749 r = bttv_risc_planar(btv, &buf->top, list, 0,
750 btv->width, ypadding, lines,
753 btv->fmt->vshift, cpadding);
755 r = bttv_risc_planar(btv, &buf->bottom, list,
756 ypadding, btv->width, ypadding,
757 lines, uoffset + cpadding,
760 btv->fmt->vshift, cpadding);
762 case V4L2_FIELD_SEQ_TB:
763 bttv_calc_geo(btv, &buf->geo, btv->width, btv->height,
765 &btv->crop[!!btv->do_crop].rect);
766 lines = btv->height >> 1;
767 ypadding = btv->width;
768 cpadding = btv->width >> btv->fmt->hshift;
769 r = bttv_risc_planar(btv, &buf->top, list, 0,
770 btv->width, 0, lines,
771 uoffset >> 1, voffset >> 1,
773 btv->fmt->vshift, 0);
774 r = bttv_risc_planar(btv, &buf->bottom, list,
776 btv->width, 0, lines,
777 lines * ypadding + (uoffset >> 1),
778 lines * ypadding + (voffset >> 1),
780 btv->fmt->vshift, 0);
788 if (btv->fmt->flags & FORMAT_FLAGS_RAW) {
789 /* build risc code */
790 buf->vbuf.field = V4L2_FIELD_SEQ_TB;
791 bttv_calc_geo(btv, &buf->geo, tvnorm->swidth, tvnorm->sheight,
792 1, tvnorm, &btv->crop[!!btv->do_crop].rect);
793 r = bttv_risc_packed(btv, &buf->top, list, 0, RAW_BPL, 0, 0,
795 r = bttv_risc_packed(btv, &buf->bottom, list, size / 2,
796 RAW_BPL, 0, 0, RAW_LINES);
799 /* copy format info */
800 buf->btformat = btv->fmt->btformat;
801 buf->btswap = btv->fmt->btswap;