Lines Matching +full:min +full:- +full:pix +full:- +full:alignment
1 // SPDX-License-Identifier: GPL-2.0+
3 * A virtual v4l2-mem2mem example device.
5 * This is a virtual device driver for testing mem-to-mem vb2 framework.
9 * The device is capable of multi-instance, multi-buffer-per-transaction
12 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
23 #include <media/v4l2-mem2mem.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-ioctl.h>
26 #include <media/v4l2-ctrls.h>
27 #include <media/v4l2-event.h>
28 #include <media/videobuf2-vmalloc.h>
50 /* Pixel alignment for non-bayer formats */
54 /* Pixel alignment for bayer formats */
74 v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
133 /* Per-queue, driver-specific private data */
157 if (fmt->fourcc == fourcc) in find_format()
232 return container_of(file->private_data, struct vim2m_ctx, fh); in file2ctx()
240 return &ctx->q_data[V4L2_M2M_SRC]; in get_q_data()
242 return &ctx->q_data[V4L2_M2M_DST]; in get_q_data()
266 int x, depth = q_data_out->fmt->depth >> 3; in copy_line()
269 memcpy(dst, src, q_data_out->width * depth); in copy_line()
271 for (x = 0; x < q_data_out->width >> 1; x++) { in copy_line()
273 memcpy(dst + depth, src - depth, depth); in copy_line()
274 src -= depth << 1; in copy_line()
285 struct vim2m_fmt *out = q_data_out->fmt; in copy_two_pixels()
286 struct vim2m_fmt *in = q_data_in->fmt; in copy_two_pixels()
296 switch (in->fourcc) { in copy_two_pixels()
299 u16 pix = le16_to_cpu(*(__le16 *)(src[i])); in copy_two_pixels() local
301 *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07; in copy_two_pixels()
302 *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03; in copy_two_pixels()
303 *b++ = (u8)((pix & 0x1f) << 3) | 0x07; in copy_two_pixels()
308 u16 pix = be16_to_cpu(*(__be16 *)(src[i])); in copy_two_pixels() local
310 *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07; in copy_two_pixels()
311 *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03; in copy_two_pixels()
312 *b++ = (u8)((pix & 0x1f) << 3) | 0x07; in copy_two_pixels()
338 switch (out->fourcc) { in copy_two_pixels()
341 u16 pix; in copy_two_pixels() local
344 pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) | in copy_two_pixels()
347 *dst_pix = cpu_to_le16(pix); in copy_two_pixels()
354 u16 pix; in copy_two_pixels() local
357 pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) | in copy_two_pixels()
360 *dst_pix = cpu_to_be16(pix); in copy_two_pixels()
386 u = ((-4878 * (*r) - 9578 * (*g) + 14456 * (*b) in copy_two_pixels()
388 v = ((14456 * (*r++) - 12105 * (*g++) - 2351 * (*b++) in copy_two_pixels()
443 struct vim2m_dev *dev = ctx->dev; in device_process()
453 bytesperline = (q_data_in->width * q_data_in->fmt->depth) >> 3; in device_process()
454 bytes_per_pixel = q_data_in->fmt->depth >> 3; in device_process()
461 height = q_data_out->height; in device_process()
462 width = q_data_out->width; in device_process()
464 p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0); in device_process()
465 p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0); in device_process()
467 v4l2_err(&dev->v4l2_dev, in device_process()
469 return -EFAULT; in device_process()
472 out_vb->sequence = q_data_out->sequence++; in device_process()
473 in_vb->sequence = q_data_in->sequence++; in device_process()
476 if (ctx->mode & MEM2MEM_VFLIP) { in device_process()
477 start = height - 1; in device_process()
478 end = -1; in device_process()
479 step = -1; in device_process()
491 if (q_data_in->fmt->fourcc == q_data_out->fmt->fourcc && in device_process()
492 q_data_in->width == q_data_out->width && in device_process()
493 q_data_in->height == q_data_out->height) { in device_process()
496 if (ctx->mode & MEM2MEM_HFLIP) in device_process()
497 p += bytesperline - (q_data_in->fmt->depth >> 3); in device_process()
500 ctx->mode & MEM2MEM_HFLIP); in device_process()
510 x_int = q_data_in->width / q_data_out->width; in device_process()
511 x_fract = q_data_in->width % q_data_out->width; in device_process()
514 y_in = (y * q_data_in->height) / q_data_out->height; in device_process()
519 if (ctx->mode & MEM2MEM_HFLIP) in device_process()
520 p_line += bytesperline - (q_data_in->fmt->depth >> 3); in device_process()
528 x_err -= width; in device_process()
531 if (ctx->mode & MEM2MEM_HFLIP) in device_process()
532 p_in_x[1] = p_line - x_offset * bytes_per_pixel; in device_process()
538 ctx->mode & MEM2MEM_HFLIP); in device_process()
545 x_err -= width; in device_process()
548 if (ctx->mode & MEM2MEM_HFLIP) in device_process()
549 p_in_x[0] = p_line - x_offset * bytes_per_pixel; in device_process()
563 * job_ready() - check whether an instance is ready to be scheduled to run
569 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen in job_ready()
570 || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) { in job_ready()
571 dprintk(ctx->dev, 1, "Not enough buffers available\n"); in job_ready()
583 ctx->aborting = 1; in job_abort()
586 /* device_run() - prepares and starts the device
597 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in device_run()
598 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in device_run()
601 v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req, in device_run()
602 &ctx->hdl); in device_run()
607 v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req, in device_run()
608 &ctx->hdl); in device_run()
611 schedule_delayed_work(&ctx->work_run, msecs_to_jiffies(ctx->transtime)); in device_run()
622 vim2m_dev = curr_ctx->dev; in device_work()
624 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); in device_work()
625 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); in device_work()
627 curr_ctx->num_processed++; in device_work()
632 if (curr_ctx->num_processed == curr_ctx->translen in device_work()
633 || curr_ctx->aborting) { in device_work()
634 dprintk(curr_ctx->dev, 2, "Finishing capture buffer fill\n"); in device_work()
635 curr_ctx->num_processed = 0; in device_work()
636 v4l2_m2m_job_finish(vim2m_dev->m2m_dev, curr_ctx->fh.m2m_ctx); in device_work()
648 strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); in vidioc_querycap()
649 strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); in vidioc_querycap()
650 snprintf(cap->bus_info, sizeof(cap->bus_info), in vidioc_querycap()
664 /* index-th format of type type found ? */ in enum_fmt()
665 if (num == f->index) in enum_fmt()
669 * just increment per-type index in enum_fmt()
678 f->pixelformat = fmt->fourcc; in enum_fmt()
683 return -EINVAL; in enum_fmt()
701 if (fsize->index != 0) in vidioc_enum_framesizes()
702 return -EINVAL; in vidioc_enum_framesizes()
704 if (!find_format(fsize->pixel_format)) in vidioc_enum_framesizes()
705 return -EINVAL; in vidioc_enum_framesizes()
707 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in vidioc_enum_framesizes()
708 fsize->stepwise.min_width = MIN_W; in vidioc_enum_framesizes()
709 fsize->stepwise.min_height = MIN_H; in vidioc_enum_framesizes()
710 fsize->stepwise.max_width = MAX_W; in vidioc_enum_framesizes()
711 fsize->stepwise.max_height = MAX_H; in vidioc_enum_framesizes()
713 get_alignment(fsize->pixel_format, in vidioc_enum_framesizes()
714 &fsize->stepwise.step_width, in vidioc_enum_framesizes()
715 &fsize->stepwise.step_height); in vidioc_enum_framesizes()
724 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in vidioc_g_fmt()
726 return -EINVAL; in vidioc_g_fmt()
728 q_data = get_q_data(ctx, f->type); in vidioc_g_fmt()
730 return -EINVAL; in vidioc_g_fmt()
732 f->fmt.pix.width = q_data->width; in vidioc_g_fmt()
733 f->fmt.pix.height = q_data->height; in vidioc_g_fmt()
734 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_g_fmt()
735 f->fmt.pix.pixelformat = q_data->fmt->fourcc; in vidioc_g_fmt()
736 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3; in vidioc_g_fmt()
737 f->fmt.pix.sizeimage = q_data->sizeimage; in vidioc_g_fmt()
738 f->fmt.pix.colorspace = ctx->colorspace; in vidioc_g_fmt()
739 f->fmt.pix.xfer_func = ctx->xfer_func; in vidioc_g_fmt()
740 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in vidioc_g_fmt()
741 f->fmt.pix.quantization = ctx->quant; in vidioc_g_fmt()
765 if (f->fmt.pix.height < MIN_H) in vidioc_try_fmt()
766 f->fmt.pix.height = MIN_H; in vidioc_try_fmt()
767 else if (f->fmt.pix.height > MAX_H) in vidioc_try_fmt()
768 f->fmt.pix.height = MAX_H; in vidioc_try_fmt()
770 if (f->fmt.pix.width < MIN_W) in vidioc_try_fmt()
771 f->fmt.pix.width = MIN_W; in vidioc_try_fmt()
772 else if (f->fmt.pix.width > MAX_W) in vidioc_try_fmt()
773 f->fmt.pix.width = MAX_W; in vidioc_try_fmt()
775 get_alignment(f->fmt.pix.pixelformat, &walign, &halign); in vidioc_try_fmt()
776 f->fmt.pix.width &= ~(walign - 1); in vidioc_try_fmt()
777 f->fmt.pix.height &= ~(halign - 1); in vidioc_try_fmt()
778 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; in vidioc_try_fmt()
779 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; in vidioc_try_fmt()
780 f->fmt.pix.field = V4L2_FIELD_NONE; in vidioc_try_fmt()
791 fmt = find_format(f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_cap()
793 f->fmt.pix.pixelformat = formats[0].fourcc; in vidioc_try_fmt_vid_cap()
794 fmt = find_format(f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_cap()
796 if (!(fmt->types & MEM2MEM_CAPTURE)) { in vidioc_try_fmt_vid_cap()
797 v4l2_err(&ctx->dev->v4l2_dev, in vidioc_try_fmt_vid_cap()
799 f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_cap()
800 return -EINVAL; in vidioc_try_fmt_vid_cap()
802 f->fmt.pix.colorspace = ctx->colorspace; in vidioc_try_fmt_vid_cap()
803 f->fmt.pix.xfer_func = ctx->xfer_func; in vidioc_try_fmt_vid_cap()
804 f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; in vidioc_try_fmt_vid_cap()
805 f->fmt.pix.quantization = ctx->quant; in vidioc_try_fmt_vid_cap()
816 fmt = find_format(f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_out()
818 f->fmt.pix.pixelformat = formats[0].fourcc; in vidioc_try_fmt_vid_out()
819 fmt = find_format(f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_out()
821 if (!(fmt->types & MEM2MEM_OUTPUT)) { in vidioc_try_fmt_vid_out()
822 v4l2_err(&ctx->dev->v4l2_dev, in vidioc_try_fmt_vid_out()
824 f->fmt.pix.pixelformat); in vidioc_try_fmt_vid_out()
825 return -EINVAL; in vidioc_try_fmt_vid_out()
827 if (!f->fmt.pix.colorspace) in vidioc_try_fmt_vid_out()
828 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; in vidioc_try_fmt_vid_out()
838 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in vidioc_s_fmt()
840 return -EINVAL; in vidioc_s_fmt()
842 q_data = get_q_data(ctx, f->type); in vidioc_s_fmt()
844 return -EINVAL; in vidioc_s_fmt()
847 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); in vidioc_s_fmt()
848 return -EBUSY; in vidioc_s_fmt()
851 q_data->fmt = find_format(f->fmt.pix.pixelformat); in vidioc_s_fmt()
852 q_data->width = f->fmt.pix.width; in vidioc_s_fmt()
853 q_data->height = f->fmt.pix.height; in vidioc_s_fmt()
854 q_data->sizeimage = q_data->width * q_data->height in vidioc_s_fmt()
855 * q_data->fmt->depth >> 3; in vidioc_s_fmt()
857 dprintk(ctx->dev, 1, in vidioc_s_fmt()
859 type_name(f->type), q_data->width, q_data->height, in vidioc_s_fmt()
860 q_data->fmt->depth, in vidioc_s_fmt()
861 (q_data->fmt->fourcc & 0xff), in vidioc_s_fmt()
862 (q_data->fmt->fourcc >> 8) & 0xff, in vidioc_s_fmt()
863 (q_data->fmt->fourcc >> 16) & 0xff, in vidioc_s_fmt()
864 (q_data->fmt->fourcc >> 24) & 0xff); in vidioc_s_fmt()
893 ctx->colorspace = f->fmt.pix.colorspace; in vidioc_s_fmt_vid_out()
894 ctx->xfer_func = f->fmt.pix.xfer_func; in vidioc_s_fmt_vid_out()
895 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; in vidioc_s_fmt_vid_out()
896 ctx->quant = f->fmt.pix.quantization; in vidioc_s_fmt_vid_out()
904 container_of(ctrl->handler, struct vim2m_ctx, hdl); in vim2m_s_ctrl()
906 switch (ctrl->id) { in vim2m_s_ctrl()
908 if (ctrl->val) in vim2m_s_ctrl()
909 ctx->mode |= MEM2MEM_HFLIP; in vim2m_s_ctrl()
911 ctx->mode &= ~MEM2MEM_HFLIP; in vim2m_s_ctrl()
915 if (ctrl->val) in vim2m_s_ctrl()
916 ctx->mode |= MEM2MEM_VFLIP; in vim2m_s_ctrl()
918 ctx->mode &= ~MEM2MEM_VFLIP; in vim2m_s_ctrl()
922 ctx->transtime = ctrl->val; in vim2m_s_ctrl()
923 if (ctx->transtime < 1) in vim2m_s_ctrl()
924 ctx->transtime = 1; in vim2m_s_ctrl()
928 ctx->translen = ctrl->val; in vim2m_s_ctrl()
932 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); in vim2m_s_ctrl()
933 return -EINVAL; in vim2m_s_ctrl()
986 q_data = get_q_data(ctx, vq->type); in vim2m_queue_setup()
988 return -EINVAL; in vim2m_queue_setup()
990 size = q_data->width * q_data->height * q_data->fmt->depth >> 3; in vim2m_queue_setup()
993 (count)--; in vim2m_queue_setup()
997 return sizes[0] < size ? -EINVAL : 0; in vim2m_queue_setup()
1002 dprintk(ctx->dev, 1, "%s: get %d buffer(s) of size %d each.\n", in vim2m_queue_setup()
1003 type_name(vq->type), count, size); in vim2m_queue_setup()
1011 struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vim2m_buf_out_validate()
1013 if (vbuf->field == V4L2_FIELD_ANY) in vim2m_buf_out_validate()
1014 vbuf->field = V4L2_FIELD_NONE; in vim2m_buf_out_validate()
1015 if (vbuf->field != V4L2_FIELD_NONE) { in vim2m_buf_out_validate()
1016 dprintk(ctx->dev, 1, "%s field isn't supported\n", __func__); in vim2m_buf_out_validate()
1017 return -EINVAL; in vim2m_buf_out_validate()
1025 struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vim2m_buf_prepare()
1028 dprintk(ctx->dev, 2, "type: %s\n", type_name(vb->vb2_queue->type)); in vim2m_buf_prepare()
1030 q_data = get_q_data(ctx, vb->vb2_queue->type); in vim2m_buf_prepare()
1032 return -EINVAL; in vim2m_buf_prepare()
1033 if (vb2_plane_size(vb, 0) < q_data->sizeimage) { in vim2m_buf_prepare()
1034 dprintk(ctx->dev, 1, in vim2m_buf_prepare()
1037 (long)q_data->sizeimage); in vim2m_buf_prepare()
1038 return -EINVAL; in vim2m_buf_prepare()
1041 vb2_set_plane_payload(vb, 0, q_data->sizeimage); in vim2m_buf_prepare()
1049 struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vim2m_buf_queue()
1051 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in vim2m_buf_queue()
1057 struct vim2m_q_data *q_data = get_q_data(ctx, q->type); in vim2m_start_streaming()
1060 return -EINVAL; in vim2m_start_streaming()
1062 if (V4L2_TYPE_IS_OUTPUT(q->type)) in vim2m_start_streaming()
1063 ctx->aborting = 0; in vim2m_start_streaming()
1065 q_data->sequence = 0; in vim2m_start_streaming()
1074 cancel_delayed_work_sync(&ctx->work_run); in vim2m_stop_streaming()
1077 if (V4L2_TYPE_IS_OUTPUT(q->type)) in vim2m_stop_streaming()
1078 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in vim2m_stop_streaming()
1080 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in vim2m_stop_streaming()
1083 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, in vim2m_stop_streaming()
1084 &ctx->hdl); in vim2m_stop_streaming()
1091 struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in vim2m_buf_request_complete()
1093 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl); in vim2m_buf_request_complete()
1114 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in queue_init()
1115 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in queue_init()
1116 src_vq->drv_priv = ctx; in queue_init()
1117 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
1118 src_vq->ops = &vim2m_qops; in queue_init()
1119 src_vq->mem_ops = &vb2_vmalloc_memops; in queue_init()
1120 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
1121 src_vq->lock = &ctx->vb_mutex; in queue_init()
1122 src_vq->supports_requests = true; in queue_init()
1128 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in queue_init()
1129 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in queue_init()
1130 dst_vq->drv_priv = ctx; in queue_init()
1131 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
1132 dst_vq->ops = &vim2m_qops; in queue_init()
1133 dst_vq->mem_ops = &vb2_vmalloc_memops; in queue_init()
1134 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
1135 dst_vq->lock = &ctx->vb_mutex; in queue_init()
1145 .min = 1,
1156 .min = 1,
1171 if (mutex_lock_interruptible(&dev->dev_mutex)) in vim2m_open()
1172 return -ERESTARTSYS; in vim2m_open()
1175 rc = -ENOMEM; in vim2m_open()
1179 v4l2_fh_init(&ctx->fh, video_devdata(file)); in vim2m_open()
1180 file->private_data = &ctx->fh; in vim2m_open()
1181 ctx->dev = dev; in vim2m_open()
1182 hdl = &ctx->hdl; in vim2m_open()
1190 if (hdl->error) { in vim2m_open()
1191 rc = hdl->error; in vim2m_open()
1196 ctx->fh.ctrl_handler = hdl; in vim2m_open()
1199 ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; in vim2m_open()
1200 ctx->q_data[V4L2_M2M_SRC].width = 640; in vim2m_open()
1201 ctx->q_data[V4L2_M2M_SRC].height = 480; in vim2m_open()
1202 ctx->q_data[V4L2_M2M_SRC].sizeimage = in vim2m_open()
1203 ctx->q_data[V4L2_M2M_SRC].width * in vim2m_open()
1204 ctx->q_data[V4L2_M2M_SRC].height * in vim2m_open()
1205 (ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3); in vim2m_open()
1206 ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC]; in vim2m_open()
1207 ctx->colorspace = V4L2_COLORSPACE_REC709; in vim2m_open()
1209 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); in vim2m_open()
1211 mutex_init(&ctx->vb_mutex); in vim2m_open()
1212 INIT_DELAYED_WORK(&ctx->work_run, device_work); in vim2m_open()
1214 if (IS_ERR(ctx->fh.m2m_ctx)) { in vim2m_open()
1215 rc = PTR_ERR(ctx->fh.m2m_ctx); in vim2m_open()
1218 v4l2_fh_exit(&ctx->fh); in vim2m_open()
1223 v4l2_fh_add(&ctx->fh); in vim2m_open()
1224 atomic_inc(&dev->num_inst); in vim2m_open()
1227 ctx, ctx->fh.m2m_ctx); in vim2m_open()
1230 mutex_unlock(&dev->dev_mutex); in vim2m_open()
1241 v4l2_fh_del(&ctx->fh); in vim2m_release()
1242 v4l2_fh_exit(&ctx->fh); in vim2m_release()
1243 v4l2_ctrl_handler_free(&ctx->hdl); in vim2m_release()
1244 mutex_lock(&dev->dev_mutex); in vim2m_release()
1245 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in vim2m_release()
1246 mutex_unlock(&dev->dev_mutex); in vim2m_release()
1249 atomic_dec(&dev->num_inst); in vim2m_release()
1258 v4l2_device_unregister(&dev->v4l2_dev); in vim2m_device_release()
1259 v4l2_m2m_release(dev->m2m_dev); in vim2m_device_release()
1261 media_device_cleanup(&dev->mdev); in vim2m_device_release()
1280 .minor = -1,
1304 return -ENOMEM; in vim2m_probe()
1306 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); in vim2m_probe()
1310 atomic_set(&dev->num_inst, 0); in vim2m_probe()
1311 mutex_init(&dev->dev_mutex); in vim2m_probe()
1313 dev->vfd = vim2m_videodev; in vim2m_probe()
1314 vfd = &dev->vfd; in vim2m_probe()
1315 vfd->lock = &dev->dev_mutex; in vim2m_probe()
1316 vfd->v4l2_dev = &dev->v4l2_dev; in vim2m_probe()
1319 v4l2_info(&dev->v4l2_dev, in vim2m_probe()
1320 "Device registered as /dev/video%d\n", vfd->num); in vim2m_probe()
1324 dev->m2m_dev = v4l2_m2m_init(&m2m_ops); in vim2m_probe()
1325 if (IS_ERR(dev->m2m_dev)) { in vim2m_probe()
1326 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); in vim2m_probe()
1327 ret = PTR_ERR(dev->m2m_dev); in vim2m_probe()
1328 dev->m2m_dev = NULL; in vim2m_probe()
1333 dev->mdev.dev = &pdev->dev; in vim2m_probe()
1334 strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model)); in vim2m_probe()
1335 strscpy(dev->mdev.bus_info, "platform:vim2m", in vim2m_probe()
1336 sizeof(dev->mdev.bus_info)); in vim2m_probe()
1337 media_device_init(&dev->mdev); in vim2m_probe()
1338 dev->mdev.ops = &m2m_media_ops; in vim2m_probe()
1339 dev->v4l2_dev.mdev = &dev->mdev; in vim2m_probe()
1344 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); in vim2m_probe()
1349 ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, in vim2m_probe()
1352 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); in vim2m_probe()
1356 ret = media_device_register(&dev->mdev); in vim2m_probe()
1358 v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); in vim2m_probe()
1366 v4l2_m2m_unregister_media_controller(dev->m2m_dev); in vim2m_probe()
1369 video_unregister_device(&dev->vfd); in vim2m_probe()
1373 v4l2_m2m_release(dev->m2m_dev); in vim2m_probe()
1375 v4l2_device_unregister(&dev->v4l2_dev); in vim2m_probe()
1386 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); in vim2m_remove()
1389 media_device_unregister(&dev->mdev); in vim2m_remove()
1390 v4l2_m2m_unregister_media_controller(dev->m2m_dev); in vim2m_remove()
1392 video_unregister_device(&dev->vfd); in vim2m_remove()