Lines Matching +full:input +full:- +full:depth

1 // SPDX-License-Identifier: GPL-2.0-or-later
9 * acknowledged. Full credit goes to them - any problems within this code
20 #include <media/v4l2-common.h>
21 #include <media/v4l2-event.h>
22 #include <media/videobuf2-dma-sg.h>
25 #include "tw68-reg.h"
27 /* ------------------------------------------------------------------ */
30 * FIXME -
38 .depth = 16,
42 .depth = 16,
46 .depth = 16,
50 .depth = 16,
54 .depth = 24,
58 .depth = 24,
62 .depth = 32,
66 .depth = 32,
71 .depth = 16,
75 .depth = 16,
148 .name = "PAL-M",
160 .name = "PAL-Nc",
172 .name = "PAL-60",
206 /* ------------------------------------------------------------------ */
213 if (norm != dev->tvnorm) { in set_tvnorm()
214 dev->width = 720; in set_tvnorm()
215 dev->height = (norm->id & V4L2_STD_525_60) ? 480 : 576; in set_tvnorm()
216 dev->tvnorm = norm; in set_tvnorm()
226 * We are working with 3 values for horizontal and vertical - scale,
253 const struct tw68_tvnorm *norm = dev->tvnorm; in tw68_set_scale()
260 height /= 2; /* we must set for 1-frame */ in tw68_set_scale()
265 norm->h_delay, norm->h_start, norm->h_stop, in tw68_set_scale()
266 norm->v_delay, norm->video_v_start, in tw68_set_scale()
267 norm->video_v_stop); in tw68_set_scale()
269 switch (dev->vdecoder) { in tw68_set_scale()
271 hdelay = norm->h_delay0; in tw68_set_scale()
274 hdelay = norm->h_delay; in tw68_set_scale()
278 hdelay += norm->h_start; in tw68_set_scale()
279 hactive = norm->h_stop - norm->h_start + 1; in tw68_set_scale()
283 vdelay = norm->v_delay; in tw68_set_scale()
284 vactive = ((norm->id & V4L2_STD_525_60) ? 524 : 624) / 2 - norm->video_v_start; in tw68_set_scale()
291 v4l2_norm_to_name(dev->tvnorm->id)); in tw68_set_scale()
318 /* ------------------------------------------------------------------ */
323 tw68_set_scale(dev, dev->width, dev->height, dev->field); in tw68_video_start_dma()
330 tw_writel(TW68_DMAP_SA, buf->dma); in tw68_video_start_dma()
332 tw_writel(TW68_INTSTAT, dev->board_virqmask); in tw68_video_start_dma()
334 tw_andorl(TW68_DMAC, 0xff, dev->fmt->twformat | in tw68_video_start_dma()
336 dev->pci_irqmask |= dev->board_virqmask; in tw68_video_start_dma()
337 tw_setl(TW68_INTMASK, dev->pci_irqmask); in tw68_video_start_dma()
341 /* ------------------------------------------------------------------ */
355 /* ------------------------------------------------------------- */
365 unsigned size = (dev->fmt->depth * dev->width * dev->height) >> 3; in tw68_queue_setup()
370 *num_buffers = tot_bufs - q_num_bufs; in tw68_queue_setup()
377 return sizes[0] < size ? -EINVAL : 0; in tw68_queue_setup()
401 * The end-result of all this that you only get an interrupt when a buffer
407 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_queue()
413 spin_lock_irqsave(&dev->slock, flags); in tw68_buf_queue()
416 buf->jmp[0] = cpu_to_le32(RISC_JUMP); in tw68_buf_queue()
417 buf->jmp[1] = cpu_to_le32(buf->dma + 8); in tw68_buf_queue()
419 if (!list_empty(&dev->active)) { in tw68_buf_queue()
420 prev = list_entry(dev->active.prev, struct tw68_buf, list); in tw68_buf_queue()
421 buf->cpu[0] |= cpu_to_le32(RISC_INT_BIT); in tw68_buf_queue()
422 prev->jmp[1] = cpu_to_le32(buf->dma); in tw68_buf_queue()
424 list_add_tail(&buf->list, &dev->active); in tw68_buf_queue()
425 spin_unlock_irqrestore(&dev->slock, flags); in tw68_buf_queue()
435 * user - type, width, height and #fields. This is compared with the
437 * code (which controls the filling of the buffer) is (re-)generated.
443 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_prepare()
449 size = (dev->width * dev->height * dev->fmt->depth) >> 3; in tw68_buf_prepare()
451 return -EINVAL; in tw68_buf_prepare()
454 bpl = (dev->width * dev->fmt->depth) >> 3; in tw68_buf_prepare()
455 switch (dev->field) { in tw68_buf_prepare()
457 ret = tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
458 0, UNSET, bpl, 0, dev->height); in tw68_buf_prepare()
461 ret = tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
462 UNSET, 0, bpl, 0, dev->height); in tw68_buf_prepare()
465 ret = tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
466 0, bpl * (dev->height >> 1), in tw68_buf_prepare()
467 bpl, 0, dev->height >> 1); in tw68_buf_prepare()
470 ret = tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
471 bpl * (dev->height >> 1), 0, in tw68_buf_prepare()
472 bpl, 0, dev->height >> 1); in tw68_buf_prepare()
476 ret = tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
477 0, bpl, bpl, bpl, dev->height >> 1); in tw68_buf_prepare()
486 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_finish()
490 if (buf->cpu) in tw68_buf_finish()
491 dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma); in tw68_buf_finish()
498 container_of(dev->active.next, struct tw68_buf, list); in tw68_start_streaming()
500 dev->seqnr = 0; in tw68_start_streaming()
511 while (!list_empty(&dev->active)) { in tw68_stop_streaming()
513 container_of(dev->active.next, struct tw68_buf, list); in tw68_stop_streaming()
515 list_del(&buf->list); in tw68_stop_streaming()
516 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw68_stop_streaming()
531 /* ------------------------------------------------------------------ */
536 container_of(ctrl->handler, struct tw68_dev, hdl); in tw68_s_ctrl()
538 switch (ctrl->id) { in tw68_s_ctrl()
540 tw_writeb(TW68_BRIGHT, ctrl->val); in tw68_s_ctrl()
543 tw_writeb(TW68_HUE, ctrl->val); in tw68_s_ctrl()
546 tw_writeb(TW68_CONTRAST, ctrl->val); in tw68_s_ctrl()
549 tw_writeb(TW68_SAT_U, ctrl->val); in tw68_s_ctrl()
550 tw_writeb(TW68_SAT_V, ctrl->val); in tw68_s_ctrl()
553 if (ctrl->val) in tw68_s_ctrl()
559 if (ctrl->val) in tw68_s_ctrl()
568 /* ------------------------------------------------------------------ */
579 f->fmt.pix.width = dev->width; in tw68_g_fmt_vid_cap()
580 f->fmt.pix.height = dev->height; in tw68_g_fmt_vid_cap()
581 f->fmt.pix.field = dev->field; in tw68_g_fmt_vid_cap()
582 f->fmt.pix.pixelformat = dev->fmt->fourcc; in tw68_g_fmt_vid_cap()
583 f->fmt.pix.bytesperline = in tw68_g_fmt_vid_cap()
584 (f->fmt.pix.width * (dev->fmt->depth)) >> 3; in tw68_g_fmt_vid_cap()
585 f->fmt.pix.sizeimage = in tw68_g_fmt_vid_cap()
586 f->fmt.pix.height * f->fmt.pix.bytesperline; in tw68_g_fmt_vid_cap()
587 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw68_g_fmt_vid_cap()
599 fmt = format_by_fourcc(f->fmt.pix.pixelformat); in tw68_try_fmt_vid_cap()
601 return -EINVAL; in tw68_try_fmt_vid_cap()
603 field = f->fmt.pix.field; in tw68_try_fmt_vid_cap()
604 maxh = (dev->tvnorm->id & V4L2_STD_525_60) ? 480 : 576; in tw68_try_fmt_vid_cap()
616 field = (f->fmt.pix.height > maxh / 2) in tw68_try_fmt_vid_cap()
622 f->fmt.pix.field = field; in tw68_try_fmt_vid_cap()
623 if (f->fmt.pix.width < 48) in tw68_try_fmt_vid_cap()
624 f->fmt.pix.width = 48; in tw68_try_fmt_vid_cap()
625 if (f->fmt.pix.height < 32) in tw68_try_fmt_vid_cap()
626 f->fmt.pix.height = 32; in tw68_try_fmt_vid_cap()
627 if (f->fmt.pix.width > 720) in tw68_try_fmt_vid_cap()
628 f->fmt.pix.width = 720; in tw68_try_fmt_vid_cap()
629 if (f->fmt.pix.height > maxh) in tw68_try_fmt_vid_cap()
630 f->fmt.pix.height = maxh; in tw68_try_fmt_vid_cap()
631 f->fmt.pix.width &= ~0x03; in tw68_try_fmt_vid_cap()
632 f->fmt.pix.bytesperline = in tw68_try_fmt_vid_cap()
633 (f->fmt.pix.width * (fmt->depth)) >> 3; in tw68_try_fmt_vid_cap()
634 f->fmt.pix.sizeimage = in tw68_try_fmt_vid_cap()
635 f->fmt.pix.height * f->fmt.pix.bytesperline; in tw68_try_fmt_vid_cap()
636 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw68_try_fmt_vid_cap()
656 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); in tw68_s_fmt_vid_cap()
657 dev->width = f->fmt.pix.width; in tw68_s_fmt_vid_cap()
658 dev->height = f->fmt.pix.height; in tw68_s_fmt_vid_cap()
659 dev->field = f->fmt.pix.field; in tw68_s_fmt_vid_cap()
669 n = i->index; in tw68_enum_input()
671 return -EINVAL; in tw68_enum_input()
672 i->index = n; in tw68_enum_input()
673 i->type = V4L2_INPUT_TYPE_CAMERA; in tw68_enum_input()
674 snprintf(i->name, sizeof(i->name), "Composite %d", n); in tw68_enum_input()
676 /* If the query is for the current input, get live data */ in tw68_enum_input()
677 if (n == dev->input) { in tw68_enum_input()
682 i->status |= V4L2_IN_ST_NO_SYNC; in tw68_enum_input()
684 i->status |= V4L2_IN_ST_NO_H_LOCK; in tw68_enum_input()
686 i->status |= V4L2_IN_ST_NO_SIGNAL; in tw68_enum_input()
688 i->status |= V4L2_IN_ST_NO_COLOR; in tw68_enum_input()
690 i->status |= V4L2_IN_ST_MACROVISION; in tw68_enum_input()
692 i->std = video_devdata(file)->tvnorms; in tw68_enum_input()
700 *i = dev->input; in tw68_g_input()
709 return -EINVAL; in tw68_s_input()
710 dev->input = i; in tw68_s_input()
711 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input << 2); in tw68_s_input()
718 strscpy(cap->driver, "tw68", sizeof(cap->driver)); in tw68_querycap()
719 strscpy(cap->card, "Techwell Capture Card", in tw68_querycap()
720 sizeof(cap->card)); in tw68_querycap()
729 if (vb2_is_busy(&dev->vidq)) in tw68_s_std()
730 return -EBUSY; in tw68_s_std()
746 return -EINVAL; in tw68_s_std()
756 *id = dev->tvnorm->id; in tw68_g_std()
763 if (f->index >= FORMATS) in tw68_enum_fmt_vid_cap()
764 return -EINVAL; in tw68_enum_fmt_vid_cap()
766 f->pixelformat = formats[f->index].fourcc; in tw68_enum_fmt_vid_cap()
782 /* First we do the PCI regs, 8 4-byte regs per line */ in tw68_dump_regs()
796 /* Next the control regs, which are single-byte, address mod 4 */ in tw68_dump_regs()
829 if (reg->size == 1) in vidioc_g_register()
830 reg->val = tw_readb(reg->reg); in vidioc_g_register()
832 reg->val = tw_readl(reg->reg); in vidioc_g_register()
841 if (reg->size == 1) in vidioc_s_register()
842 tw_writeb(reg->reg, reg->val); in vidioc_s_register()
844 tw_writel(reg->reg & 0xffff, reg->val); in vidioc_s_register()
900 /* ------------------------------------------------------------------ */
904 tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format); in tw68_set_tvnorm_hw()
909 struct v4l2_ctrl_handler *hdl = &dev->hdl; in tw68_video_init1()
913 V4L2_CID_BRIGHTNESS, -128, 127, 1, 20); in tw68_video_init1()
920 V4L2_CID_HUE, -128, 127, 1, 0); in tw68_video_init1()
925 if (hdl->error) { in tw68_video_init1()
927 return hdl->error; in tw68_video_init1()
929 dev->v4l2_dev.ctrl_handler = hdl; in tw68_video_init1()
940 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); in tw68_video_init2()
941 dev->width = 720; in tw68_video_init2()
942 dev->height = 576; in tw68_video_init2()
943 dev->field = V4L2_FIELD_INTERLACED; in tw68_video_init2()
945 INIT_LIST_HEAD(&dev->active); in tw68_video_init2()
946 dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in tw68_video_init2()
947 dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in tw68_video_init2()
948 dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | VB2_DMABUF; in tw68_video_init2()
949 dev->vidq.ops = &tw68_video_qops; in tw68_video_init2()
950 dev->vidq.mem_ops = &vb2_dma_sg_memops; in tw68_video_init2()
951 dev->vidq.drv_priv = dev; in tw68_video_init2()
952 dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in tw68_video_init2()
953 dev->vidq.buf_struct_size = sizeof(struct tw68_buf); in tw68_video_init2()
954 dev->vidq.lock = &dev->lock; in tw68_video_init2()
955 dev->vidq.min_queued_buffers = 2; in tw68_video_init2()
956 dev->vidq.dev = &dev->pci->dev; in tw68_video_init2()
957 ret = vb2_queue_init(&dev->vidq); in tw68_video_init2()
960 dev->vdev = tw68_video_template; in tw68_video_init2()
961 dev->vdev.v4l2_dev = &dev->v4l2_dev; in tw68_video_init2()
962 dev->vdev.lock = &dev->lock; in tw68_video_init2()
963 dev->vdev.queue = &dev->vidq; in tw68_video_init2()
964 video_set_drvdata(&dev->vdev, dev); in tw68_video_init2()
965 return video_register_device(&dev->vdev, VFL_TYPE_VIDEO, video_nr); in tw68_video_init2()
986 spin_lock(&dev->slock); in tw68_irq_video_done()
987 buf = list_entry(dev->active.next, struct tw68_buf, list); in tw68_irq_video_done()
988 list_del(&buf->list); in tw68_irq_video_done()
989 spin_unlock(&dev->slock); in tw68_irq_video_done()
990 buf->vb.vb2_buf.timestamp = ktime_get_ns(); in tw68_irq_video_done()
991 buf->vb.field = dev->field; in tw68_irq_video_done()
992 buf->vb.sequence = dev->seqnr++; in tw68_irq_video_done()
993 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in tw68_irq_video_done()
999 dev_dbg(&dev->pci->dev, "Lost sync\n"); in tw68_irq_video_done()
1001 dev_err(&dev->pci->dev, "PABORT interrupt\n"); in tw68_irq_video_done()
1003 dev_err(&dev->pci->dev, "DMAPERR interrupt\n"); in tw68_irq_video_done()
1005 * On TW6800, FDMIS is apparently generated if video input is switched in tw68_irq_video_done()
1009 dev_dbg(&dev->pci->dev, "FDMIS interrupt\n"); in tw68_irq_video_done()
1014 dev_dbg(&dev->pci->dev, "FFOF interrupt\n"); in tw68_irq_video_done()
1018 dev_dbg(&dev->pci->dev, "FFERR interrupt\n"); in tw68_irq_video_done()