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 hsync = mgb4_read_reg(video, regs->hsync); in get_timings()
147 u32 vsync = mgb4_read_reg(video, regs->vsync); 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 = (hsync & 0x00FF0000) >> 16; in get_timings()
165 timings->bt.vsync = (vsync & 0x00FF0000) >> 16; in get_timings()
166 timings->bt.hbackporch = (hsync & 0x0000FF00) >> 8; in get_timings()
167 timings->bt.hfrontporch = hsync & 0x000000FF; in get_timings()
168 timings->bt.vbackporch = (vsync & 0x0000FF00) >> 8; in get_timings()
169 timings->bt.vfrontporch = vsync & 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 struct mgb4_regs *video = &vindev->mgbdev->video; in stop_streaming()
264 const struct mgb4_vin_config *config = vindev->config; in stop_streaming()
265 int irq = xdma_get_user_irq(vindev->mgbdev->xdev, config->vin_irq); in stop_streaming()
267 xdma_disable_user_irq(vindev->mgbdev->xdev, irq); in stop_streaming()
271 * the IN->OUT transmission to work! in stop_streaming()
274 mgb4_mask_reg(&vindev->mgbdev->video, config->regs.config, 0x2, in stop_streaming()
277 mgb4_write_reg(video, vindev->config->regs.padding, 0); in stop_streaming()
280 cancel_work_sync(&vindev->dma_work); in stop_streaming()
287 struct mgb4_regs *video = &vindev->mgbdev->video; in start_streaming()
288 const struct mgb4_vin_config *config = vindev->config; in start_streaming()
289 int irq = xdma_get_user_irq(vindev->mgbdev->xdev, config->vin_irq); in start_streaming()
291 vindev->sequence = 0; in start_streaming()
297 mgb4_mask_reg(&vindev->mgbdev->video, config->regs.config, 0x2, in start_streaming()
300 mgb4_write_reg(video, vindev->config->regs.padding, vindev->padding); in start_streaming()
301 set_loopback_padding(vindev, vindev->padding); in start_streaming()
303 xdma_enable_user_irq(vindev->mgbdev->xdev, irq); in start_streaming()
322 mutex_lock(&vindev->lock); in fh_open()
331 if (get_timings(vindev, &vindev->timings) < 0) in fh_open()
332 vindev->timings = cea1080p60; in fh_open()
335 mutex_unlock(&vindev->lock); in fh_open()
352 strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); in vidioc_querycap()
353 strscpy(cap->card, "MGB4 PCIe Card", sizeof(cap->card)); in vidioc_querycap()
362 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_fmt()
364 if (f->index == 0) { in vidioc_enum_fmt()
365 f->pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_enum_fmt()
367 } else if (f->index == 1 && has_yuv(video)) { in vidioc_enum_fmt()
368 f->pixelformat = V4L2_PIX_FMT_YUYV; in vidioc_enum_fmt()
371 return -EINVAL; in vidioc_enum_fmt()
379 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_frameintervals()
381 if (ival->index != 0) in vidioc_enum_frameintervals()
382 return -EINVAL; in vidioc_enum_frameintervals()
383 if (!(ival->pixel_format == V4L2_PIX_FMT_ABGR32 || in vidioc_enum_frameintervals()
384 ((has_yuv(video) && ival->pixel_format == V4L2_PIX_FMT_YUYV)))) in vidioc_enum_frameintervals()
385 return -EINVAL; in vidioc_enum_frameintervals()
386 if (ival->width != vindev->timings.bt.width || in vidioc_enum_frameintervals()
387 ival->height != vindev->timings.bt.height) in vidioc_enum_frameintervals()
388 return -EINVAL; in vidioc_enum_frameintervals()
390 ival->type = V4L2_FRMIVAL_TYPE_STEPWISE; in vidioc_enum_frameintervals()
391 ival->stepwise.max.denominator = MGB4_HW_FREQ; in vidioc_enum_frameintervals()
392 ival->stepwise.max.numerator = 0xFFFFFFFF; in vidioc_enum_frameintervals()
393 ival->stepwise.min.denominator = vindev->timings.bt.pixelclock; in vidioc_enum_frameintervals()
394 ival->stepwise.min.numerator = pixel_size(&vindev->timings); in vidioc_enum_frameintervals()
395 ival->stepwise.step.denominator = MGB4_HW_FREQ; in vidioc_enum_frameintervals()
396 ival->stepwise.step.numerator = 1; in vidioc_enum_frameintervals()
404 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_g_fmt()
405 u32 config = mgb4_read_reg(video, vindev->config->regs.config); in vidioc_g_fmt()
407 f->fmt.pix.width = vindev->timings.bt.width; in vidioc_g_fmt()
408 f->fmt.pix.height = vindev->timings.bt.height; in vidioc_g_fmt()
409 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_g_fmt()
412 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; in vidioc_g_fmt()
414 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; in vidioc_g_fmt()
417 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in vidioc_g_fmt()
419 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_g_fmt()
421 f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 2; in vidioc_g_fmt()
423 f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_g_fmt()
424 f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; in vidioc_g_fmt()
425 f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 4; in vidioc_g_fmt()
427 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; in vidioc_g_fmt()
435 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_try_fmt()
438 f->fmt.pix.width = vindev->timings.bt.width; in vidioc_try_fmt()
439 f->fmt.pix.height = vindev->timings.bt.height; in vidioc_try_fmt()
440 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_try_fmt()
442 if (has_yuv(video) && f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in vidioc_try_fmt()
444 if (!(f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709 || in vidioc_try_fmt()
445 f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M)) in vidioc_try_fmt()
446 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_try_fmt()
449 f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; in vidioc_try_fmt()
450 f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; in vidioc_try_fmt()
453 if (f->fmt.pix.bytesperline > f->fmt.pix.width * pixelsize && in vidioc_try_fmt()
454 f->fmt.pix.bytesperline < f->fmt.pix.width * pixelsize * 2) in vidioc_try_fmt()
455 f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, in vidioc_try_fmt()
458 f->fmt.pix.bytesperline = f->fmt.pix.width * pixelsize; in vidioc_try_fmt()
459 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; in vidioc_try_fmt()
467 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_s_fmt()
470 if (vb2_is_busy(&vindev->queue)) in vidioc_s_fmt()
471 return -EBUSY; in vidioc_s_fmt()
475 config = mgb4_read_reg(video, vindev->config->regs.config); in vidioc_s_fmt()
476 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { in vidioc_s_fmt()
480 if (f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709) { in vidioc_s_fmt()
483 } else if (f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M) { in vidioc_s_fmt()
494 mgb4_write_reg(video, vindev->config->regs.config, config); in vidioc_s_fmt()
496 vindev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width in vidioc_s_fmt()
506 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_enum_input()
509 if (i->index != 0) in vidioc_enum_input()
510 return -EINVAL; in vidioc_enum_input()
512 strscpy(i->name, "MGB4", sizeof(i->name)); in vidioc_enum_input()
513 i->type = V4L2_INPUT_TYPE_CAMERA; in vidioc_enum_input()
514 i->capabilities = V4L2_IN_CAP_DV_TIMINGS; in vidioc_enum_input()
515 i->status = 0; in vidioc_enum_input()
517 status = mgb4_read_reg(video, vindev->config->regs.status); in vidioc_enum_input()
519 i->status |= V4L2_IN_ST_NO_SYNC; in vidioc_enum_input()
521 i->status |= V4L2_IN_ST_NO_SIGNAL; in vidioc_enum_input()
531 if (fsize->index != 0 || !(fsize->pixel_format == V4L2_PIX_FMT_ABGR32 || in vidioc_enum_framesizes()
532 fsize->pixel_format == V4L2_PIX_FMT_YUYV)) in vidioc_enum_framesizes()
533 return -EINVAL; in vidioc_enum_framesizes()
535 fsize->discrete.width = vindev->timings.bt.width; in vidioc_enum_framesizes()
536 fsize->discrete.height = vindev->timings.bt.height; in vidioc_enum_framesizes()
537 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in vidioc_enum_framesizes()
544 return (i == 0) ? 0 : -EINVAL; in vidioc_s_input()
557 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_g_parm()
558 struct v4l2_fract *tpf = &parm->parm.output.timeperframe; in vidioc_g_parm()
559 u32 timer; in vidioc_g_parm() local
561 parm->parm.capture.readbuffers = 2; in vidioc_g_parm()
564 timer = mgb4_read_reg(video, vindev->config->regs.timer); in vidioc_g_parm()
565 if (timer < 0xFFFF) { in vidioc_g_parm()
566 tpf->numerator = pixel_size(&vindev->timings); in vidioc_g_parm()
567 tpf->denominator = vindev->timings.bt.pixelclock; in vidioc_g_parm()
569 tpf->numerator = timer; in vidioc_g_parm()
570 tpf->denominator = MGB4_HW_FREQ; in vidioc_g_parm()
573 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; in vidioc_g_parm()
583 struct mgb4_regs *video = &vindev->mgbdev->video; in vidioc_s_parm()
584 struct v4l2_fract *tpf = &parm->parm.output.timeperframe; in vidioc_s_parm()
585 u32 period, timer; in vidioc_s_parm() local
588 timer = tpf->denominator ? in vidioc_s_parm()
589 MGB4_PERIOD(tpf->numerator, tpf->denominator) : 0; in vidioc_s_parm()
590 if (timer) { in vidioc_s_parm()
591 period = MGB4_PERIOD(pixel_size(&vindev->timings), in vidioc_s_parm()
592 vindev->timings.bt.pixelclock); in vidioc_s_parm()
593 if (timer < period) in vidioc_s_parm()
594 timer = 0; in vidioc_s_parm()
597 mgb4_write_reg(video, vindev->config->regs.timer, timer); in vidioc_s_parm()
608 if (timings->bt.width < video_timings_cap.bt.min_width || in vidioc_s_dv_timings()
609 timings->bt.width > video_timings_cap.bt.max_width || in vidioc_s_dv_timings()
610 timings->bt.height < video_timings_cap.bt.min_height || in vidioc_s_dv_timings()
611 timings->bt.height > video_timings_cap.bt.max_height) in vidioc_s_dv_timings()
612 return -EINVAL; in vidioc_s_dv_timings()
613 if (timings->bt.width == vindev->timings.bt.width && in vidioc_s_dv_timings()
614 timings->bt.height == vindev->timings.bt.height) in vidioc_s_dv_timings()
616 if (vb2_is_busy(&vindev->queue)) in vidioc_s_dv_timings()
617 return -EBUSY; in vidioc_s_dv_timings()
619 vindev->timings = *timings; in vidioc_s_dv_timings()
628 *timings = vindev->timings; in vidioc_g_dv_timings()
658 switch (sub->type) { in vidioc_subscribe_event()
701 struct mgb4_regs *video = &vindev->mgbdev->video; in dma_transfer()
702 struct device *dev = &vindev->mgbdev->pdev->dev; in dma_transfer()
708 spin_lock_irqsave(&vindev->qlock, flags); in dma_transfer()
709 if (!list_empty(&vindev->buf_list)) { in dma_transfer()
710 buf = list_first_entry(&vindev->buf_list, in dma_transfer()
712 list_del_init(vindev->buf_list.next); in dma_transfer()
714 spin_unlock_irqrestore(&vindev->qlock, flags); in dma_transfer()
719 addr = mgb4_read_reg(video, vindev->config->regs.address); in dma_transfer()
722 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in dma_transfer()
726 rv = mgb4_dma_transfer(vindev->mgbdev, vindev->config->dma_channel, in dma_transfer()
728 vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0)); in dma_transfer()
731 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in dma_transfer()
733 buf->vb.vb2_buf.timestamp = ktime_get_ns(); in dma_transfer()
734 buf->vb.sequence = vindev->sequence++; in dma_transfer()
735 buf->vb.field = V4L2_FIELD_NONE; in dma_transfer()
736 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in dma_transfer()
744 struct mgb4_regs *video = &vindev->mgbdev->video; in signal_change()
745 struct v4l2_bt_timings *timings = &vindev->timings.bt; in signal_change()
746 struct device *dev = &vindev->mgbdev->pdev->dev; in signal_change()
748 u32 resolution = mgb4_read_reg(video, vindev->config->regs.resolution); in signal_change()
749 u32 width = resolution >> 16; in signal_change() local
752 if (timings->width != width || timings->height != height) { in signal_change()
758 v4l2_event_queue(&vindev->vdev, &ev); in signal_change()
760 if (vb2_is_streaming(&vindev->queue)) in signal_change()
761 vb2_queue_error(&vindev->queue); in signal_change()
764 dev_dbg(dev, "stream changed to %ux%u\n", width, height); in signal_change()
770 struct mgb4_regs *video = &vindev->mgbdev->video; in vin_handler()
772 schedule_work(&vindev->dma_work); in vin_handler()
774 mgb4_write_reg(video, 0xB4, 1U << vindev->config->vin_irq); in vin_handler()
782 struct mgb4_regs *video = &vindev->mgbdev->video; in err_handler()
784 schedule_work(&vindev->err_work); in err_handler()
786 mgb4_write_reg(video, 0xB4, 1U << vindev->config->err_irq); in err_handler()
797 struct device *dev = &vindev->mgbdev->pdev->dev; in deser_init()
799 if (MGB4_IS_GMSL(vindev->mgbdev)) { in deser_init()
811 rv = mgb4_i2c_init(&vindev->deser, vindev->mgbdev->i2c_adap, info, in deser_init()
817 rv = mgb4_i2c_configure(&vindev->deser, values, values_count); in deser_init()
826 mgb4_i2c_free(&vindev->deser); in deser_init()
833 struct mgb4_regs *video = &vindev->mgbdev->video; in fpga_init()
834 const struct mgb4_vin_regs *regs = &vindev->config->regs; in fpga_init()
836 mgb4_write_reg(video, regs->config, 0x00000001); in fpga_init()
837 mgb4_write_reg(video, regs->sync, 0x03E80002); in fpga_init()
838 mgb4_write_reg(video, regs->padding, 0x00000000); in fpga_init()
839 mgb4_write_reg(video, regs->config, 1U << 9); in fpga_init()
845 struct mgb4_regs *video = &vindev->mgbdev->video; in create_debugfs()
848 if (IS_ERR_OR_NULL(vindev->mgbdev->debugfs)) in create_debugfs()
850 entry = debugfs_create_dir(vindev->vdev.name, vindev->mgbdev->debugfs); in create_debugfs()
854 vindev->regs[0].name = "CONFIG"; in create_debugfs()
855 vindev->regs[0].offset = vindev->config->regs.config; in create_debugfs()
856 vindev->regs[1].name = "STATUS"; in create_debugfs()
857 vindev->regs[1].offset = vindev->config->regs.status; in create_debugfs()
858 vindev->regs[2].name = "RESOLUTION"; in create_debugfs()
859 vindev->regs[2].offset = vindev->config->regs.resolution; in create_debugfs()
860 vindev->regs[3].name = "FRAME_PERIOD"; in create_debugfs()
861 vindev->regs[3].offset = vindev->config->regs.frame_period; in create_debugfs()
862 vindev->regs[4].name = "HS_VS_GENER_SETTINGS"; in create_debugfs()
863 vindev->regs[4].offset = vindev->config->regs.sync; in create_debugfs()
864 vindev->regs[5].name = "PCLK_FREQUENCY"; in create_debugfs()
865 vindev->regs[5].offset = vindev->config->regs.pclk; in create_debugfs()
866 vindev->regs[6].name = "VIDEO_PARAMS_1"; in create_debugfs()
867 vindev->regs[6].offset = vindev->config->regs.hsync; in create_debugfs()
868 vindev->regs[7].name = "VIDEO_PARAMS_2"; in create_debugfs()
869 vindev->regs[7].offset = vindev->config->regs.vsync; in create_debugfs()
870 vindev->regs[8].name = "PADDING_PIXELS"; in create_debugfs()
871 vindev->regs[8].offset = vindev->config->regs.padding; in create_debugfs()
873 vindev->regs[9].name = "TIMER"; in create_debugfs()
874 vindev->regs[9].offset = vindev->config->regs.timer; in create_debugfs()
875 vindev->regset.nregs = 10; in create_debugfs()
877 vindev->regset.nregs = 9; in create_debugfs()
880 vindev->regset.base = video->membase; in create_debugfs()
881 vindev->regset.regs = vindev->regs; in create_debugfs()
883 debugfs_create_regset32("registers", 0444, entry, &vindev->regset); in create_debugfs()
892 struct pci_dev *pdev = mgbdev->pdev; in mgb4_vin_create()
893 struct device *dev = &pdev->dev; in mgb4_vin_create()
900 vindev->mgbdev = mgbdev; in mgb4_vin_create()
901 vindev->config = &vin_cfg[id]; in mgb4_vin_create()
904 INIT_LIST_HEAD(&vindev->buf_list); in mgb4_vin_create()
905 spin_lock_init(&vindev->qlock); in mgb4_vin_create()
908 INIT_WORK(&vindev->dma_work, dma_transfer); in mgb4_vin_create()
909 INIT_WORK(&vindev->err_work, signal_change); in mgb4_vin_create()
912 vin_irq = xdma_get_user_irq(mgbdev->xdev, vindev->config->vin_irq); in mgb4_vin_create()
913 rv = request_irq(vin_irq, vin_handler, 0, "mgb4-vin", vindev); in mgb4_vin_create()
919 err_irq = xdma_get_user_irq(mgbdev->xdev, vindev->config->err_irq); in mgb4_vin_create()
920 rv = request_irq(err_irq, err_handler, 0, "mgb4-err", vindev); in mgb4_vin_create()
935 rv = v4l2_device_register(dev, &vindev->v4l2dev); in mgb4_vin_create()
941 mutex_init(&vindev->lock); in mgb4_vin_create()
943 vindev->queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in mgb4_vin_create()
944 vindev->queue.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; in mgb4_vin_create()
945 vindev->queue.buf_struct_size = sizeof(struct mgb4_frame_buffer); in mgb4_vin_create()
946 vindev->queue.ops = &queue_ops; in mgb4_vin_create()
947 vindev->queue.mem_ops = &vb2_dma_sg_memops; in mgb4_vin_create()
948 vindev->queue.gfp_flags = GFP_DMA32; in mgb4_vin_create()
949 vindev->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in mgb4_vin_create()
950 vindev->queue.min_queued_buffers = 2; in mgb4_vin_create()
951 vindev->queue.drv_priv = vindev; in mgb4_vin_create()
952 vindev->queue.lock = &vindev->lock; in mgb4_vin_create()
953 vindev->queue.dev = dev; in mgb4_vin_create()
954 rv = vb2_queue_init(&vindev->queue); in mgb4_vin_create()
960 snprintf(vindev->vdev.name, sizeof(vindev->vdev.name), "mgb4-in%d", in mgb4_vin_create()
962 vindev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE in mgb4_vin_create()
964 vindev->vdev.fops = &video_fops; in mgb4_vin_create()
965 vindev->vdev.ioctl_ops = &video_ioctl_ops; in mgb4_vin_create()
966 vindev->vdev.release = video_device_release_empty; in mgb4_vin_create()
967 vindev->vdev.v4l2_dev = &vindev->v4l2dev; in mgb4_vin_create()
968 vindev->vdev.lock = &vindev->lock; in mgb4_vin_create()
969 vindev->vdev.queue = &vindev->queue; in mgb4_vin_create()
970 video_set_drvdata(&vindev->vdev, vindev); in mgb4_vin_create()
973 xdma_enable_user_irq(vindev->mgbdev->xdev, err_irq); in mgb4_vin_create()
976 rv = video_register_device(&vindev->vdev, VFL_TYPE_VIDEO, -1); in mgb4_vin_create()
985 rv = device_add_groups(&vindev->vdev.dev, groups); in mgb4_vin_create()
996 video_unregister_device(&vindev->vdev); in mgb4_vin_create()
998 v4l2_device_unregister(&vindev->v4l2dev); in mgb4_vin_create()
1012 int vin_irq = xdma_get_user_irq(vindev->mgbdev->xdev, in mgb4_vin_free()
1013 vindev->config->vin_irq); in mgb4_vin_free()
1014 int err_irq = xdma_get_user_irq(vindev->mgbdev->xdev, in mgb4_vin_free()
1015 vindev->config->err_irq); in mgb4_vin_free()
1017 xdma_disable_user_irq(vindev->mgbdev->xdev, err_irq); in mgb4_vin_free()
1022 groups = MGB4_IS_GMSL(vindev->mgbdev) in mgb4_vin_free()
1024 device_remove_groups(&vindev->vdev.dev, groups); in mgb4_vin_free()
1026 mgb4_i2c_free(&vindev->deser); in mgb4_vin_free()
1027 video_unregister_device(&vindev->vdev); in mgb4_vin_free()
1028 v4l2_device_unregister(&vindev->v4l2dev); in mgb4_vin_free()