Lines Matching +full:timer +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2021-2023 Digiteq Automotive
11 * When the device is in loopback mode (a direct, in HW, in->out frame passing
21 #include <linux/v4l2-dv-timings.h>
22 #include <media/v4l2-ioctl.h>
23 #include <media/videobuf2-v4l2.h>
24 #include <media/videobuf2-dma-sg.h>
25 #include <media/v4l2-dv-timings.h>
26 #include <media/v4l2-event.h>
92 voutdev = vindev->mgbdev->vout[i]; in loopback_dev()
96 config = mgb4_read_reg(&voutdev->mgbdev->video, in loopback_dev()
97 voutdev->config->regs.config); in loopback_dev()
98 if ((config & 0xc) >> 2 == vindev->config->id) in loopback_dev()
105 * Check, whether the loopback mode - a HW INPUT->OUTPUT transmission - is
126 struct mgb4_regs *video = &vindev->mgbdev->video; in set_loopback_padding()
133 mgb4_write_reg(video, voutdev->config->regs.padding, in set_loopback_padding()
141 struct mgb4_regs *video = &vindev->mgbdev->video; in get_timings()
142 const struct mgb4_vin_regs *regs = &vindev->config->regs; in get_timings()
144 u32 status = mgb4_read_reg(video, regs->status); in get_timings()
145 u32 pclk = mgb4_read_reg(video, regs->pclk); in get_timings()
146 u32 signal = mgb4_read_reg(video, regs->signal); in get_timings()
147 u32 signal2 = mgb4_read_reg(video, regs->signal2); in get_timings()
148 u32 resolution = mgb4_read_reg(video, regs->resolution); in get_timings()
151 return -ENOLCK; in get_timings()
153 return -ENOLINK; in get_timings()
156 timings->type = V4L2_DV_BT_656_1120; in get_timings()
157 timings->bt.width = resolution >> 16; in get_timings()
158 timings->bt.height = resolution & 0xFFFF; in get_timings()
160 timings->bt.polarities |= V4L2_DV_HSYNC_POS_POL; in get_timings()
162 timings->bt.polarities |= V4L2_DV_VSYNC_POS_POL; in get_timings()
163 timings->bt.pixelclock = pclk * 1000; in get_timings()
164 timings->bt.hsync = (signal & 0x00FF0000) >> 16; in get_timings()
165 timings->bt.vsync = (signal2 & 0x00FF0000) >> 16; in get_timings()
166 timings->bt.hbackporch = (signal & 0x0000FF00) >> 8; in get_timings()
167 timings->bt.hfrontporch = signal & 0x000000FF; in get_timings()
168 timings->bt.vbackporch = (signal2 & 0x0000FF00) >> 8; in get_timings()
169 timings->bt.vfrontporch = signal2 & 0x000000FF; in get_timings()
180 spin_lock_irqsave(&vindev->qlock, flags); in return_all_buffers()
181 list_for_each_entry_safe(buf, node, &vindev->buf_list, list) { in return_all_buffers()
182 vb2_buffer_done(&buf->vb.vb2_buf, state); in return_all_buffers()
183 list_del(&buf->list); in return_all_buffers()
185 spin_unlock_irqrestore(&vindev->qlock, flags); in return_all_buffers()
193 struct mgb4_regs *video = &vindev->mgbdev->video; in queue_setup()
194 u32 config = mgb4_read_reg(video, vindev->config->regs.config); in queue_setup()
196 unsigned int size = (vindev->timings.bt.width + vindev->padding) in queue_setup()
197 * vindev->timings.bt.height * pixelsize; in queue_setup()
204 if (test_bit(0, &vindev->mgbdev->io_reconfig)) in queue_setup()
205 return -EBUSY; in queue_setup()
208 return -EINVAL; in queue_setup()
210 return sizes[0] < size ? -EINVAL : 0; in queue_setup()
222 INIT_LIST_HEAD(&buf->list); in buffer_init()
229 struct mgb4_vin_dev *vindev = vb2_get_drv_priv(vb->vb2_queue); in buffer_prepare()
230 struct mgb4_regs *video = &vindev->mgbdev->video; in buffer_prepare()
231 struct device *dev = &vindev->mgbdev->pdev->dev; in buffer_prepare()
232 u32 config = mgb4_read_reg(video, vindev->config->regs.config); in buffer_prepare()
234 unsigned int size = (vindev->timings.bt.width + vindev->padding) in buffer_prepare()
235 * vindev->timings.bt.height * pixelsize; in buffer_prepare()
240 return -EINVAL; in buffer_prepare()
250 struct mgb4_vin_dev *vindev = vb2_get_drv_priv(vb->vb2_queue); in buffer_queue()
255 spin_lock_irqsave(&vindev->qlock, flags); in buffer_queue()
256 list_add_tail(&buf->list, &vindev->buf_list); in buffer_queue()
257 spin_unlock_irqrestore(&vindev->qlock, flags); in buffer_queue()
263 const struct mgb4_vin_config *config = vindev->config; in stop_streaming()
264 int irq = xdma_get_user_irq(vindev->mgbdev->xdev, config->vin_irq); in stop_streaming()
266 xdma_disable_user_irq(vindev->mgbdev->xdev, irq); in stop_streaming()
270 * the IN->OUT transmission to work! in stop_streaming()
273 mgb4_mask_reg(&vindev->mgbdev->video, config->regs.config, 0x2, in stop_streaming()
276 cancel_work_sync(&vindev->dma_work); in stop_streaming()
283 const struct mgb4_vin_config *config = vindev->config; in start_streaming()
284 int irq = xdma_get_user_irq(vindev->mgbdev->xdev, config->vin_irq); in start_streaming()
286 vindev->sequence = 0; in start_streaming()
292 mgb4_mask_reg(&vindev->mgbdev->video, config->regs.config, 0x2, in start_streaming()
295 xdma_enable_user_irq(vindev->mgbdev->xdev, irq); in start_streaming()
316 mutex_lock(&vindev->lock); in fh_open()
325 if (get_timings(vindev, &vindev->timings) < 0) in fh_open()
326 vindev->timings = cea1080p60; in fh_open()
327 set_loopback_padding(vindev, vindev->padding); in fh_open()
330 mutex_unlock(&vindev->lock); in fh_open()
339 mutex_lock(&vindev->lock); in fh_release()
346 mutex_unlock(&vindev->lock); in fh_release()
364 strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); in vidioc_querycap()
365 strscpy(cap->card, "MGB4 PCIe Card", sizeof(cap->card)); in vidioc_querycap()
374 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_fmt()
376 if (f->index == 0) { in vidioc_enum_fmt()
377 f->pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_enum_fmt()
379 } else if (f->index == 1 && has_yuv(video)) { in vidioc_enum_fmt()
380 f->pixelformat = V4L2_PIX_FMT_YUYV; in vidioc_enum_fmt()
383 return -EINVAL; in vidioc_enum_fmt()
391 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_frameintervals()
393 if (ival->index != 0) in vidioc_enum_frameintervals()
394 return -EINVAL; in vidioc_enum_frameintervals()
395 if (!(ival->pixel_format == V4L2_PIX_FMT_ABGR32 || in vidioc_enum_frameintervals()
396 ((has_yuv(video) && ival->pixel_format == V4L2_PIX_FMT_YUYV)))) in vidioc_enum_frameintervals()
397 return -EINVAL; in vidioc_enum_frameintervals()
398 if (ival->width != vindev->timings.bt.width || in vidioc_enum_frameintervals()
399 ival->height != vindev->timings.bt.height) in vidioc_enum_frameintervals()
400 return -EINVAL; in vidioc_enum_frameintervals()
402 ival->type = V4L2_FRMIVAL_TYPE_STEPWISE; in vidioc_enum_frameintervals()
403 ival->stepwise.max.denominator = MGB4_HW_FREQ; in vidioc_enum_frameintervals()
404 ival->stepwise.max.numerator = 0xFFFFFFFF; in vidioc_enum_frameintervals()
405 ival->stepwise.min.denominator = vindev->timings.bt.pixelclock; in vidioc_enum_frameintervals()
406 ival->stepwise.min.numerator = pixel_size(&vindev->timings); in vidioc_enum_frameintervals()
407 ival->stepwise.step.denominator = MGB4_HW_FREQ; in vidioc_enum_frameintervals()
408 ival->stepwise.step.numerator = 1; in vidioc_enum_frameintervals()
416 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_g_fmt()
417 u32 config = mgb4_read_reg(video, vindev->config->regs.config); in vidioc_g_fmt()
419 f->fmt.pix.width = vindev->timings.bt.width; in vidioc_g_fmt()
420 f->fmt.pix.height = vindev->timings.bt.height; in vidioc_g_fmt()
421 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_g_fmt()
424 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; in vidioc_g_fmt()
426 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; in vidioc_g_fmt()
429 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in vidioc_g_fmt()
431 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_g_fmt()
433 f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 2; in vidioc_g_fmt()
435 f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_g_fmt()
436 f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; in vidioc_g_fmt()
437 f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 4; in vidioc_g_fmt()
439 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; in vidioc_g_fmt()
447 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_try_fmt()
450 f->fmt.pix.width = vindev->timings.bt.width; in vidioc_try_fmt()
451 f->fmt.pix.height = vindev->timings.bt.height; in vidioc_try_fmt()
452 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_try_fmt()
454 if (has_yuv(video) && f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in vidioc_try_fmt()
456 if (!(f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709 || in vidioc_try_fmt()
457 f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M)) in vidioc_try_fmt()
458 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_try_fmt()
461 f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_try_fmt()
462 f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; in vidioc_try_fmt()
465 if (f->fmt.pix.bytesperline > f->fmt.pix.width * pixelsize && in vidioc_try_fmt()
466 f->fmt.pix.bytesperline < f->fmt.pix.width * pixelsize * 2) in vidioc_try_fmt()
467 f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, in vidioc_try_fmt()
470 f->fmt.pix.bytesperline = f->fmt.pix.width * pixelsize; in vidioc_try_fmt()
471 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; in vidioc_try_fmt()
479 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_s_fmt()
482 if (vb2_is_busy(&vindev->queue)) in vidioc_s_fmt()
483 return -EBUSY; in vidioc_s_fmt()
487 config = mgb4_read_reg(video, vindev->config->regs.config); in vidioc_s_fmt()
488 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in vidioc_s_fmt()
492 if (f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709) { in vidioc_s_fmt()
495 } else if (f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M) { in vidioc_s_fmt()
506 mgb4_write_reg(video, vindev->config->regs.config, config); in vidioc_s_fmt()
508 vindev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width in vidioc_s_fmt()
510 mgb4_write_reg(video, vindev->config->regs.padding, vindev->padding); in vidioc_s_fmt()
511 set_loopback_padding(vindev, vindev->padding); in vidioc_s_fmt()
520 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_input()
523 if (i->index != 0) in vidioc_enum_input()
524 return -EINVAL; in vidioc_enum_input()
526 strscpy(i->name, "MGB4", sizeof(i->name)); in vidioc_enum_input()
527 i->type = V4L2_INPUT_TYPE_CAMERA; in vidioc_enum_input()
528 i->capabilities = V4L2_IN_CAP_DV_TIMINGS; in vidioc_enum_input()
529 i->status = 0; in vidioc_enum_input()
531 status = mgb4_read_reg(video, vindev->config->regs.status); in vidioc_enum_input()
533 i->status |= V4L2_IN_ST_NO_SYNC; in vidioc_enum_input()
535 i->status |= V4L2_IN_ST_NO_SIGNAL; in vidioc_enum_input()
545 if (fsize->index != 0 || !(fsize->pixel_format == V4L2_PIX_FMT_ABGR32 || in vidioc_enum_framesizes()
546 fsize->pixel_format == V4L2_PIX_FMT_YUYV)) in vidioc_enum_framesizes()
547 return -EINVAL; in vidioc_enum_framesizes()
549 fsize->discrete.width = vindev->timings.bt.width; in vidioc_enum_framesizes()
550 fsize->discrete.height = vindev->timings.bt.height; in vidioc_enum_framesizes()
551 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in vidioc_enum_framesizes()
558 return (i == 0) ? 0 : -EINVAL; in vidioc_s_input()
571 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_g_parm()
572 struct v4l2_fract *tpf = &parm->parm.output.timeperframe; in vidioc_g_parm()
573 u32 timer; in vidioc_g_parm() local
575 parm->parm.capture.readbuffers = 2; in vidioc_g_parm()
578 timer = mgb4_read_reg(video, vindev->config->regs.timer); in vidioc_g_parm()
579 if (timer < 0xFFFF) { in vidioc_g_parm()
580 tpf->numerator = pixel_size(&vindev->timings); in vidioc_g_parm()
581 tpf->denominator = vindev->timings.bt.pixelclock; in vidioc_g_parm()
583 tpf->numerator = timer; in vidioc_g_parm()
584 tpf->denominator = MGB4_HW_FREQ; in vidioc_g_parm()
587 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in vidioc_g_parm()
597 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_s_parm()
598 struct v4l2_fract *tpf = &parm->parm.output.timeperframe; in vidioc_s_parm()
599 u32 period, timer; in vidioc_s_parm() local
602 timer = tpf->denominator ? in vidioc_s_parm()
603 MGB4_PERIOD(tpf->numerator, tpf->denominator) : 0; in vidioc_s_parm()
604 if (timer) { in vidioc_s_parm()
605 period = MGB4_PERIOD(pixel_size(&vindev->timings), in vidioc_s_parm()
606 vindev->timings.bt.pixelclock); in vidioc_s_parm()
607 if (timer < period) in vidioc_s_parm()
608 timer = 0; in vidioc_s_parm()
611 mgb4_write_reg(video, vindev->config->regs.timer, timer); in vidioc_s_parm()
622 if (timings->bt.width < video_timings_cap.bt.min_width || in vidioc_s_dv_timings()
623 timings->bt.width > video_timings_cap.bt.max_width || in vidioc_s_dv_timings()
624 timings->bt.height < video_timings_cap.bt.min_height || in vidioc_s_dv_timings()
625 timings->bt.height > video_timings_cap.bt.max_height) in vidioc_s_dv_timings()
626 return -EINVAL; in vidioc_s_dv_timings()
627 if (timings->bt.width == vindev->timings.bt.width && in vidioc_s_dv_timings()
628 timings->bt.height == vindev->timings.bt.height) in vidioc_s_dv_timings()
630 if (vb2_is_busy(&vindev->queue)) in vidioc_s_dv_timings()
631 return -EBUSY; in vidioc_s_dv_timings()
633 vindev->timings = *timings; in vidioc_s_dv_timings()
642 *timings = vindev->timings; in vidioc_g_dv_timings()
672 switch (sub->type) { in vidioc_subscribe_event()
715 struct mgb4_regs *video = &vindev->mgbdev->video; in dma_transfer()
716 struct device *dev = &vindev->mgbdev->pdev->dev; in dma_transfer()
722 spin_lock_irqsave(&vindev->qlock, flags); in dma_transfer()
723 if (!list_empty(&vindev->buf_list)) { in dma_transfer()
724 buf = list_first_entry(&vindev->buf_list, in dma_transfer()
726 list_del_init(vindev->buf_list.next); in dma_transfer()
728 spin_unlock_irqrestore(&vindev->qlock, flags); in dma_transfer()
733 addr = mgb4_read_reg(video, vindev->config->regs.address); in dma_transfer()
736 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in dma_transfer()
740 rv = mgb4_dma_transfer(vindev->mgbdev, vindev->config->dma_channel, in dma_transfer()
742 vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0)); in dma_transfer()
745 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in dma_transfer()
747 buf->vb.vb2_buf.timestamp = ktime_get_ns(); in dma_transfer()
748 buf->vb.sequence = vindev->sequence++; in dma_transfer()
749 buf->vb.field = V4L2_FIELD_NONE; in dma_transfer()
750 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in dma_transfer()
758 struct mgb4_regs *video = &vindev->mgbdev->video; in signal_change()
759 struct v4l2_bt_timings *timings = &vindev->timings.bt; in signal_change()
760 struct device *dev = &vindev->mgbdev->pdev->dev; in signal_change()
762 u32 resolution = mgb4_read_reg(video, vindev->config->regs.resolution); in signal_change()
763 u32 width = resolution >> 16; in signal_change() local
766 if (timings->width != width || timings->height != height) { in signal_change()
772 v4l2_event_queue(&vindev->vdev, &ev); in signal_change()
774 if (vb2_is_streaming(&vindev->queue)) in signal_change()
775 vb2_queue_error(&vindev->queue); in signal_change()
778 dev_dbg(dev, "stream changed to %ux%u\n", width, height); in signal_change()
784 struct mgb4_regs *video = &vindev->mgbdev->video; in vin_handler()
786 schedule_work(&vindev->dma_work); in vin_handler()
788 mgb4_write_reg(video, 0xB4, 1U << vindev->config->vin_irq); in vin_handler()
796 struct mgb4_regs *video = &vindev->mgbdev->video; in err_handler()
798 schedule_work(&vindev->err_work); in err_handler()
800 mgb4_write_reg(video, 0xB4, 1U << vindev->config->err_irq); in err_handler()
811 struct device *dev = &vindev->mgbdev->pdev->dev; in deser_init()
813 if (MGB4_IS_GMSL(vindev->mgbdev)) { in deser_init()
825 rv = mgb4_i2c_init(&vindev->deser, vindev->mgbdev->i2c_adap, info, in deser_init()
831 rv = mgb4_i2c_configure(&vindev->deser, values, values_count); in deser_init()
840 mgb4_i2c_free(&vindev->deser); in deser_init()
847 struct mgb4_regs *video = &vindev->mgbdev->video; in fpga_init()
848 const struct mgb4_vin_regs *regs = &vindev->config->regs; in fpga_init()
850 mgb4_write_reg(video, regs->config, 0x00000001); in fpga_init()
851 mgb4_write_reg(video, regs->sync, 0x03E80002); in fpga_init()
852 mgb4_write_reg(video, regs->padding, 0x00000000); in fpga_init()
853 mgb4_write_reg(video, regs->config, 1U << 9); in fpga_init()
859 struct mgb4_regs *video = &vindev->mgbdev->video; in debugfs_init()
861 vindev->debugfs = debugfs_create_dir(vindev->vdev.name, in debugfs_init()
862 vindev->mgbdev->debugfs); in debugfs_init()
863 if (!vindev->debugfs) in debugfs_init()
866 vindev->regs[0].name = "CONFIG"; in debugfs_init()
867 vindev->regs[0].offset = vindev->config->regs.config; in debugfs_init()
868 vindev->regs[1].name = "STATUS"; in debugfs_init()
869 vindev->regs[1].offset = vindev->config->regs.status; in debugfs_init()
870 vindev->regs[2].name = "RESOLUTION"; in debugfs_init()
871 vindev->regs[2].offset = vindev->config->regs.resolution; in debugfs_init()
872 vindev->regs[3].name = "FRAME_PERIOD"; in debugfs_init()
873 vindev->regs[3].offset = vindev->config->regs.frame_period; in debugfs_init()
874 vindev->regs[4].name = "HS_VS_GENER_SETTINGS"; in debugfs_init()
875 vindev->regs[4].offset = vindev->config->regs.sync; in debugfs_init()
876 vindev->regs[5].name = "PCLK_FREQUENCY"; in debugfs_init()
877 vindev->regs[5].offset = vindev->config->regs.pclk; in debugfs_init()
878 vindev->regs[6].name = "VIDEO_PARAMS_1"; in debugfs_init()
879 vindev->regs[6].offset = vindev->config->regs.signal; in debugfs_init()
880 vindev->regs[7].name = "VIDEO_PARAMS_2"; in debugfs_init()
881 vindev->regs[7].offset = vindev->config->regs.signal2; in debugfs_init()
882 vindev->regs[8].name = "PADDING_PIXELS"; in debugfs_init()
883 vindev->regs[8].offset = vindev->config->regs.padding; in debugfs_init()
885 vindev->regs[9].name = "TIMER"; in debugfs_init()
886 vindev->regs[9].offset = vindev->config->regs.timer; in debugfs_init()
887 vindev->regset.nregs = 10; in debugfs_init()
889 vindev->regset.nregs = 9; in debugfs_init()
892 vindev->regset.base = video->membase; in debugfs_init()
893 vindev->regset.regs = vindev->regs; in debugfs_init()
895 debugfs_create_regset32("registers", 0444, vindev->debugfs, in debugfs_init()
896 &vindev->regset); in debugfs_init()
905 struct pci_dev *pdev = mgbdev->pdev; in mgb4_vin_create()
906 struct device *dev = &pdev->dev; in mgb4_vin_create()
913 vindev->mgbdev = mgbdev; in mgb4_vin_create()
914 vindev->config = &vin_cfg[id]; in mgb4_vin_create()
917 INIT_LIST_HEAD(&vindev->buf_list); in mgb4_vin_create()
918 spin_lock_init(&vindev->qlock); in mgb4_vin_create()
921 INIT_WORK(&vindev->dma_work, dma_transfer); in mgb4_vin_create()
922 INIT_WORK(&vindev->err_work, signal_change); in mgb4_vin_create()
925 vin_irq = xdma_get_user_irq(mgbdev->xdev, vindev->config->vin_irq); in mgb4_vin_create()
926 rv = request_irq(vin_irq, vin_handler, 0, "mgb4-vin", vindev); in mgb4_vin_create()
932 err_irq = xdma_get_user_irq(mgbdev->xdev, vindev->config->err_irq); in mgb4_vin_create()
933 rv = request_irq(err_irq, err_handler, 0, "mgb4-err", vindev); in mgb4_vin_create()
948 rv = v4l2_device_register(dev, &vindev->v4l2dev); in mgb4_vin_create()
954 mutex_init(&vindev->lock); in mgb4_vin_create()
956 vindev->queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in mgb4_vin_create()
957 vindev->queue.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; in mgb4_vin_create()
958 vindev->queue.buf_struct_size = sizeof(struct mgb4_frame_buffer); in mgb4_vin_create()
959 vindev->queue.ops = &queue_ops; in mgb4_vin_create()
960 vindev->queue.mem_ops = &vb2_dma_sg_memops; in mgb4_vin_create()
961 vindev->queue.gfp_flags = GFP_DMA32; in mgb4_vin_create()
962 vindev->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in mgb4_vin_create()
963 vindev->queue.min_queued_buffers = 2; in mgb4_vin_create()
964 vindev->queue.drv_priv = vindev; in mgb4_vin_create()
965 vindev->queue.lock = &vindev->lock; in mgb4_vin_create()
966 vindev->queue.dev = dev; in mgb4_vin_create()
967 rv = vb2_queue_init(&vindev->queue); in mgb4_vin_create()
973 snprintf(vindev->vdev.name, sizeof(vindev->vdev.name), "mgb4-in%d", in mgb4_vin_create()
975 vindev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE in mgb4_vin_create()
977 vindev->vdev.fops = &video_fops; in mgb4_vin_create()
978 vindev->vdev.ioctl_ops = &video_ioctl_ops; in mgb4_vin_create()
979 vindev->vdev.release = video_device_release_empty; in mgb4_vin_create()
980 vindev->vdev.v4l2_dev = &vindev->v4l2dev; in mgb4_vin_create()
981 vindev->vdev.lock = &vindev->lock; in mgb4_vin_create()
982 vindev->vdev.queue = &vindev->queue; in mgb4_vin_create()
983 video_set_drvdata(&vindev->vdev, vindev); in mgb4_vin_create()
986 xdma_enable_user_irq(vindev->mgbdev->xdev, err_irq); in mgb4_vin_create()
989 rv = video_register_device(&vindev->vdev, VFL_TYPE_VIDEO, -1); in mgb4_vin_create()
998 rv = device_add_groups(&vindev->vdev.dev, groups); in mgb4_vin_create()
1011 video_unregister_device(&vindev->vdev); in mgb4_vin_create()
1013 v4l2_device_unregister(&vindev->v4l2dev); in mgb4_vin_create()
1027 int vin_irq = xdma_get_user_irq(vindev->mgbdev->xdev, in mgb4_vin_free()
1028 vindev->config->vin_irq); in mgb4_vin_free()
1029 int err_irq = xdma_get_user_irq(vindev->mgbdev->xdev, in mgb4_vin_free()
1030 vindev->config->err_irq); in mgb4_vin_free()
1032 xdma_disable_user_irq(vindev->mgbdev->xdev, err_irq); in mgb4_vin_free()
1038 debugfs_remove_recursive(vindev->debugfs); in mgb4_vin_free()
1041 groups = MGB4_IS_GMSL(vindev->mgbdev) in mgb4_vin_free()
1043 device_remove_groups(&vindev->vdev.dev, groups); in mgb4_vin_free()
1045 mgb4_i2c_free(&vindev->deser); in mgb4_vin_free()
1046 video_unregister_device(&vindev->vdev); in mgb4_vin_free()
1047 v4l2_device_unregister(&vindev->v4l2dev); in mgb4_vin_free()