1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/pm_runtime.h> 7 #include <media/v4l2-event.h> 8 #include <media/v4l2-ioctl.h> 9 #include <media/v4l2-mem2mem.h> 10 #include <media/videobuf2-dma-contig.h> 11 12 #include "iris_vidc.h" 13 #include "iris_instance.h" 14 #include "iris_vdec.h" 15 #include "iris_venc.h" 16 #include "iris_vb2.h" 17 #include "iris_vpu_buffer.h" 18 #include "iris_platform_common.h" 19 20 #define IRIS_DRV_NAME "iris_driver" 21 #define IRIS_BUS_NAME "platform:iris_icc" 22 #define STEP_WIDTH 1 23 #define STEP_HEIGHT 1 24 25 static void iris_v4l2_fh_init(struct iris_inst *inst, struct file *filp) 26 { 27 if (inst->domain == ENCODER) 28 v4l2_fh_init(&inst->fh, inst->core->vdev_enc); 29 else if (inst->domain == DECODER) 30 v4l2_fh_init(&inst->fh, inst->core->vdev_dec); 31 inst->fh.ctrl_handler = &inst->ctrl_handler; 32 v4l2_fh_add(&inst->fh, filp); 33 } 34 35 static void iris_v4l2_fh_deinit(struct iris_inst *inst, struct file *filp) 36 { 37 v4l2_fh_del(&inst->fh, filp); 38 inst->fh.ctrl_handler = NULL; 39 v4l2_fh_exit(&inst->fh); 40 } 41 42 static void iris_add_session(struct iris_inst *inst) 43 { 44 struct iris_core *core = inst->core; 45 struct iris_inst *iter; 46 u32 count = 0; 47 48 mutex_lock(&core->lock); 49 50 list_for_each_entry(iter, &core->instances, list) 51 count++; 52 53 if (count < core->iris_platform_data->max_session_count) 54 list_add_tail(&inst->list, &core->instances); 55 56 mutex_unlock(&core->lock); 57 } 58 59 static void iris_remove_session(struct iris_inst *inst) 60 { 61 struct iris_core *core = inst->core; 62 struct iris_inst *iter, *temp; 63 64 mutex_lock(&core->lock); 65 list_for_each_entry_safe(iter, temp, &core->instances, list) { 66 if (iter->session_id == inst->session_id) { 67 list_del_init(&iter->list); 68 break; 69 } 70 } 71 mutex_unlock(&core->lock); 72 } 73 74 static inline struct iris_inst *iris_get_inst(struct file *filp) 75 { 76 return container_of(file_to_v4l2_fh(filp), struct iris_inst, fh); 77 } 78 79 static void iris_m2m_device_run(void *priv) 80 { 81 } 82 83 static void iris_m2m_job_abort(void *priv) 84 { 85 struct iris_inst *inst = priv; 86 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 87 88 v4l2_m2m_job_finish(inst->m2m_dev, m2m_ctx); 89 } 90 91 static const struct v4l2_m2m_ops iris_m2m_ops = { 92 .device_run = iris_m2m_device_run, 93 .job_abort = iris_m2m_job_abort, 94 }; 95 96 static int 97 iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) 98 { 99 struct iris_inst *inst = priv; 100 int ret; 101 102 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 103 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 104 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 105 src_vq->ops = inst->core->iris_vb2_ops; 106 src_vq->mem_ops = &vb2_dma_contig_memops; 107 src_vq->drv_priv = inst; 108 src_vq->buf_struct_size = sizeof(struct iris_buffer); 109 src_vq->min_reqbufs_allocation = MIN_BUFFERS; 110 src_vq->dev = inst->core->dev; 111 src_vq->lock = &inst->ctx_q_lock; 112 ret = vb2_queue_init(src_vq); 113 if (ret) 114 return ret; 115 116 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 117 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 118 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 119 dst_vq->ops = inst->core->iris_vb2_ops; 120 dst_vq->mem_ops = &vb2_dma_contig_memops; 121 dst_vq->drv_priv = inst; 122 dst_vq->buf_struct_size = sizeof(struct iris_buffer); 123 dst_vq->min_reqbufs_allocation = MIN_BUFFERS; 124 dst_vq->dev = inst->core->dev; 125 dst_vq->lock = &inst->ctx_q_lock; 126 127 return vb2_queue_init(dst_vq); 128 } 129 130 int iris_open(struct file *filp) 131 { 132 struct iris_core *core = video_drvdata(filp); 133 struct video_device *vdev; 134 struct iris_inst *inst; 135 u32 session_type; 136 int ret; 137 138 vdev = video_devdata(filp); 139 if (strcmp(vdev->name, "qcom-iris-decoder") == 0) 140 session_type = DECODER; 141 else if (strcmp(vdev->name, "qcom-iris-encoder") == 0) 142 session_type = ENCODER; 143 else 144 return -EINVAL; 145 146 ret = pm_runtime_resume_and_get(core->dev); 147 if (ret < 0) 148 return ret; 149 150 ret = iris_core_init(core); 151 if (ret) { 152 dev_err(core->dev, "core init failed\n"); 153 pm_runtime_put_sync(core->dev); 154 return ret; 155 } 156 157 pm_runtime_put_sync(core->dev); 158 159 inst = core->iris_platform_data->get_instance(); 160 if (!inst) 161 return -ENOMEM; 162 163 inst->core = core; 164 inst->domain = session_type; 165 inst->session_id = hash32_ptr(inst); 166 inst->state = IRIS_INST_DEINIT; 167 168 mutex_init(&inst->lock); 169 mutex_init(&inst->ctx_q_lock); 170 171 INIT_LIST_HEAD(&inst->buffers[BUF_BIN].list); 172 INIT_LIST_HEAD(&inst->buffers[BUF_ARP].list); 173 INIT_LIST_HEAD(&inst->buffers[BUF_COMV].list); 174 INIT_LIST_HEAD(&inst->buffers[BUF_NON_COMV].list); 175 INIT_LIST_HEAD(&inst->buffers[BUF_LINE].list); 176 INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list); 177 INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list); 178 INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list); 179 init_completion(&inst->completion); 180 init_completion(&inst->flush_completion); 181 182 iris_v4l2_fh_init(inst, filp); 183 184 inst->m2m_dev = v4l2_m2m_init(&iris_m2m_ops); 185 if (IS_ERR_OR_NULL(inst->m2m_dev)) { 186 ret = -EINVAL; 187 goto fail_v4l2_fh_deinit; 188 } 189 190 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, iris_m2m_queue_init); 191 if (IS_ERR_OR_NULL(inst->m2m_ctx)) { 192 ret = -EINVAL; 193 goto fail_m2m_release; 194 } 195 196 if (inst->domain == DECODER) 197 ret = iris_vdec_inst_init(inst); 198 else if (inst->domain == ENCODER) 199 ret = iris_venc_inst_init(inst); 200 if (ret) 201 goto fail_m2m_ctx_release; 202 203 iris_add_session(inst); 204 205 inst->fh.m2m_ctx = inst->m2m_ctx; 206 207 return 0; 208 209 fail_m2m_ctx_release: 210 v4l2_m2m_ctx_release(inst->m2m_ctx); 211 fail_m2m_release: 212 v4l2_m2m_release(inst->m2m_dev); 213 fail_v4l2_fh_deinit: 214 iris_v4l2_fh_deinit(inst, filp); 215 mutex_destroy(&inst->ctx_q_lock); 216 mutex_destroy(&inst->lock); 217 kfree(inst); 218 219 return ret; 220 } 221 222 static void iris_session_close(struct iris_inst *inst) 223 { 224 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 225 bool wait_for_response = true; 226 int ret; 227 228 if (inst->state == IRIS_INST_DEINIT) 229 return; 230 231 reinit_completion(&inst->completion); 232 233 ret = hfi_ops->session_close(inst); 234 if (ret) 235 wait_for_response = false; 236 237 if (wait_for_response) 238 iris_wait_for_session_response(inst, false); 239 } 240 241 static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane) 242 { 243 const struct iris_platform_data *platform_data = inst->core->iris_platform_data; 244 struct iris_buffer *buf, *next; 245 struct iris_buffers *buffers; 246 const u32 *internal_buf_type; 247 u32 internal_buffer_count, i; 248 u32 count = 0; 249 250 if (V4L2_TYPE_IS_OUTPUT(plane)) { 251 internal_buf_type = platform_data->dec_ip_int_buf_tbl; 252 internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; 253 } else { 254 internal_buf_type = platform_data->dec_op_int_buf_tbl; 255 internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; 256 } 257 258 for (i = 0; i < internal_buffer_count; i++) { 259 buffers = &inst->buffers[internal_buf_type[i]]; 260 count = 0; 261 list_for_each_entry_safe(buf, next, &buffers->list, list) 262 count++; 263 if (count) 264 dev_err(inst->core->dev, "%d buffer of type %d not released", 265 count, internal_buf_type[i]); 266 } 267 268 buffers = &inst->buffers[BUF_PERSIST]; 269 270 count = 0; 271 list_for_each_entry_safe(buf, next, &buffers->list, list) 272 count++; 273 if (count) 274 dev_err(inst->core->dev, "%d buffer of type BUF_PERSIST not released", count); 275 } 276 277 int iris_close(struct file *filp) 278 { 279 struct iris_inst *inst = iris_get_inst(filp); 280 281 v4l2_ctrl_handler_free(&inst->ctrl_handler); 282 v4l2_m2m_ctx_release(inst->m2m_ctx); 283 v4l2_m2m_release(inst->m2m_dev); 284 mutex_lock(&inst->lock); 285 if (inst->domain == DECODER) 286 iris_vdec_inst_deinit(inst); 287 else if (inst->domain == ENCODER) 288 iris_venc_inst_deinit(inst); 289 iris_session_close(inst); 290 iris_inst_change_state(inst, IRIS_INST_DEINIT); 291 iris_v4l2_fh_deinit(inst, filp); 292 iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 293 iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 294 iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 295 iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 296 iris_remove_session(inst); 297 mutex_unlock(&inst->lock); 298 mutex_destroy(&inst->ctx_q_lock); 299 mutex_destroy(&inst->lock); 300 kfree(inst); 301 302 return 0; 303 } 304 305 static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f) 306 { 307 struct iris_inst *inst = iris_get_inst(filp); 308 309 if (inst->domain == DECODER) 310 return iris_vdec_enum_fmt(inst, f); 311 else if (inst->domain == ENCODER) 312 return iris_venc_enum_fmt(inst, f); 313 else 314 return -EINVAL; 315 } 316 317 static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) 318 { 319 struct iris_inst *inst = iris_get_inst(filp); 320 int ret = 0; 321 322 mutex_lock(&inst->lock); 323 324 if (inst->domain == DECODER) 325 ret = iris_vdec_try_fmt(inst, f); 326 else if (inst->domain == ENCODER) 327 ret = iris_venc_try_fmt(inst, f); 328 329 mutex_unlock(&inst->lock); 330 331 return ret; 332 } 333 334 static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) 335 { 336 struct iris_inst *inst = iris_get_inst(filp); 337 int ret = 0; 338 339 mutex_lock(&inst->lock); 340 341 if (inst->domain == DECODER) 342 ret = iris_vdec_s_fmt(inst, f); 343 else if (inst->domain == ENCODER) 344 ret = iris_venc_s_fmt(inst, f); 345 346 mutex_unlock(&inst->lock); 347 348 return ret; 349 } 350 351 static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) 352 { 353 struct iris_inst *inst = iris_get_inst(filp); 354 int ret = 0; 355 356 mutex_lock(&inst->lock); 357 if (V4L2_TYPE_IS_OUTPUT(f->type)) 358 *f = *inst->fmt_src; 359 else if (V4L2_TYPE_IS_CAPTURE(f->type)) 360 *f = *inst->fmt_dst; 361 else 362 ret = -EINVAL; 363 364 mutex_unlock(&inst->lock); 365 366 return ret; 367 } 368 369 static int iris_enum_framesizes(struct file *filp, void *fh, 370 struct v4l2_frmsizeenum *fsize) 371 { 372 struct iris_inst *inst = iris_get_inst(filp); 373 struct platform_inst_caps *caps; 374 int ret = 0; 375 376 if (fsize->index) 377 return -EINVAL; 378 379 if (inst->domain == DECODER) 380 ret = iris_vdec_validate_format(inst, fsize->pixel_format); 381 else 382 ret = iris_venc_validate_format(inst, fsize->pixel_format); 383 384 if (ret) 385 return ret; 386 387 caps = inst->core->iris_platform_data->inst_caps; 388 389 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 390 fsize->stepwise.min_width = caps->min_frame_width; 391 fsize->stepwise.max_width = caps->max_frame_width; 392 fsize->stepwise.step_width = STEP_WIDTH; 393 fsize->stepwise.min_height = caps->min_frame_height; 394 fsize->stepwise.max_height = caps->max_frame_height; 395 fsize->stepwise.step_height = STEP_HEIGHT; 396 397 return ret; 398 } 399 400 static int iris_enum_frameintervals(struct file *filp, void *fh, 401 struct v4l2_frmivalenum *fival) 402 403 { 404 struct iris_inst *inst = iris_get_inst(filp); 405 struct iris_core *core = inst->core; 406 struct platform_inst_caps *caps; 407 u32 fps, mbpf; 408 int ret = 0; 409 410 if (inst->domain == DECODER) 411 return -ENOTTY; 412 413 if (fival->index) 414 return -EINVAL; 415 416 ret = iris_venc_validate_format(inst, fival->pixel_format); 417 if (ret) 418 return ret; 419 420 if (!fival->width || !fival->height) 421 return -EINVAL; 422 423 caps = inst->core->iris_platform_data->inst_caps; 424 if (fival->width > caps->max_frame_width || 425 fival->width < caps->min_frame_width || 426 fival->height > caps->max_frame_height || 427 fival->height < caps->min_frame_height) 428 return -EINVAL; 429 430 mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width); 431 fps = DIV_ROUND_UP(core->iris_platform_data->max_core_mbps, mbpf); 432 433 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 434 fival->stepwise.min.numerator = 1; 435 fival->stepwise.min.denominator = 436 min_t(u32, fps, MAXIMUM_FPS); 437 fival->stepwise.max.numerator = 1; 438 fival->stepwise.max.denominator = 1; 439 fival->stepwise.step.numerator = 1; 440 fival->stepwise.step.denominator = MAXIMUM_FPS; 441 442 return 0; 443 } 444 445 static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap) 446 { 447 struct iris_inst *inst = iris_get_inst(filp); 448 449 strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver)); 450 451 if (inst->domain == DECODER) 452 strscpy(cap->card, "Iris Decoder", sizeof(cap->card)); 453 else 454 strscpy(cap->card, "Iris Encoder", sizeof(cap->card)); 455 456 return 0; 457 } 458 459 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s) 460 { 461 struct iris_inst *inst = iris_get_inst(filp); 462 463 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 464 inst->domain == DECODER) 465 return -EINVAL; 466 467 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 468 inst->domain == ENCODER) 469 return -EINVAL; 470 471 if (inst->domain == DECODER) { 472 switch (s->target) { 473 case V4L2_SEL_TGT_CROP_BOUNDS: 474 case V4L2_SEL_TGT_CROP_DEFAULT: 475 case V4L2_SEL_TGT_CROP: 476 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 477 case V4L2_SEL_TGT_COMPOSE_PADDED: 478 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 479 case V4L2_SEL_TGT_COMPOSE: 480 s->r.left = inst->crop.left; 481 s->r.top = inst->crop.top; 482 s->r.width = inst->crop.width; 483 s->r.height = inst->crop.height; 484 break; 485 default: 486 return -EINVAL; 487 } 488 } else if (inst->domain == ENCODER) { 489 switch (s->target) { 490 case V4L2_SEL_TGT_CROP_BOUNDS: 491 case V4L2_SEL_TGT_CROP_DEFAULT: 492 s->r.width = inst->fmt_src->fmt.pix_mp.width; 493 s->r.height = inst->fmt_src->fmt.pix_mp.height; 494 break; 495 case V4L2_SEL_TGT_CROP: 496 s->r.width = inst->crop.width; 497 s->r.height = inst->crop.height; 498 break; 499 default: 500 return -EINVAL; 501 } 502 s->r.left = inst->crop.left; 503 s->r.top = inst->crop.top; 504 } 505 506 return 0; 507 } 508 509 static int iris_s_selection(struct file *filp, void *fh, struct v4l2_selection *s) 510 { 511 struct iris_inst *inst = iris_get_inst(filp); 512 513 if (inst->domain == DECODER) 514 return -EINVAL; 515 else if (inst->domain == ENCODER) 516 return iris_venc_s_selection(inst, s); 517 518 return -EINVAL; 519 } 520 521 static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) 522 { 523 struct iris_inst *inst = container_of(fh, struct iris_inst, fh); 524 525 if (inst->domain == DECODER) 526 return iris_vdec_subscribe_event(inst, sub); 527 else if (inst->domain == ENCODER) 528 return iris_venc_subscribe_event(inst, sub); 529 530 return -EINVAL; 531 } 532 533 static int iris_s_parm(struct file *filp, void *fh, struct v4l2_streamparm *a) 534 { 535 struct iris_inst *inst = iris_get_inst(filp); 536 537 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 538 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 539 return -EINVAL; 540 541 if (inst->domain == ENCODER) 542 return iris_venc_s_param(inst, a); 543 else 544 return -EINVAL; 545 } 546 547 static int iris_g_parm(struct file *filp, void *fh, struct v4l2_streamparm *a) 548 { 549 struct iris_inst *inst = iris_get_inst(filp); 550 551 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 552 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 553 return -EINVAL; 554 555 if (inst->domain == ENCODER) 556 return iris_venc_g_param(inst, a); 557 else 558 return -EINVAL; 559 } 560 561 static int iris_dec_cmd(struct file *filp, void *fh, 562 struct v4l2_decoder_cmd *dec) 563 { 564 struct iris_inst *inst = iris_get_inst(filp); 565 int ret = 0; 566 567 mutex_lock(&inst->lock); 568 569 ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec); 570 if (ret) 571 goto unlock; 572 573 if (inst->state == IRIS_INST_DEINIT) 574 goto unlock; 575 576 if (!iris_allow_cmd(inst, dec->cmd)) { 577 ret = -EBUSY; 578 goto unlock; 579 } 580 581 if (dec->cmd == V4L2_DEC_CMD_START) 582 ret = iris_vdec_start_cmd(inst); 583 else if (dec->cmd == V4L2_DEC_CMD_STOP) 584 ret = iris_vdec_stop_cmd(inst); 585 else 586 ret = -EINVAL; 587 588 unlock: 589 mutex_unlock(&inst->lock); 590 591 return ret; 592 } 593 594 static struct v4l2_file_operations iris_v4l2_file_ops = { 595 .owner = THIS_MODULE, 596 .open = iris_open, 597 .release = iris_close, 598 .unlocked_ioctl = video_ioctl2, 599 .poll = v4l2_m2m_fop_poll, 600 .mmap = v4l2_m2m_fop_mmap, 601 }; 602 603 static const struct vb2_ops iris_vb2_ops = { 604 .buf_init = iris_vb2_buf_init, 605 .queue_setup = iris_vb2_queue_setup, 606 .start_streaming = iris_vb2_start_streaming, 607 .stop_streaming = iris_vb2_stop_streaming, 608 .buf_prepare = iris_vb2_buf_prepare, 609 .buf_out_validate = iris_vb2_buf_out_validate, 610 .buf_queue = iris_vb2_buf_queue, 611 }; 612 613 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_dec = { 614 .vidioc_enum_fmt_vid_cap = iris_enum_fmt, 615 .vidioc_enum_fmt_vid_out = iris_enum_fmt, 616 .vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane, 617 .vidioc_try_fmt_vid_out_mplane = iris_try_fmt_vid_mplane, 618 .vidioc_s_fmt_vid_cap_mplane = iris_s_fmt_vid_mplane, 619 .vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane, 620 .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane, 621 .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, 622 .vidioc_enum_framesizes = iris_enum_framesizes, 623 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 624 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 625 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 626 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 627 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 628 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 629 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 630 .vidioc_remove_bufs = v4l2_m2m_ioctl_remove_bufs, 631 .vidioc_querycap = iris_querycap, 632 .vidioc_g_selection = iris_g_selection, 633 .vidioc_subscribe_event = iris_subscribe_event, 634 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 635 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 636 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 637 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, 638 .vidioc_decoder_cmd = iris_dec_cmd, 639 }; 640 641 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_enc = { 642 .vidioc_enum_fmt_vid_cap = iris_enum_fmt, 643 .vidioc_enum_fmt_vid_out = iris_enum_fmt, 644 .vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane, 645 .vidioc_try_fmt_vid_out_mplane = iris_try_fmt_vid_mplane, 646 .vidioc_s_fmt_vid_cap_mplane = iris_s_fmt_vid_mplane, 647 .vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane, 648 .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane, 649 .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, 650 .vidioc_enum_framesizes = iris_enum_framesizes, 651 .vidioc_enum_frameintervals = iris_enum_frameintervals, 652 .vidioc_querycap = iris_querycap, 653 .vidioc_subscribe_event = iris_subscribe_event, 654 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 655 .vidioc_g_selection = iris_g_selection, 656 .vidioc_s_selection = iris_s_selection, 657 .vidioc_s_parm = iris_s_parm, 658 .vidioc_g_parm = iris_g_parm, 659 }; 660 661 void iris_init_ops(struct iris_core *core) 662 { 663 core->iris_v4l2_file_ops = &iris_v4l2_file_ops; 664 core->iris_vb2_ops = &iris_vb2_ops; 665 core->iris_v4l2_ioctl_ops_dec = &iris_v4l2_ioctl_ops_dec; 666 core->iris_v4l2_ioctl_ops_enc = &iris_v4l2_ioctl_ops_enc; 667 } 668