1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * V4L2 Capture IC Preprocess Subdev for Freescale i.MX5/6 SOC 4 * 5 * This subdevice handles capture of video frames from the CSI or VDIC, 6 * which are routed directly to the Image Converter preprocess tasks, 7 * for resizing, colorspace conversion, and rotation. 8 * 9 * Copyright (c) 2012-2017 Mentor Graphics Inc. 10 */ 11 #include <linux/delay.h> 12 #include <linux/interrupt.h> 13 #include <linux/module.h> 14 #include <linux/sched.h> 15 #include <linux/slab.h> 16 #include <linux/spinlock.h> 17 #include <linux/timer.h> 18 #include <media/v4l2-ctrls.h> 19 #include <media/v4l2-device.h> 20 #include <media/v4l2-ioctl.h> 21 #include <media/v4l2-mc.h> 22 #include <media/v4l2-subdev.h> 23 #include <media/imx.h> 24 #include "imx-media.h" 25 #include "imx-ic.h" 26 27 /* 28 * Min/Max supported width and heights. 29 * 30 * We allow planar output, so we have to align width at the source pad 31 * by 16 pixels to meet IDMAC alignment requirements for possible planar 32 * output. 33 * 34 * TODO: move this into pad format negotiation, if capture device 35 * has not requested a planar format, we should allow 8 pixel 36 * alignment at the source pad. 37 */ 38 #define MIN_W_SINK 176 39 #define MIN_H_SINK 144 40 #define MAX_W_SINK 4096 41 #define MAX_H_SINK 4096 42 #define W_ALIGN_SINK 3 /* multiple of 8 pixels */ 43 #define H_ALIGN_SINK 1 /* multiple of 2 lines */ 44 45 #define MAX_W_SRC 1024 46 #define MAX_H_SRC 1024 47 #define W_ALIGN_SRC 1 /* multiple of 2 pixels */ 48 #define H_ALIGN_SRC 1 /* multiple of 2 lines */ 49 50 #define S_ALIGN 1 /* multiple of 2 */ 51 52 struct prp_priv { 53 struct imx_media_dev *md; 54 struct imx_ic_priv *ic_priv; 55 struct media_pad pad[PRPENCVF_NUM_PADS]; 56 /* the video device at output pad */ 57 struct imx_media_video_dev *vdev; 58 59 /* lock to protect all members below */ 60 struct mutex lock; 61 62 /* IPU units we require */ 63 struct ipu_soc *ipu; 64 struct ipu_ic *ic; 65 struct ipuv3_channel *out_ch; 66 struct ipuv3_channel *rot_in_ch; 67 struct ipuv3_channel *rot_out_ch; 68 69 /* active vb2 buffers to send to video dev sink */ 70 struct imx_media_buffer *active_vb2_buf[2]; 71 struct imx_media_dma_buf underrun_buf; 72 73 int ipu_buf_num; /* ipu double buffer index: 0-1 */ 74 75 /* the sink for the captured frames */ 76 struct media_entity *sink; 77 /* the source subdev */ 78 struct v4l2_subdev *src_sd; 79 80 struct v4l2_mbus_framefmt format_mbus[PRPENCVF_NUM_PADS]; 81 const struct imx_media_pixfmt *cc[PRPENCVF_NUM_PADS]; 82 struct v4l2_fract frame_interval; 83 84 struct imx_media_dma_buf rot_buf[2]; 85 86 /* controls */ 87 struct v4l2_ctrl_handler ctrl_hdlr; 88 int rotation; /* degrees */ 89 bool hflip; 90 bool vflip; 91 92 /* derived from rotation, hflip, vflip controls */ 93 enum ipu_rotate_mode rot_mode; 94 95 spinlock_t irqlock; /* protect eof_irq handler */ 96 97 struct timer_list eof_timeout_timer; 98 int eof_irq; 99 int nfb4eof_irq; 100 101 int stream_count; 102 u32 frame_sequence; /* frame sequence counter */ 103 bool last_eof; /* waiting for last EOF at stream off */ 104 bool nfb4eof; /* NFB4EOF encountered during streaming */ 105 bool interweave_swap; /* swap top/bottom lines when interweaving */ 106 struct completion last_eof_comp; 107 }; 108 109 static const struct prp_channels { 110 u32 out_ch; 111 u32 rot_in_ch; 112 u32 rot_out_ch; 113 } prp_channel[] = { 114 [IC_TASK_ENCODER] = { 115 .out_ch = IPUV3_CHANNEL_IC_PRP_ENC_MEM, 116 .rot_in_ch = IPUV3_CHANNEL_MEM_ROT_ENC, 117 .rot_out_ch = IPUV3_CHANNEL_ROT_ENC_MEM, 118 }, 119 [IC_TASK_VIEWFINDER] = { 120 .out_ch = IPUV3_CHANNEL_IC_PRP_VF_MEM, 121 .rot_in_ch = IPUV3_CHANNEL_MEM_ROT_VF, 122 .rot_out_ch = IPUV3_CHANNEL_ROT_VF_MEM, 123 }, 124 }; 125 126 static inline struct prp_priv *sd_to_priv(struct v4l2_subdev *sd) 127 { 128 struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd); 129 130 return ic_priv->task_priv; 131 } 132 133 static void prp_put_ipu_resources(struct prp_priv *priv) 134 { 135 if (priv->ic) 136 ipu_ic_put(priv->ic); 137 priv->ic = NULL; 138 139 if (priv->out_ch) 140 ipu_idmac_put(priv->out_ch); 141 priv->out_ch = NULL; 142 143 if (priv->rot_in_ch) 144 ipu_idmac_put(priv->rot_in_ch); 145 priv->rot_in_ch = NULL; 146 147 if (priv->rot_out_ch) 148 ipu_idmac_put(priv->rot_out_ch); 149 priv->rot_out_ch = NULL; 150 } 151 152 static int prp_get_ipu_resources(struct prp_priv *priv) 153 { 154 struct imx_ic_priv *ic_priv = priv->ic_priv; 155 struct ipu_ic *ic; 156 struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch; 157 int ret, task = ic_priv->task_id; 158 159 priv->ipu = priv->md->ipu[ic_priv->ipu_id]; 160 161 ic = ipu_ic_get(priv->ipu, task); 162 if (IS_ERR(ic)) { 163 v4l2_err(&ic_priv->sd, "failed to get IC\n"); 164 ret = PTR_ERR(ic); 165 goto out; 166 } 167 priv->ic = ic; 168 169 out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch); 170 if (IS_ERR(out_ch)) { 171 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", 172 prp_channel[task].out_ch); 173 ret = PTR_ERR(out_ch); 174 goto out; 175 } 176 priv->out_ch = out_ch; 177 178 rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch); 179 if (IS_ERR(rot_in_ch)) { 180 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", 181 prp_channel[task].rot_in_ch); 182 ret = PTR_ERR(rot_in_ch); 183 goto out; 184 } 185 priv->rot_in_ch = rot_in_ch; 186 187 rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch); 188 if (IS_ERR(rot_out_ch)) { 189 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", 190 prp_channel[task].rot_out_ch); 191 ret = PTR_ERR(rot_out_ch); 192 goto out; 193 } 194 priv->rot_out_ch = rot_out_ch; 195 196 return 0; 197 out: 198 prp_put_ipu_resources(priv); 199 return ret; 200 } 201 202 static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch) 203 { 204 struct imx_media_video_dev *vdev = priv->vdev; 205 struct imx_media_buffer *done, *next; 206 struct vb2_buffer *vb; 207 dma_addr_t phys; 208 209 done = priv->active_vb2_buf[priv->ipu_buf_num]; 210 if (done) { 211 done->vbuf.field = vdev->fmt.fmt.pix.field; 212 done->vbuf.sequence = priv->frame_sequence; 213 vb = &done->vbuf.vb2_buf; 214 vb->timestamp = ktime_get_ns(); 215 vb2_buffer_done(vb, priv->nfb4eof ? 216 VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); 217 } 218 219 priv->frame_sequence++; 220 priv->nfb4eof = false; 221 222 /* get next queued buffer */ 223 next = imx_media_capture_device_next_buf(vdev); 224 if (next) { 225 phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0); 226 priv->active_vb2_buf[priv->ipu_buf_num] = next; 227 } else { 228 phys = priv->underrun_buf.phys; 229 priv->active_vb2_buf[priv->ipu_buf_num] = NULL; 230 } 231 232 if (ipu_idmac_buffer_is_ready(ch, priv->ipu_buf_num)) 233 ipu_idmac_clear_buffer(ch, priv->ipu_buf_num); 234 235 if (priv->interweave_swap && ch == priv->out_ch) 236 phys += vdev->fmt.fmt.pix.bytesperline; 237 238 ipu_cpmem_set_buffer(ch, priv->ipu_buf_num, phys); 239 } 240 241 static irqreturn_t prp_eof_interrupt(int irq, void *dev_id) 242 { 243 struct prp_priv *priv = dev_id; 244 struct ipuv3_channel *channel; 245 246 spin_lock(&priv->irqlock); 247 248 if (priv->last_eof) { 249 complete(&priv->last_eof_comp); 250 priv->last_eof = false; 251 goto unlock; 252 } 253 254 channel = (ipu_rot_mode_is_irt(priv->rot_mode)) ? 255 priv->rot_out_ch : priv->out_ch; 256 257 prp_vb2_buf_done(priv, channel); 258 259 /* select new IPU buf */ 260 ipu_idmac_select_buffer(channel, priv->ipu_buf_num); 261 /* toggle IPU double-buffer index */ 262 priv->ipu_buf_num ^= 1; 263 264 /* bump the EOF timeout timer */ 265 mod_timer(&priv->eof_timeout_timer, 266 jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); 267 268 unlock: 269 spin_unlock(&priv->irqlock); 270 return IRQ_HANDLED; 271 } 272 273 static irqreturn_t prp_nfb4eof_interrupt(int irq, void *dev_id) 274 { 275 struct prp_priv *priv = dev_id; 276 struct imx_ic_priv *ic_priv = priv->ic_priv; 277 278 spin_lock(&priv->irqlock); 279 280 /* 281 * this is not an unrecoverable error, just mark 282 * the next captured frame with vb2 error flag. 283 */ 284 priv->nfb4eof = true; 285 286 v4l2_err(&ic_priv->sd, "NFB4EOF\n"); 287 288 spin_unlock(&priv->irqlock); 289 290 return IRQ_HANDLED; 291 } 292 293 /* 294 * EOF timeout timer function. 295 */ 296 /* 297 * EOF timeout timer function. This is an unrecoverable condition 298 * without a stream restart. 299 */ 300 static void prp_eof_timeout(struct timer_list *t) 301 { 302 struct prp_priv *priv = from_timer(priv, t, eof_timeout_timer); 303 struct imx_media_video_dev *vdev = priv->vdev; 304 struct imx_ic_priv *ic_priv = priv->ic_priv; 305 306 v4l2_err(&ic_priv->sd, "EOF timeout\n"); 307 308 /* signal a fatal error to capture device */ 309 imx_media_capture_device_error(vdev); 310 } 311 312 static void prp_setup_vb2_buf(struct prp_priv *priv, dma_addr_t *phys) 313 { 314 struct imx_media_video_dev *vdev = priv->vdev; 315 struct imx_media_buffer *buf; 316 int i; 317 318 for (i = 0; i < 2; i++) { 319 buf = imx_media_capture_device_next_buf(vdev); 320 if (buf) { 321 priv->active_vb2_buf[i] = buf; 322 phys[i] = vb2_dma_contig_plane_dma_addr( 323 &buf->vbuf.vb2_buf, 0); 324 } else { 325 priv->active_vb2_buf[i] = NULL; 326 phys[i] = priv->underrun_buf.phys; 327 } 328 } 329 } 330 331 static void prp_unsetup_vb2_buf(struct prp_priv *priv, 332 enum vb2_buffer_state return_status) 333 { 334 struct imx_media_buffer *buf; 335 int i; 336 337 /* return any remaining active frames with return_status */ 338 for (i = 0; i < 2; i++) { 339 buf = priv->active_vb2_buf[i]; 340 if (buf) { 341 struct vb2_buffer *vb = &buf->vbuf.vb2_buf; 342 343 vb->timestamp = ktime_get_ns(); 344 vb2_buffer_done(vb, return_status); 345 } 346 } 347 } 348 349 static int prp_setup_channel(struct prp_priv *priv, 350 struct ipuv3_channel *channel, 351 enum ipu_rotate_mode rot_mode, 352 dma_addr_t addr0, dma_addr_t addr1, 353 bool rot_swap_width_height) 354 { 355 struct imx_media_video_dev *vdev = priv->vdev; 356 const struct imx_media_pixfmt *outcc; 357 struct v4l2_mbus_framefmt *outfmt; 358 unsigned int burst_size; 359 struct ipu_image image; 360 bool interweave; 361 int ret; 362 363 outfmt = &priv->format_mbus[PRPENCVF_SRC_PAD]; 364 outcc = vdev->cc; 365 366 ipu_cpmem_zero(channel); 367 368 memset(&image, 0, sizeof(image)); 369 image.pix = vdev->fmt.fmt.pix; 370 image.rect = vdev->compose; 371 372 /* 373 * If the field type at capture interface is interlaced, and 374 * the output IDMAC pad is sequential, enable interweave at 375 * the IDMAC output channel. 376 */ 377 interweave = V4L2_FIELD_IS_INTERLACED(image.pix.field) && 378 V4L2_FIELD_IS_SEQUENTIAL(outfmt->field); 379 priv->interweave_swap = interweave && 380 image.pix.field == V4L2_FIELD_INTERLACED_BT; 381 382 if (rot_swap_width_height) { 383 swap(image.pix.width, image.pix.height); 384 swap(image.rect.width, image.rect.height); 385 /* recalc stride using swapped width */ 386 image.pix.bytesperline = outcc->planar ? 387 image.pix.width : 388 (image.pix.width * outcc->bpp) >> 3; 389 } 390 391 if (priv->interweave_swap && channel == priv->out_ch) { 392 /* start interweave scan at 1st top line (2nd line) */ 393 image.rect.top = 1; 394 } 395 396 image.phys0 = addr0; 397 image.phys1 = addr1; 398 399 /* 400 * Skip writing U and V components to odd rows in the output 401 * channels for planar 4:2:0 (but not when enabling IDMAC 402 * interweaving, they are incompatible). 403 */ 404 if ((channel == priv->out_ch && !interweave) || 405 channel == priv->rot_out_ch) { 406 switch (image.pix.pixelformat) { 407 case V4L2_PIX_FMT_YUV420: 408 case V4L2_PIX_FMT_YVU420: 409 case V4L2_PIX_FMT_NV12: 410 ipu_cpmem_skip_odd_chroma_rows(channel); 411 break; 412 } 413 } 414 415 ret = ipu_cpmem_set_image(channel, &image); 416 if (ret) 417 return ret; 418 419 if (channel == priv->rot_in_ch || 420 channel == priv->rot_out_ch) { 421 burst_size = 8; 422 ipu_cpmem_set_block_mode(channel); 423 } else { 424 burst_size = (image.pix.width & 0xf) ? 8 : 16; 425 } 426 427 ipu_cpmem_set_burstsize(channel, burst_size); 428 429 if (rot_mode) 430 ipu_cpmem_set_rotation(channel, rot_mode); 431 432 if (interweave && channel == priv->out_ch) 433 ipu_cpmem_interlaced_scan(channel, 434 priv->interweave_swap ? 435 -image.pix.bytesperline : 436 image.pix.bytesperline, 437 image.pix.pixelformat); 438 439 ret = ipu_ic_task_idma_init(priv->ic, channel, 440 image.pix.width, image.pix.height, 441 burst_size, rot_mode); 442 if (ret) 443 return ret; 444 445 ipu_cpmem_set_axi_id(channel, 1); 446 447 ipu_idmac_set_double_buffer(channel, true); 448 449 return 0; 450 } 451 452 static int prp_setup_rotation(struct prp_priv *priv) 453 { 454 struct imx_media_video_dev *vdev = priv->vdev; 455 struct imx_ic_priv *ic_priv = priv->ic_priv; 456 const struct imx_media_pixfmt *outcc, *incc; 457 struct v4l2_mbus_framefmt *infmt; 458 struct v4l2_pix_format *outfmt; 459 dma_addr_t phys[2]; 460 int ret; 461 462 infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; 463 outfmt = &vdev->fmt.fmt.pix; 464 incc = priv->cc[PRPENCVF_SINK_PAD]; 465 outcc = vdev->cc; 466 467 ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[0], 468 outfmt->sizeimage); 469 if (ret) { 470 v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[0], %d\n", ret); 471 return ret; 472 } 473 ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[1], 474 outfmt->sizeimage); 475 if (ret) { 476 v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[1], %d\n", ret); 477 goto free_rot0; 478 } 479 480 ret = ipu_ic_task_init(priv->ic, 481 infmt->width, infmt->height, 482 outfmt->height, outfmt->width, 483 incc->cs, outcc->cs); 484 if (ret) { 485 v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret); 486 goto free_rot1; 487 } 488 489 /* init the IC-PRP-->MEM IDMAC channel */ 490 ret = prp_setup_channel(priv, priv->out_ch, IPU_ROTATE_NONE, 491 priv->rot_buf[0].phys, priv->rot_buf[1].phys, 492 true); 493 if (ret) { 494 v4l2_err(&ic_priv->sd, 495 "prp_setup_channel(out_ch) failed, %d\n", ret); 496 goto free_rot1; 497 } 498 499 /* init the MEM-->IC-PRP ROT IDMAC channel */ 500 ret = prp_setup_channel(priv, priv->rot_in_ch, priv->rot_mode, 501 priv->rot_buf[0].phys, priv->rot_buf[1].phys, 502 true); 503 if (ret) { 504 v4l2_err(&ic_priv->sd, 505 "prp_setup_channel(rot_in_ch) failed, %d\n", ret); 506 goto free_rot1; 507 } 508 509 prp_setup_vb2_buf(priv, phys); 510 511 /* init the destination IC-PRP ROT-->MEM IDMAC channel */ 512 ret = prp_setup_channel(priv, priv->rot_out_ch, IPU_ROTATE_NONE, 513 phys[0], phys[1], 514 false); 515 if (ret) { 516 v4l2_err(&ic_priv->sd, 517 "prp_setup_channel(rot_out_ch) failed, %d\n", ret); 518 goto unsetup_vb2; 519 } 520 521 /* now link IC-PRP-->MEM to MEM-->IC-PRP ROT */ 522 ipu_idmac_link(priv->out_ch, priv->rot_in_ch); 523 524 /* enable the IC */ 525 ipu_ic_enable(priv->ic); 526 527 /* set buffers ready */ 528 ipu_idmac_select_buffer(priv->out_ch, 0); 529 ipu_idmac_select_buffer(priv->out_ch, 1); 530 ipu_idmac_select_buffer(priv->rot_out_ch, 0); 531 ipu_idmac_select_buffer(priv->rot_out_ch, 1); 532 533 /* enable the channels */ 534 ipu_idmac_enable_channel(priv->out_ch); 535 ipu_idmac_enable_channel(priv->rot_in_ch); 536 ipu_idmac_enable_channel(priv->rot_out_ch); 537 538 /* and finally enable the IC PRP task */ 539 ipu_ic_task_enable(priv->ic); 540 541 return 0; 542 543 unsetup_vb2: 544 prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED); 545 free_rot1: 546 imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]); 547 free_rot0: 548 imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]); 549 return ret; 550 } 551 552 static void prp_unsetup_rotation(struct prp_priv *priv) 553 { 554 ipu_ic_task_disable(priv->ic); 555 556 ipu_idmac_disable_channel(priv->out_ch); 557 ipu_idmac_disable_channel(priv->rot_in_ch); 558 ipu_idmac_disable_channel(priv->rot_out_ch); 559 560 ipu_idmac_unlink(priv->out_ch, priv->rot_in_ch); 561 562 ipu_ic_disable(priv->ic); 563 564 imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]); 565 imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]); 566 } 567 568 static int prp_setup_norotation(struct prp_priv *priv) 569 { 570 struct imx_media_video_dev *vdev = priv->vdev; 571 struct imx_ic_priv *ic_priv = priv->ic_priv; 572 const struct imx_media_pixfmt *outcc, *incc; 573 struct v4l2_mbus_framefmt *infmt; 574 struct v4l2_pix_format *outfmt; 575 dma_addr_t phys[2]; 576 int ret; 577 578 infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; 579 outfmt = &vdev->fmt.fmt.pix; 580 incc = priv->cc[PRPENCVF_SINK_PAD]; 581 outcc = vdev->cc; 582 583 ret = ipu_ic_task_init(priv->ic, 584 infmt->width, infmt->height, 585 outfmt->width, outfmt->height, 586 incc->cs, outcc->cs); 587 if (ret) { 588 v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret); 589 return ret; 590 } 591 592 prp_setup_vb2_buf(priv, phys); 593 594 /* init the IC PRP-->MEM IDMAC channel */ 595 ret = prp_setup_channel(priv, priv->out_ch, priv->rot_mode, 596 phys[0], phys[1], false); 597 if (ret) { 598 v4l2_err(&ic_priv->sd, 599 "prp_setup_channel(out_ch) failed, %d\n", ret); 600 goto unsetup_vb2; 601 } 602 603 ipu_cpmem_dump(priv->out_ch); 604 ipu_ic_dump(priv->ic); 605 ipu_dump(priv->ipu); 606 607 ipu_ic_enable(priv->ic); 608 609 /* set buffers ready */ 610 ipu_idmac_select_buffer(priv->out_ch, 0); 611 ipu_idmac_select_buffer(priv->out_ch, 1); 612 613 /* enable the channels */ 614 ipu_idmac_enable_channel(priv->out_ch); 615 616 /* enable the IC task */ 617 ipu_ic_task_enable(priv->ic); 618 619 return 0; 620 621 unsetup_vb2: 622 prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED); 623 return ret; 624 } 625 626 static void prp_unsetup_norotation(struct prp_priv *priv) 627 { 628 ipu_ic_task_disable(priv->ic); 629 ipu_idmac_disable_channel(priv->out_ch); 630 ipu_ic_disable(priv->ic); 631 } 632 633 static void prp_unsetup(struct prp_priv *priv, 634 enum vb2_buffer_state state) 635 { 636 if (ipu_rot_mode_is_irt(priv->rot_mode)) 637 prp_unsetup_rotation(priv); 638 else 639 prp_unsetup_norotation(priv); 640 641 prp_unsetup_vb2_buf(priv, state); 642 } 643 644 static int prp_start(struct prp_priv *priv) 645 { 646 struct imx_ic_priv *ic_priv = priv->ic_priv; 647 struct imx_media_video_dev *vdev = priv->vdev; 648 struct v4l2_pix_format *outfmt; 649 int ret; 650 651 ret = prp_get_ipu_resources(priv); 652 if (ret) 653 return ret; 654 655 outfmt = &vdev->fmt.fmt.pix; 656 657 ret = imx_media_alloc_dma_buf(priv->md, &priv->underrun_buf, 658 outfmt->sizeimage); 659 if (ret) 660 goto out_put_ipu; 661 662 priv->ipu_buf_num = 0; 663 664 /* init EOF completion waitq */ 665 init_completion(&priv->last_eof_comp); 666 priv->frame_sequence = 0; 667 priv->last_eof = false; 668 priv->nfb4eof = false; 669 670 if (ipu_rot_mode_is_irt(priv->rot_mode)) 671 ret = prp_setup_rotation(priv); 672 else 673 ret = prp_setup_norotation(priv); 674 if (ret) 675 goto out_free_underrun; 676 677 priv->nfb4eof_irq = ipu_idmac_channel_irq(priv->ipu, 678 priv->out_ch, 679 IPU_IRQ_NFB4EOF); 680 ret = devm_request_irq(ic_priv->dev, priv->nfb4eof_irq, 681 prp_nfb4eof_interrupt, 0, 682 "imx-ic-prp-nfb4eof", priv); 683 if (ret) { 684 v4l2_err(&ic_priv->sd, 685 "Error registering NFB4EOF irq: %d\n", ret); 686 goto out_unsetup; 687 } 688 689 if (ipu_rot_mode_is_irt(priv->rot_mode)) 690 priv->eof_irq = ipu_idmac_channel_irq( 691 priv->ipu, priv->rot_out_ch, IPU_IRQ_EOF); 692 else 693 priv->eof_irq = ipu_idmac_channel_irq( 694 priv->ipu, priv->out_ch, IPU_IRQ_EOF); 695 696 ret = devm_request_irq(ic_priv->dev, priv->eof_irq, 697 prp_eof_interrupt, 0, 698 "imx-ic-prp-eof", priv); 699 if (ret) { 700 v4l2_err(&ic_priv->sd, 701 "Error registering eof irq: %d\n", ret); 702 goto out_free_nfb4eof_irq; 703 } 704 705 /* start upstream */ 706 ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 1); 707 ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0; 708 if (ret) { 709 v4l2_err(&ic_priv->sd, 710 "upstream stream on failed: %d\n", ret); 711 goto out_free_eof_irq; 712 } 713 714 /* start the EOF timeout timer */ 715 mod_timer(&priv->eof_timeout_timer, 716 jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); 717 718 return 0; 719 720 out_free_eof_irq: 721 devm_free_irq(ic_priv->dev, priv->eof_irq, priv); 722 out_free_nfb4eof_irq: 723 devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv); 724 out_unsetup: 725 prp_unsetup(priv, VB2_BUF_STATE_QUEUED); 726 out_free_underrun: 727 imx_media_free_dma_buf(priv->md, &priv->underrun_buf); 728 out_put_ipu: 729 prp_put_ipu_resources(priv); 730 return ret; 731 } 732 733 static void prp_stop(struct prp_priv *priv) 734 { 735 struct imx_ic_priv *ic_priv = priv->ic_priv; 736 unsigned long flags; 737 int ret; 738 739 /* mark next EOF interrupt as the last before stream off */ 740 spin_lock_irqsave(&priv->irqlock, flags); 741 priv->last_eof = true; 742 spin_unlock_irqrestore(&priv->irqlock, flags); 743 744 /* 745 * and then wait for interrupt handler to mark completion. 746 */ 747 ret = wait_for_completion_timeout( 748 &priv->last_eof_comp, 749 msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT)); 750 if (ret == 0) 751 v4l2_warn(&ic_priv->sd, "wait last EOF timeout\n"); 752 753 /* stop upstream */ 754 ret = v4l2_subdev_call(priv->src_sd, video, s_stream, 0); 755 if (ret && ret != -ENOIOCTLCMD) 756 v4l2_warn(&ic_priv->sd, 757 "upstream stream off failed: %d\n", ret); 758 759 devm_free_irq(ic_priv->dev, priv->eof_irq, priv); 760 devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv); 761 762 prp_unsetup(priv, VB2_BUF_STATE_ERROR); 763 764 imx_media_free_dma_buf(priv->md, &priv->underrun_buf); 765 766 /* cancel the EOF timeout timer */ 767 del_timer_sync(&priv->eof_timeout_timer); 768 769 prp_put_ipu_resources(priv); 770 } 771 772 static struct v4l2_mbus_framefmt * 773 __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_pad_config *cfg, 774 unsigned int pad, enum v4l2_subdev_format_whence which) 775 { 776 struct imx_ic_priv *ic_priv = priv->ic_priv; 777 778 if (which == V4L2_SUBDEV_FORMAT_TRY) 779 return v4l2_subdev_get_try_format(&ic_priv->sd, cfg, pad); 780 else 781 return &priv->format_mbus[pad]; 782 } 783 784 /* 785 * Applies IC resizer and IDMAC alignment restrictions to output 786 * rectangle given the input rectangle, and depending on given 787 * rotation mode. 788 * 789 * The IC resizer cannot downsize more than 4:1. Note also that 790 * for 90 or 270 rotation, _both_ output width and height must 791 * be aligned by W_ALIGN_SRC, because the intermediate rotation 792 * buffer swaps output width/height, and the final output buffer 793 * does not. 794 * 795 * Returns true if the output rectangle was modified. 796 */ 797 static bool prp_bound_align_output(struct v4l2_mbus_framefmt *outfmt, 798 struct v4l2_mbus_framefmt *infmt, 799 enum ipu_rotate_mode rot_mode) 800 { 801 u32 orig_width = outfmt->width; 802 u32 orig_height = outfmt->height; 803 804 if (ipu_rot_mode_is_irt(rot_mode)) 805 v4l_bound_align_image(&outfmt->width, 806 infmt->height / 4, MAX_H_SRC, 807 W_ALIGN_SRC, 808 &outfmt->height, 809 infmt->width / 4, MAX_W_SRC, 810 W_ALIGN_SRC, S_ALIGN); 811 else 812 v4l_bound_align_image(&outfmt->width, 813 infmt->width / 4, MAX_W_SRC, 814 W_ALIGN_SRC, 815 &outfmt->height, 816 infmt->height / 4, MAX_H_SRC, 817 H_ALIGN_SRC, S_ALIGN); 818 819 return outfmt->width != orig_width || outfmt->height != orig_height; 820 } 821 822 /* 823 * V4L2 subdev operations. 824 */ 825 826 static int prp_enum_mbus_code(struct v4l2_subdev *sd, 827 struct v4l2_subdev_pad_config *cfg, 828 struct v4l2_subdev_mbus_code_enum *code) 829 { 830 if (code->pad >= PRPENCVF_NUM_PADS) 831 return -EINVAL; 832 833 return imx_media_enum_ipu_format(&code->code, code->index, CS_SEL_ANY); 834 } 835 836 static int prp_get_fmt(struct v4l2_subdev *sd, 837 struct v4l2_subdev_pad_config *cfg, 838 struct v4l2_subdev_format *sdformat) 839 { 840 struct prp_priv *priv = sd_to_priv(sd); 841 struct v4l2_mbus_framefmt *fmt; 842 int ret = 0; 843 844 if (sdformat->pad >= PRPENCVF_NUM_PADS) 845 return -EINVAL; 846 847 mutex_lock(&priv->lock); 848 849 fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); 850 if (!fmt) { 851 ret = -EINVAL; 852 goto out; 853 } 854 855 sdformat->format = *fmt; 856 out: 857 mutex_unlock(&priv->lock); 858 return ret; 859 } 860 861 static void prp_try_fmt(struct prp_priv *priv, 862 struct v4l2_subdev_pad_config *cfg, 863 struct v4l2_subdev_format *sdformat, 864 const struct imx_media_pixfmt **cc) 865 { 866 struct v4l2_mbus_framefmt *infmt; 867 868 *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY); 869 if (!*cc) { 870 u32 code; 871 872 imx_media_enum_ipu_format(&code, 0, CS_SEL_ANY); 873 *cc = imx_media_find_ipu_format(code, CS_SEL_ANY); 874 sdformat->format.code = (*cc)->codes[0]; 875 } 876 877 infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which); 878 879 if (sdformat->pad == PRPENCVF_SRC_PAD) { 880 sdformat->format.field = infmt->field; 881 882 prp_bound_align_output(&sdformat->format, infmt, 883 priv->rot_mode); 884 885 /* propagate colorimetry from sink */ 886 sdformat->format.colorspace = infmt->colorspace; 887 sdformat->format.xfer_func = infmt->xfer_func; 888 sdformat->format.quantization = infmt->quantization; 889 sdformat->format.ycbcr_enc = infmt->ycbcr_enc; 890 } else { 891 v4l_bound_align_image(&sdformat->format.width, 892 MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK, 893 &sdformat->format.height, 894 MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK, 895 S_ALIGN); 896 897 imx_media_fill_default_mbus_fields(&sdformat->format, infmt, 898 true); 899 } 900 } 901 902 static int prp_set_fmt(struct v4l2_subdev *sd, 903 struct v4l2_subdev_pad_config *cfg, 904 struct v4l2_subdev_format *sdformat) 905 { 906 struct prp_priv *priv = sd_to_priv(sd); 907 struct imx_media_video_dev *vdev = priv->vdev; 908 const struct imx_media_pixfmt *cc; 909 struct v4l2_pix_format vdev_fmt; 910 struct v4l2_mbus_framefmt *fmt; 911 struct v4l2_rect vdev_compose; 912 int ret = 0; 913 914 if (sdformat->pad >= PRPENCVF_NUM_PADS) 915 return -EINVAL; 916 917 mutex_lock(&priv->lock); 918 919 if (priv->stream_count > 0) { 920 ret = -EBUSY; 921 goto out; 922 } 923 924 prp_try_fmt(priv, cfg, sdformat, &cc); 925 926 fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); 927 *fmt = sdformat->format; 928 929 /* propagate a default format to source pad */ 930 if (sdformat->pad == PRPENCVF_SINK_PAD) { 931 const struct imx_media_pixfmt *outcc; 932 struct v4l2_mbus_framefmt *outfmt; 933 struct v4l2_subdev_format format; 934 935 format.pad = PRPENCVF_SRC_PAD; 936 format.which = sdformat->which; 937 format.format = sdformat->format; 938 prp_try_fmt(priv, cfg, &format, &outcc); 939 940 outfmt = __prp_get_fmt(priv, cfg, PRPENCVF_SRC_PAD, 941 sdformat->which); 942 *outfmt = format.format; 943 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 944 priv->cc[PRPENCVF_SRC_PAD] = outcc; 945 } 946 947 if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) 948 goto out; 949 950 priv->cc[sdformat->pad] = cc; 951 952 /* propagate output pad format to capture device */ 953 imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt, &vdev_compose, 954 &priv->format_mbus[PRPENCVF_SRC_PAD], 955 priv->cc[PRPENCVF_SRC_PAD]); 956 mutex_unlock(&priv->lock); 957 imx_media_capture_device_set_format(vdev, &vdev_fmt, &vdev_compose); 958 959 return 0; 960 out: 961 mutex_unlock(&priv->lock); 962 return ret; 963 } 964 965 static int prp_enum_frame_size(struct v4l2_subdev *sd, 966 struct v4l2_subdev_pad_config *cfg, 967 struct v4l2_subdev_frame_size_enum *fse) 968 { 969 struct prp_priv *priv = sd_to_priv(sd); 970 struct v4l2_subdev_format format = {}; 971 const struct imx_media_pixfmt *cc; 972 int ret = 0; 973 974 if (fse->pad >= PRPENCVF_NUM_PADS || fse->index != 0) 975 return -EINVAL; 976 977 mutex_lock(&priv->lock); 978 979 format.pad = fse->pad; 980 format.which = fse->which; 981 format.format.code = fse->code; 982 format.format.width = 1; 983 format.format.height = 1; 984 prp_try_fmt(priv, cfg, &format, &cc); 985 fse->min_width = format.format.width; 986 fse->min_height = format.format.height; 987 988 if (format.format.code != fse->code) { 989 ret = -EINVAL; 990 goto out; 991 } 992 993 format.format.code = fse->code; 994 format.format.width = -1; 995 format.format.height = -1; 996 prp_try_fmt(priv, cfg, &format, &cc); 997 fse->max_width = format.format.width; 998 fse->max_height = format.format.height; 999 out: 1000 mutex_unlock(&priv->lock); 1001 return ret; 1002 } 1003 1004 static int prp_link_setup(struct media_entity *entity, 1005 const struct media_pad *local, 1006 const struct media_pad *remote, u32 flags) 1007 { 1008 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1009 struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd); 1010 struct prp_priv *priv = ic_priv->task_priv; 1011 struct v4l2_subdev *remote_sd; 1012 int ret = 0; 1013 1014 dev_dbg(ic_priv->dev, "link setup %s -> %s", remote->entity->name, 1015 local->entity->name); 1016 1017 mutex_lock(&priv->lock); 1018 1019 if (local->flags & MEDIA_PAD_FL_SINK) { 1020 if (!is_media_entity_v4l2_subdev(remote->entity)) { 1021 ret = -EINVAL; 1022 goto out; 1023 } 1024 1025 remote_sd = media_entity_to_v4l2_subdev(remote->entity); 1026 1027 if (flags & MEDIA_LNK_FL_ENABLED) { 1028 if (priv->src_sd) { 1029 ret = -EBUSY; 1030 goto out; 1031 } 1032 priv->src_sd = remote_sd; 1033 } else { 1034 priv->src_sd = NULL; 1035 } 1036 1037 goto out; 1038 } 1039 1040 /* this is the source pad */ 1041 1042 /* the remote must be the device node */ 1043 if (!is_media_entity_v4l2_video_device(remote->entity)) { 1044 ret = -EINVAL; 1045 goto out; 1046 } 1047 1048 if (flags & MEDIA_LNK_FL_ENABLED) { 1049 if (priv->sink) { 1050 ret = -EBUSY; 1051 goto out; 1052 } 1053 } else { 1054 priv->sink = NULL; 1055 goto out; 1056 } 1057 1058 priv->sink = remote->entity; 1059 out: 1060 mutex_unlock(&priv->lock); 1061 return ret; 1062 } 1063 1064 static int prp_s_ctrl(struct v4l2_ctrl *ctrl) 1065 { 1066 struct prp_priv *priv = container_of(ctrl->handler, 1067 struct prp_priv, ctrl_hdlr); 1068 struct imx_ic_priv *ic_priv = priv->ic_priv; 1069 enum ipu_rotate_mode rot_mode; 1070 int rotation, ret = 0; 1071 bool hflip, vflip; 1072 1073 mutex_lock(&priv->lock); 1074 1075 rotation = priv->rotation; 1076 hflip = priv->hflip; 1077 vflip = priv->vflip; 1078 1079 switch (ctrl->id) { 1080 case V4L2_CID_HFLIP: 1081 hflip = (ctrl->val == 1); 1082 break; 1083 case V4L2_CID_VFLIP: 1084 vflip = (ctrl->val == 1); 1085 break; 1086 case V4L2_CID_ROTATE: 1087 rotation = ctrl->val; 1088 break; 1089 default: 1090 v4l2_err(&ic_priv->sd, "Invalid control\n"); 1091 ret = -EINVAL; 1092 goto out; 1093 } 1094 1095 ret = ipu_degrees_to_rot_mode(&rot_mode, rotation, hflip, vflip); 1096 if (ret) 1097 goto out; 1098 1099 if (rot_mode != priv->rot_mode) { 1100 struct v4l2_mbus_framefmt outfmt, infmt; 1101 1102 /* can't change rotation mid-streaming */ 1103 if (priv->stream_count > 0) { 1104 ret = -EBUSY; 1105 goto out; 1106 } 1107 1108 outfmt = priv->format_mbus[PRPENCVF_SRC_PAD]; 1109 infmt = priv->format_mbus[PRPENCVF_SINK_PAD]; 1110 1111 if (prp_bound_align_output(&outfmt, &infmt, rot_mode)) { 1112 ret = -EINVAL; 1113 goto out; 1114 } 1115 1116 priv->rot_mode = rot_mode; 1117 priv->rotation = rotation; 1118 priv->hflip = hflip; 1119 priv->vflip = vflip; 1120 } 1121 1122 out: 1123 mutex_unlock(&priv->lock); 1124 return ret; 1125 } 1126 1127 static const struct v4l2_ctrl_ops prp_ctrl_ops = { 1128 .s_ctrl = prp_s_ctrl, 1129 }; 1130 1131 static int prp_init_controls(struct prp_priv *priv) 1132 { 1133 struct imx_ic_priv *ic_priv = priv->ic_priv; 1134 struct v4l2_ctrl_handler *hdlr = &priv->ctrl_hdlr; 1135 int ret; 1136 1137 v4l2_ctrl_handler_init(hdlr, 3); 1138 1139 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_HFLIP, 1140 0, 1, 1, 0); 1141 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_VFLIP, 1142 0, 1, 1, 0); 1143 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_ROTATE, 1144 0, 270, 90, 0); 1145 1146 ic_priv->sd.ctrl_handler = hdlr; 1147 1148 if (hdlr->error) { 1149 ret = hdlr->error; 1150 goto out_free; 1151 } 1152 1153 v4l2_ctrl_handler_setup(hdlr); 1154 return 0; 1155 1156 out_free: 1157 v4l2_ctrl_handler_free(hdlr); 1158 return ret; 1159 } 1160 1161 static int prp_s_stream(struct v4l2_subdev *sd, int enable) 1162 { 1163 struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd); 1164 struct prp_priv *priv = ic_priv->task_priv; 1165 int ret = 0; 1166 1167 mutex_lock(&priv->lock); 1168 1169 if (!priv->src_sd || !priv->sink) { 1170 ret = -EPIPE; 1171 goto out; 1172 } 1173 1174 /* 1175 * enable/disable streaming only if stream_count is 1176 * going from 0 to 1 / 1 to 0. 1177 */ 1178 if (priv->stream_count != !enable) 1179 goto update_count; 1180 1181 dev_dbg(ic_priv->dev, "stream %s\n", enable ? "ON" : "OFF"); 1182 1183 if (enable) 1184 ret = prp_start(priv); 1185 else 1186 prp_stop(priv); 1187 if (ret) 1188 goto out; 1189 1190 update_count: 1191 priv->stream_count += enable ? 1 : -1; 1192 if (priv->stream_count < 0) 1193 priv->stream_count = 0; 1194 out: 1195 mutex_unlock(&priv->lock); 1196 return ret; 1197 } 1198 1199 static int prp_g_frame_interval(struct v4l2_subdev *sd, 1200 struct v4l2_subdev_frame_interval *fi) 1201 { 1202 struct prp_priv *priv = sd_to_priv(sd); 1203 1204 if (fi->pad >= PRPENCVF_NUM_PADS) 1205 return -EINVAL; 1206 1207 mutex_lock(&priv->lock); 1208 fi->interval = priv->frame_interval; 1209 mutex_unlock(&priv->lock); 1210 1211 return 0; 1212 } 1213 1214 static int prp_s_frame_interval(struct v4l2_subdev *sd, 1215 struct v4l2_subdev_frame_interval *fi) 1216 { 1217 struct prp_priv *priv = sd_to_priv(sd); 1218 1219 if (fi->pad >= PRPENCVF_NUM_PADS) 1220 return -EINVAL; 1221 1222 mutex_lock(&priv->lock); 1223 1224 /* No limits on valid frame intervals */ 1225 if (fi->interval.numerator == 0 || fi->interval.denominator == 0) 1226 fi->interval = priv->frame_interval; 1227 else 1228 priv->frame_interval = fi->interval; 1229 1230 mutex_unlock(&priv->lock); 1231 1232 return 0; 1233 } 1234 1235 /* 1236 * retrieve our pads parsed from the OF graph by the media device 1237 */ 1238 static int prp_registered(struct v4l2_subdev *sd) 1239 { 1240 struct prp_priv *priv = sd_to_priv(sd); 1241 int i, ret; 1242 u32 code; 1243 1244 /* get media device */ 1245 priv->md = dev_get_drvdata(sd->v4l2_dev->dev); 1246 1247 for (i = 0; i < PRPENCVF_NUM_PADS; i++) { 1248 priv->pad[i].flags = (i == PRPENCVF_SINK_PAD) ? 1249 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; 1250 1251 /* set a default mbus format */ 1252 imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV); 1253 ret = imx_media_init_mbus_fmt(&priv->format_mbus[i], 1254 640, 480, code, V4L2_FIELD_NONE, 1255 &priv->cc[i]); 1256 if (ret) 1257 return ret; 1258 } 1259 1260 /* init default frame interval */ 1261 priv->frame_interval.numerator = 1; 1262 priv->frame_interval.denominator = 30; 1263 1264 ret = media_entity_pads_init(&sd->entity, PRPENCVF_NUM_PADS, 1265 priv->pad); 1266 if (ret) 1267 return ret; 1268 1269 ret = imx_media_capture_device_register(priv->md, priv->vdev); 1270 if (ret) 1271 return ret; 1272 1273 ret = imx_media_add_video_device(priv->md, priv->vdev); 1274 if (ret) 1275 goto unreg; 1276 1277 ret = prp_init_controls(priv); 1278 if (ret) 1279 goto unreg; 1280 1281 return 0; 1282 unreg: 1283 imx_media_capture_device_unregister(priv->vdev); 1284 return ret; 1285 } 1286 1287 static void prp_unregistered(struct v4l2_subdev *sd) 1288 { 1289 struct prp_priv *priv = sd_to_priv(sd); 1290 1291 imx_media_capture_device_unregister(priv->vdev); 1292 v4l2_ctrl_handler_free(&priv->ctrl_hdlr); 1293 } 1294 1295 static const struct v4l2_subdev_pad_ops prp_pad_ops = { 1296 .init_cfg = imx_media_init_cfg, 1297 .enum_mbus_code = prp_enum_mbus_code, 1298 .enum_frame_size = prp_enum_frame_size, 1299 .get_fmt = prp_get_fmt, 1300 .set_fmt = prp_set_fmt, 1301 }; 1302 1303 static const struct v4l2_subdev_video_ops prp_video_ops = { 1304 .g_frame_interval = prp_g_frame_interval, 1305 .s_frame_interval = prp_s_frame_interval, 1306 .s_stream = prp_s_stream, 1307 }; 1308 1309 static const struct media_entity_operations prp_entity_ops = { 1310 .link_setup = prp_link_setup, 1311 .link_validate = v4l2_subdev_link_validate, 1312 }; 1313 1314 static const struct v4l2_subdev_ops prp_subdev_ops = { 1315 .video = &prp_video_ops, 1316 .pad = &prp_pad_ops, 1317 }; 1318 1319 static const struct v4l2_subdev_internal_ops prp_internal_ops = { 1320 .registered = prp_registered, 1321 .unregistered = prp_unregistered, 1322 }; 1323 1324 static int prp_init(struct imx_ic_priv *ic_priv) 1325 { 1326 struct prp_priv *priv; 1327 1328 priv = devm_kzalloc(ic_priv->dev, sizeof(*priv), GFP_KERNEL); 1329 if (!priv) 1330 return -ENOMEM; 1331 1332 ic_priv->task_priv = priv; 1333 priv->ic_priv = ic_priv; 1334 1335 spin_lock_init(&priv->irqlock); 1336 timer_setup(&priv->eof_timeout_timer, prp_eof_timeout, 0); 1337 1338 priv->vdev = imx_media_capture_device_init(&ic_priv->sd, 1339 PRPENCVF_SRC_PAD); 1340 if (IS_ERR(priv->vdev)) 1341 return PTR_ERR(priv->vdev); 1342 1343 mutex_init(&priv->lock); 1344 1345 return 0; 1346 } 1347 1348 static void prp_remove(struct imx_ic_priv *ic_priv) 1349 { 1350 struct prp_priv *priv = ic_priv->task_priv; 1351 1352 mutex_destroy(&priv->lock); 1353 imx_media_capture_device_remove(priv->vdev); 1354 } 1355 1356 struct imx_ic_ops imx_ic_prpencvf_ops = { 1357 .subdev_ops = &prp_subdev_ops, 1358 .internal_ops = &prp_internal_ops, 1359 .entity_ops = &prp_entity_ops, 1360 .init = prp_init, 1361 .remove = prp_remove, 1362 }; 1363