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 /* ------------------------------------------------------------- */
363 unsigned tot_bufs = q->num_buffers + *num_buffers; in tw68_queue_setup()
364 unsigned size = (dev->fmt->depth * dev->width * dev->height) >> 3; in tw68_queue_setup()
369 *num_buffers = tot_bufs - q->num_buffers; in tw68_queue_setup()
376 return sizes[0] < size ? -EINVAL : 0; in tw68_queue_setup()
400 * The end-result of all this that you only get an interrupt when a buffer
406 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_queue()
412 spin_lock_irqsave(&dev->slock, flags); in tw68_buf_queue()
415 buf->jmp[0] = cpu_to_le32(RISC_JUMP); in tw68_buf_queue()
416 buf->jmp[1] = cpu_to_le32(buf->dma + 8); in tw68_buf_queue()
418 if (!list_empty(&dev->active)) { in tw68_buf_queue()
419 prev = list_entry(dev->active.prev, struct tw68_buf, list); in tw68_buf_queue()
420 buf->cpu[0] |= cpu_to_le32(RISC_INT_BIT); in tw68_buf_queue()
421 prev->jmp[1] = cpu_to_le32(buf->dma); in tw68_buf_queue()
423 list_add_tail(&buf->list, &dev->active); in tw68_buf_queue()
424 spin_unlock_irqrestore(&dev->slock, flags); in tw68_buf_queue()
434 * user - type, width, height and #fields. This is compared with the
436 * code (which controls the filling of the buffer) is (re-)generated.
441 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_prepare()
447 size = (dev->width * dev->height * dev->fmt->depth) >> 3; in tw68_buf_prepare()
449 return -EINVAL; in tw68_buf_prepare()
452 bpl = (dev->width * dev->fmt->depth) >> 3; in tw68_buf_prepare()
453 switch (dev->field) { in tw68_buf_prepare()
455 tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
456 0, UNSET, bpl, 0, dev->height); in tw68_buf_prepare()
459 tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
460 UNSET, 0, bpl, 0, dev->height); in tw68_buf_prepare()
463 tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
464 0, bpl * (dev->height >> 1), in tw68_buf_prepare()
465 bpl, 0, dev->height >> 1); in tw68_buf_prepare()
468 tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
469 bpl * (dev->height >> 1), 0, in tw68_buf_prepare()
470 bpl, 0, dev->height >> 1); in tw68_buf_prepare()
474 tw68_risc_buffer(dev->pci, buf, dma->sgl, in tw68_buf_prepare()
475 0, bpl, bpl, bpl, dev->height >> 1); in tw68_buf_prepare()
484 struct vb2_queue *vq = vb->vb2_queue; in tw68_buf_finish()
488 dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma); in tw68_buf_finish()
495 container_of(dev->active.next, struct tw68_buf, list); in tw68_start_streaming()
497 dev->seqnr = 0; in tw68_start_streaming()
508 while (!list_empty(&dev->active)) { in tw68_stop_streaming()
510 container_of(dev->active.next, struct tw68_buf, list); in tw68_stop_streaming()
512 list_del(&buf->list); in tw68_stop_streaming()
513 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw68_stop_streaming()
528 /* ------------------------------------------------------------------ */
533 container_of(ctrl->handler, struct tw68_dev, hdl); in tw68_s_ctrl()
535 switch (ctrl->id) { in tw68_s_ctrl()
537 tw_writeb(TW68_BRIGHT, ctrl->val); in tw68_s_ctrl()
540 tw_writeb(TW68_HUE, ctrl->val); in tw68_s_ctrl()
543 tw_writeb(TW68_CONTRAST, ctrl->val); in tw68_s_ctrl()
546 tw_writeb(TW68_SAT_U, ctrl->val); in tw68_s_ctrl()
547 tw_writeb(TW68_SAT_V, ctrl->val); in tw68_s_ctrl()
550 if (ctrl->val) in tw68_s_ctrl()
556 if (ctrl->val) in tw68_s_ctrl()
565 /* ------------------------------------------------------------------ */
576 f->fmt.pix.width = dev->width; in tw68_g_fmt_vid_cap()
577 f->fmt.pix.height = dev->height; in tw68_g_fmt_vid_cap()
578 f->fmt.pix.field = dev->field; in tw68_g_fmt_vid_cap()
579 f->fmt.pix.pixelformat = dev->fmt->fourcc; in tw68_g_fmt_vid_cap()
580 f->fmt.pix.bytesperline = in tw68_g_fmt_vid_cap()
581 (f->fmt.pix.width * (dev->fmt->depth)) >> 3; in tw68_g_fmt_vid_cap()
582 f->fmt.pix.sizeimage = in tw68_g_fmt_vid_cap()
583 f->fmt.pix.height * f->fmt.pix.bytesperline; in tw68_g_fmt_vid_cap()
584 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw68_g_fmt_vid_cap()
596 fmt = format_by_fourcc(f->fmt.pix.pixelformat); in tw68_try_fmt_vid_cap()
598 return -EINVAL; in tw68_try_fmt_vid_cap()
600 field = f->fmt.pix.field; in tw68_try_fmt_vid_cap()
601 maxh = (dev->tvnorm->id & V4L2_STD_525_60) ? 480 : 576; in tw68_try_fmt_vid_cap()
613 field = (f->fmt.pix.height > maxh / 2) in tw68_try_fmt_vid_cap()
619 f->fmt.pix.field = field; in tw68_try_fmt_vid_cap()
620 if (f->fmt.pix.width < 48) in tw68_try_fmt_vid_cap()
621 f->fmt.pix.width = 48; in tw68_try_fmt_vid_cap()
622 if (f->fmt.pix.height < 32) in tw68_try_fmt_vid_cap()
623 f->fmt.pix.height = 32; in tw68_try_fmt_vid_cap()
624 if (f->fmt.pix.width > 720) in tw68_try_fmt_vid_cap()
625 f->fmt.pix.width = 720; in tw68_try_fmt_vid_cap()
626 if (f->fmt.pix.height > maxh) in tw68_try_fmt_vid_cap()
627 f->fmt.pix.height = maxh; in tw68_try_fmt_vid_cap()
628 f->fmt.pix.width &= ~0x03; in tw68_try_fmt_vid_cap()
629 f->fmt.pix.bytesperline = in tw68_try_fmt_vid_cap()
630 (f->fmt.pix.width * (fmt->depth)) >> 3; in tw68_try_fmt_vid_cap()
631 f->fmt.pix.sizeimage = in tw68_try_fmt_vid_cap()
632 f->fmt.pix.height * f->fmt.pix.bytesperline; in tw68_try_fmt_vid_cap()
633 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw68_try_fmt_vid_cap()
653 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); in tw68_s_fmt_vid_cap()
654 dev->width = f->fmt.pix.width; in tw68_s_fmt_vid_cap()
655 dev->height = f->fmt.pix.height; in tw68_s_fmt_vid_cap()
656 dev->field = f->fmt.pix.field; in tw68_s_fmt_vid_cap()
666 n = i->index; in tw68_enum_input()
668 return -EINVAL; in tw68_enum_input()
669 i->index = n; in tw68_enum_input()
670 i->type = V4L2_INPUT_TYPE_CAMERA; in tw68_enum_input()
671 snprintf(i->name, sizeof(i->name), "Composite %d", n); in tw68_enum_input()
673 /* If the query is for the current input, get live data */ in tw68_enum_input()
674 if (n == dev->input) { in tw68_enum_input()
679 i->status |= V4L2_IN_ST_NO_SYNC; in tw68_enum_input()
681 i->status |= V4L2_IN_ST_NO_H_LOCK; in tw68_enum_input()
683 i->status |= V4L2_IN_ST_NO_SIGNAL; in tw68_enum_input()
685 i->status |= V4L2_IN_ST_NO_COLOR; in tw68_enum_input()
687 i->status |= V4L2_IN_ST_MACROVISION; in tw68_enum_input()
689 i->std = video_devdata(file)->tvnorms; in tw68_enum_input()
697 *i = dev->input; in tw68_g_input()
706 return -EINVAL; in tw68_s_input()
707 dev->input = i; in tw68_s_input()
708 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input << 2); in tw68_s_input()
715 strscpy(cap->driver, "tw68", sizeof(cap->driver)); in tw68_querycap()
716 strscpy(cap->card, "Techwell Capture Card", in tw68_querycap()
717 sizeof(cap->card)); in tw68_querycap()
726 if (vb2_is_busy(&dev->vidq)) in tw68_s_std()
727 return -EBUSY; in tw68_s_std()
743 return -EINVAL; in tw68_s_std()
753 *id = dev->tvnorm->id; in tw68_g_std()
760 if (f->index >= FORMATS) in tw68_enum_fmt_vid_cap()
761 return -EINVAL; in tw68_enum_fmt_vid_cap()
763 f->pixelformat = formats[f->index].fourcc; in tw68_enum_fmt_vid_cap()
779 /* First we do the PCI regs, 8 4-byte regs per line */ in tw68_dump_regs()
793 /* Next the control regs, which are single-byte, address mod 4 */ in tw68_dump_regs()
826 if (reg->size == 1) in vidioc_g_register()
827 reg->val = tw_readb(reg->reg); in vidioc_g_register()
829 reg->val = tw_readl(reg->reg); in vidioc_g_register()
838 if (reg->size == 1) in vidioc_s_register()
839 tw_writeb(reg->reg, reg->val); in vidioc_s_register()
841 tw_writel(reg->reg & 0xffff, reg->val); in vidioc_s_register()
897 /* ------------------------------------------------------------------ */
901 tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format); in tw68_set_tvnorm_hw()
906 struct v4l2_ctrl_handler *hdl = &dev->hdl; in tw68_video_init1()
910 V4L2_CID_BRIGHTNESS, -128, 127, 1, 20); in tw68_video_init1()
917 V4L2_CID_HUE, -128, 127, 1, 0); in tw68_video_init1()
922 if (hdl->error) { in tw68_video_init1()
924 return hdl->error; in tw68_video_init1()
926 dev->v4l2_dev.ctrl_handler = hdl; in tw68_video_init1()
937 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); in tw68_video_init2()
938 dev->width = 720; in tw68_video_init2()
939 dev->height = 576; in tw68_video_init2()
940 dev->field = V4L2_FIELD_INTERLACED; in tw68_video_init2()
942 INIT_LIST_HEAD(&dev->active); in tw68_video_init2()
943 dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in tw68_video_init2()
944 dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in tw68_video_init2()
945 dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | VB2_DMABUF; in tw68_video_init2()
946 dev->vidq.ops = &tw68_video_qops; in tw68_video_init2()
947 dev->vidq.mem_ops = &vb2_dma_sg_memops; in tw68_video_init2()
948 dev->vidq.drv_priv = dev; in tw68_video_init2()
949 dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in tw68_video_init2()
950 dev->vidq.buf_struct_size = sizeof(struct tw68_buf); in tw68_video_init2()
951 dev->vidq.lock = &dev->lock; in tw68_video_init2()
952 dev->vidq.min_buffers_needed = 2; in tw68_video_init2()
953 dev->vidq.dev = &dev->pci->dev; in tw68_video_init2()
954 ret = vb2_queue_init(&dev->vidq); in tw68_video_init2()
957 dev->vdev = tw68_video_template; in tw68_video_init2()
958 dev->vdev.v4l2_dev = &dev->v4l2_dev; in tw68_video_init2()
959 dev->vdev.lock = &dev->lock; in tw68_video_init2()
960 dev->vdev.queue = &dev->vidq; in tw68_video_init2()
961 video_set_drvdata(&dev->vdev, dev); in tw68_video_init2()
962 return video_register_device(&dev->vdev, VFL_TYPE_VIDEO, video_nr); in tw68_video_init2()
983 spin_lock(&dev->slock); in tw68_irq_video_done()
984 buf = list_entry(dev->active.next, struct tw68_buf, list); in tw68_irq_video_done()
985 list_del(&buf->list); in tw68_irq_video_done()
986 spin_unlock(&dev->slock); in tw68_irq_video_done()
987 buf->vb.vb2_buf.timestamp = ktime_get_ns(); in tw68_irq_video_done()
988 buf->vb.field = dev->field; in tw68_irq_video_done()
989 buf->vb.sequence = dev->seqnr++; in tw68_irq_video_done()
990 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in tw68_irq_video_done()
996 dev_dbg(&dev->pci->dev, "Lost sync\n"); in tw68_irq_video_done()
998 dev_err(&dev->pci->dev, "PABORT interrupt\n"); in tw68_irq_video_done()
1000 dev_err(&dev->pci->dev, "DMAPERR interrupt\n"); in tw68_irq_video_done()
1002 * On TW6800, FDMIS is apparently generated if video input is switched in tw68_irq_video_done()
1006 dev_dbg(&dev->pci->dev, "FDMIS interrupt\n"); in tw68_irq_video_done()
1011 dev_dbg(&dev->pci->dev, "FFOF interrupt\n"); in tw68_irq_video_done()
1015 dev_dbg(&dev->pci->dev, "FFERR interrupt\n"); in tw68_irq_video_done()