hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/staging/media/imx/imx-ic-prpencvf.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * V4L2 Capture IC Preprocess Subdev for Freescale i.MX5/6 SOC
34 *
....@@ -6,11 +7,6 @@
67 * for resizing, colorspace conversion, and rotation.
78 *
89 * Copyright (c) 2012-2017 Mentor Graphics Inc.
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License as published by
12
- * the Free Software Foundation; either version 2 of the License, or
13
- * (at your option) any later version.
1410 */
1511 #include <linux/delay.h>
1612 #include <linux/interrupt.h>
....@@ -39,8 +35,8 @@
3935 * has not requested a planar format, we should allow 8 pixel
4036 * alignment at the source pad.
4137 */
42
-#define MIN_W_SINK 176
43
-#define MIN_H_SINK 144
38
+#define MIN_W_SINK 32
39
+#define MIN_H_SINK 32
4440 #define MAX_W_SINK 4096
4541 #define MAX_H_SINK 4096
4642 #define W_ALIGN_SINK 3 /* multiple of 8 pixels */
....@@ -48,13 +44,12 @@
4844
4945 #define MAX_W_SRC 1024
5046 #define MAX_H_SRC 1024
51
-#define W_ALIGN_SRC 4 /* multiple of 16 pixels */
47
+#define W_ALIGN_SRC 1 /* multiple of 2 pixels */
5248 #define H_ALIGN_SRC 1 /* multiple of 2 lines */
5349
5450 #define S_ALIGN 1 /* multiple of 2 */
5551
5652 struct prp_priv {
57
- struct imx_media_dev *md;
5853 struct imx_ic_priv *ic_priv;
5954 struct media_pad pad[PRPENCVF_NUM_PADS];
6055 /* the video device at output pad */
....@@ -64,7 +59,6 @@
6459 struct mutex lock;
6560
6661 /* IPU units we require */
67
- struct ipu_soc *ipu;
6862 struct ipu_ic *ic;
6963 struct ipuv3_channel *out_ch;
7064 struct ipuv3_channel *rot_in_ch;
....@@ -106,6 +100,7 @@
106100 u32 frame_sequence; /* frame sequence counter */
107101 bool last_eof; /* waiting for last EOF at stream off */
108102 bool nfb4eof; /* NFB4EOF encountered during streaming */
103
+ bool interweave_swap; /* swap top/bottom lines when interweaving */
109104 struct completion last_eof_comp;
110105 };
111106
....@@ -159,9 +154,7 @@
159154 struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch;
160155 int ret, task = ic_priv->task_id;
161156
162
- priv->ipu = priv->md->ipu[ic_priv->ipu_id];
163
-
164
- ic = ipu_ic_get(priv->ipu, task);
157
+ ic = ipu_ic_get(ic_priv->ipu, task);
165158 if (IS_ERR(ic)) {
166159 v4l2_err(&ic_priv->sd, "failed to get IC\n");
167160 ret = PTR_ERR(ic);
....@@ -169,7 +162,7 @@
169162 }
170163 priv->ic = ic;
171164
172
- out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch);
165
+ out_ch = ipu_idmac_get(ic_priv->ipu, prp_channel[task].out_ch);
173166 if (IS_ERR(out_ch)) {
174167 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
175168 prp_channel[task].out_ch);
....@@ -178,7 +171,7 @@
178171 }
179172 priv->out_ch = out_ch;
180173
181
- rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch);
174
+ rot_in_ch = ipu_idmac_get(ic_priv->ipu, prp_channel[task].rot_in_ch);
182175 if (IS_ERR(rot_in_ch)) {
183176 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
184177 prp_channel[task].rot_in_ch);
....@@ -187,7 +180,7 @@
187180 }
188181 priv->rot_in_ch = rot_in_ch;
189182
190
- rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch);
183
+ rot_out_ch = ipu_idmac_get(ic_priv->ipu, prp_channel[task].rot_out_ch);
191184 if (IS_ERR(rot_out_ch)) {
192185 v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
193186 prp_channel[task].rot_out_ch);
....@@ -234,6 +227,9 @@
234227
235228 if (ipu_idmac_buffer_is_ready(ch, priv->ipu_buf_num))
236229 ipu_idmac_clear_buffer(ch, priv->ipu_buf_num);
230
+
231
+ if (priv->interweave_swap && ch == priv->out_ch)
232
+ phys += vdev->fmt.fmt.pix.bytesperline;
237233
238234 ipu_cpmem_set_buffer(ch, priv->ipu_buf_num, phys);
239235 }
....@@ -354,20 +350,30 @@
354350 {
355351 struct imx_media_video_dev *vdev = priv->vdev;
356352 const struct imx_media_pixfmt *outcc;
357
- struct v4l2_mbus_framefmt *infmt;
353
+ struct v4l2_mbus_framefmt *outfmt;
358354 unsigned int burst_size;
359355 struct ipu_image image;
356
+ bool interweave;
360357 int ret;
361358
362
- infmt = &priv->format_mbus[PRPENCVF_SINK_PAD];
359
+ outfmt = &priv->format_mbus[PRPENCVF_SRC_PAD];
363360 outcc = vdev->cc;
364361
365362 ipu_cpmem_zero(channel);
366363
367364 memset(&image, 0, sizeof(image));
368365 image.pix = vdev->fmt.fmt.pix;
369
- image.rect.width = image.pix.width;
370
- image.rect.height = image.pix.height;
366
+ image.rect = vdev->compose;
367
+
368
+ /*
369
+ * If the field type at capture interface is interlaced, and
370
+ * the output IDMAC pad is sequential, enable interweave at
371
+ * the IDMAC output channel.
372
+ */
373
+ interweave = V4L2_FIELD_IS_INTERLACED(image.pix.field) &&
374
+ V4L2_FIELD_IS_SEQUENTIAL(outfmt->field);
375
+ priv->interweave_swap = interweave &&
376
+ image.pix.field == V4L2_FIELD_INTERLACED_BT;
371377
372378 if (rot_swap_width_height) {
373379 swap(image.pix.width, image.pix.height);
....@@ -378,15 +384,25 @@
378384 (image.pix.width * outcc->bpp) >> 3;
379385 }
380386
387
+ if (priv->interweave_swap && channel == priv->out_ch) {
388
+ /* start interweave scan at 1st top line (2nd line) */
389
+ image.rect.top = 1;
390
+ }
391
+
381392 image.phys0 = addr0;
382393 image.phys1 = addr1;
383394
384
- if (channel == priv->out_ch || channel == priv->rot_out_ch) {
395
+ /*
396
+ * Skip writing U and V components to odd rows in the output
397
+ * channels for planar 4:2:0 (but not when enabling IDMAC
398
+ * interweaving, they are incompatible).
399
+ */
400
+ if ((channel == priv->out_ch && !interweave) ||
401
+ channel == priv->rot_out_ch) {
385402 switch (image.pix.pixelformat) {
386403 case V4L2_PIX_FMT_YUV420:
387404 case V4L2_PIX_FMT_YVU420:
388405 case V4L2_PIX_FMT_NV12:
389
- /* Skip writing U and V components to odd rows */
390406 ipu_cpmem_skip_odd_chroma_rows(channel);
391407 break;
392408 }
....@@ -409,10 +425,12 @@
409425 if (rot_mode)
410426 ipu_cpmem_set_rotation(channel, rot_mode);
411427
412
- if (image.pix.field == V4L2_FIELD_NONE &&
413
- V4L2_FIELD_HAS_BOTH(infmt->field) &&
414
- channel == priv->out_ch)
415
- ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline);
428
+ if (interweave && channel == priv->out_ch)
429
+ ipu_cpmem_interlaced_scan(channel,
430
+ priv->interweave_swap ?
431
+ -image.pix.bytesperline :
432
+ image.pix.bytesperline,
433
+ image.pix.pixelformat);
416434
417435 ret = ipu_ic_task_idma_init(priv->ic, channel,
418436 image.pix.width, image.pix.height,
....@@ -434,6 +452,7 @@
434452 const struct imx_media_pixfmt *outcc, *incc;
435453 struct v4l2_mbus_framefmt *infmt;
436454 struct v4l2_pix_format *outfmt;
455
+ struct ipu_ic_csc csc;
437456 dma_addr_t phys[2];
438457 int ret;
439458
....@@ -442,23 +461,33 @@
442461 incc = priv->cc[PRPENCVF_SINK_PAD];
443462 outcc = vdev->cc;
444463
445
- ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[0],
464
+ ret = ipu_ic_calc_csc(&csc,
465
+ infmt->ycbcr_enc, infmt->quantization,
466
+ incc->cs,
467
+ outfmt->ycbcr_enc, outfmt->quantization,
468
+ outcc->cs);
469
+ if (ret) {
470
+ v4l2_err(&ic_priv->sd, "ipu_ic_calc_csc failed, %d\n",
471
+ ret);
472
+ return ret;
473
+ }
474
+
475
+ ret = imx_media_alloc_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[0],
446476 outfmt->sizeimage);
447477 if (ret) {
448478 v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[0], %d\n", ret);
449479 return ret;
450480 }
451
- ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[1],
481
+ ret = imx_media_alloc_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[1],
452482 outfmt->sizeimage);
453483 if (ret) {
454484 v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[1], %d\n", ret);
455485 goto free_rot0;
456486 }
457487
458
- ret = ipu_ic_task_init(priv->ic,
488
+ ret = ipu_ic_task_init(priv->ic, &csc,
459489 infmt->width, infmt->height,
460
- outfmt->height, outfmt->width,
461
- incc->cs, outcc->cs);
490
+ outfmt->height, outfmt->width);
462491 if (ret) {
463492 v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret);
464493 goto free_rot1;
....@@ -521,14 +550,16 @@
521550 unsetup_vb2:
522551 prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED);
523552 free_rot1:
524
- imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]);
553
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[1]);
525554 free_rot0:
526
- imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]);
555
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[0]);
527556 return ret;
528557 }
529558
530559 static void prp_unsetup_rotation(struct prp_priv *priv)
531560 {
561
+ struct imx_ic_priv *ic_priv = priv->ic_priv;
562
+
532563 ipu_ic_task_disable(priv->ic);
533564
534565 ipu_idmac_disable_channel(priv->out_ch);
....@@ -539,8 +570,8 @@
539570
540571 ipu_ic_disable(priv->ic);
541572
542
- imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]);
543
- imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]);
573
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[0]);
574
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[1]);
544575 }
545576
546577 static int prp_setup_norotation(struct prp_priv *priv)
....@@ -550,6 +581,7 @@
550581 const struct imx_media_pixfmt *outcc, *incc;
551582 struct v4l2_mbus_framefmt *infmt;
552583 struct v4l2_pix_format *outfmt;
584
+ struct ipu_ic_csc csc;
553585 dma_addr_t phys[2];
554586 int ret;
555587
....@@ -558,10 +590,20 @@
558590 incc = priv->cc[PRPENCVF_SINK_PAD];
559591 outcc = vdev->cc;
560592
561
- ret = ipu_ic_task_init(priv->ic,
593
+ ret = ipu_ic_calc_csc(&csc,
594
+ infmt->ycbcr_enc, infmt->quantization,
595
+ incc->cs,
596
+ outfmt->ycbcr_enc, outfmt->quantization,
597
+ outcc->cs);
598
+ if (ret) {
599
+ v4l2_err(&ic_priv->sd, "ipu_ic_calc_csc failed, %d\n",
600
+ ret);
601
+ return ret;
602
+ }
603
+
604
+ ret = ipu_ic_task_init(priv->ic, &csc,
562605 infmt->width, infmt->height,
563
- outfmt->width, outfmt->height,
564
- incc->cs, outcc->cs);
606
+ outfmt->width, outfmt->height);
565607 if (ret) {
566608 v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret);
567609 return ret;
....@@ -580,7 +622,7 @@
580622
581623 ipu_cpmem_dump(priv->out_ch);
582624 ipu_ic_dump(priv->ic);
583
- ipu_dump(priv->ipu);
625
+ ipu_dump(ic_priv->ipu);
584626
585627 ipu_ic_enable(priv->ic);
586628
....@@ -632,7 +674,7 @@
632674
633675 outfmt = &vdev->fmt.fmt.pix;
634676
635
- ret = imx_media_alloc_dma_buf(priv->md, &priv->underrun_buf,
677
+ ret = imx_media_alloc_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf,
636678 outfmt->sizeimage);
637679 if (ret)
638680 goto out_put_ipu;
....@@ -652,10 +694,10 @@
652694 if (ret)
653695 goto out_free_underrun;
654696
655
- priv->nfb4eof_irq = ipu_idmac_channel_irq(priv->ipu,
697
+ priv->nfb4eof_irq = ipu_idmac_channel_irq(ic_priv->ipu,
656698 priv->out_ch,
657699 IPU_IRQ_NFB4EOF);
658
- ret = devm_request_irq(ic_priv->dev, priv->nfb4eof_irq,
700
+ ret = devm_request_irq(ic_priv->ipu_dev, priv->nfb4eof_irq,
659701 prp_nfb4eof_interrupt, 0,
660702 "imx-ic-prp-nfb4eof", priv);
661703 if (ret) {
....@@ -666,12 +708,12 @@
666708
667709 if (ipu_rot_mode_is_irt(priv->rot_mode))
668710 priv->eof_irq = ipu_idmac_channel_irq(
669
- priv->ipu, priv->rot_out_ch, IPU_IRQ_EOF);
711
+ ic_priv->ipu, priv->rot_out_ch, IPU_IRQ_EOF);
670712 else
671713 priv->eof_irq = ipu_idmac_channel_irq(
672
- priv->ipu, priv->out_ch, IPU_IRQ_EOF);
714
+ ic_priv->ipu, priv->out_ch, IPU_IRQ_EOF);
673715
674
- ret = devm_request_irq(ic_priv->dev, priv->eof_irq,
716
+ ret = devm_request_irq(ic_priv->ipu_dev, priv->eof_irq,
675717 prp_eof_interrupt, 0,
676718 "imx-ic-prp-eof", priv);
677719 if (ret) {
....@@ -696,13 +738,13 @@
696738 return 0;
697739
698740 out_free_eof_irq:
699
- devm_free_irq(ic_priv->dev, priv->eof_irq, priv);
741
+ devm_free_irq(ic_priv->ipu_dev, priv->eof_irq, priv);
700742 out_free_nfb4eof_irq:
701
- devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv);
743
+ devm_free_irq(ic_priv->ipu_dev, priv->nfb4eof_irq, priv);
702744 out_unsetup:
703745 prp_unsetup(priv, VB2_BUF_STATE_QUEUED);
704746 out_free_underrun:
705
- imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
747
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf);
706748 out_put_ipu:
707749 prp_put_ipu_resources(priv);
708750 return ret;
....@@ -734,12 +776,12 @@
734776 v4l2_warn(&ic_priv->sd,
735777 "upstream stream off failed: %d\n", ret);
736778
737
- devm_free_irq(ic_priv->dev, priv->eof_irq, priv);
738
- devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv);
779
+ devm_free_irq(ic_priv->ipu_dev, priv->eof_irq, priv);
780
+ devm_free_irq(ic_priv->ipu_dev, priv->nfb4eof_irq, priv);
739781
740782 prp_unsetup(priv, VB2_BUF_STATE_ERROR);
741783
742
- imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
784
+ imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf);
743785
744786 /* cancel the EOF timeout timer */
745787 del_timer_sync(&priv->eof_timeout_timer);
....@@ -808,7 +850,8 @@
808850 if (code->pad >= PRPENCVF_NUM_PADS)
809851 return -EINVAL;
810852
811
- return imx_media_enum_ipu_format(&code->code, code->index, CS_SEL_ANY);
853
+ return imx_media_enum_ipu_formats(&code->code, code->index,
854
+ PIXFMT_SEL_YUV_RGB);
812855 }
813856
814857 static int prp_get_fmt(struct v4l2_subdev *sd,
....@@ -843,20 +886,21 @@
843886 {
844887 struct v4l2_mbus_framefmt *infmt;
845888
846
- *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY);
889
+ *cc = imx_media_find_ipu_format(sdformat->format.code,
890
+ PIXFMT_SEL_YUV_RGB);
847891 if (!*cc) {
848892 u32 code;
849893
850
- imx_media_enum_ipu_format(&code, 0, CS_SEL_ANY);
851
- *cc = imx_media_find_ipu_format(code, CS_SEL_ANY);
894
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV_RGB);
895
+ *cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB);
896
+
852897 sdformat->format.code = (*cc)->codes[0];
853898 }
854899
855900 infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which);
856901
857902 if (sdformat->pad == PRPENCVF_SRC_PAD) {
858
- if (sdformat->format.field != V4L2_FIELD_NONE)
859
- sdformat->format.field = infmt->field;
903
+ sdformat->format.field = infmt->field;
860904
861905 prp_bound_align_output(&sdformat->format, infmt,
862906 priv->rot_mode);
....@@ -864,8 +908,6 @@
864908 /* propagate colorimetry from sink */
865909 sdformat->format.colorspace = infmt->colorspace;
866910 sdformat->format.xfer_func = infmt->xfer_func;
867
- sdformat->format.quantization = infmt->quantization;
868
- sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
869911 } else {
870912 v4l_bound_align_image(&sdformat->format.width,
871913 MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK,
....@@ -873,9 +915,11 @@
873915 MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK,
874916 S_ALIGN);
875917
876
- imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
877
- true);
918
+ if (sdformat->format.field == V4L2_FIELD_ANY)
919
+ sdformat->format.field = V4L2_FIELD_NONE;
878920 }
921
+
922
+ imx_media_try_colorimetry(&sdformat->format, true);
879923 }
880924
881925 static int prp_set_fmt(struct v4l2_subdev *sd,
....@@ -883,9 +927,7 @@
883927 struct v4l2_subdev_format *sdformat)
884928 {
885929 struct prp_priv *priv = sd_to_priv(sd);
886
- struct imx_media_video_dev *vdev = priv->vdev;
887930 const struct imx_media_pixfmt *cc;
888
- struct v4l2_pix_format vdev_fmt;
889931 struct v4l2_mbus_framefmt *fmt;
890932 int ret = 0;
891933
....@@ -922,19 +964,9 @@
922964 priv->cc[PRPENCVF_SRC_PAD] = outcc;
923965 }
924966
925
- if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
926
- goto out;
967
+ if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
968
+ priv->cc[sdformat->pad] = cc;
927969
928
- priv->cc[sdformat->pad] = cc;
929
-
930
- /* propagate output pad format to capture device */
931
- imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
932
- &priv->format_mbus[PRPENCVF_SRC_PAD],
933
- priv->cc[PRPENCVF_SRC_PAD]);
934
- mutex_unlock(&priv->lock);
935
- imx_media_capture_device_set_format(vdev, &vdev_fmt);
936
-
937
- return 0;
938970 out:
939971 mutex_unlock(&priv->lock);
940972 return ret;
....@@ -989,8 +1021,8 @@
9891021 struct v4l2_subdev *remote_sd;
9901022 int ret = 0;
9911023
992
- dev_dbg(ic_priv->dev, "link setup %s -> %s", remote->entity->name,
993
- local->entity->name);
1024
+ dev_dbg(ic_priv->ipu_dev, "%s: link setup %s -> %s",
1025
+ ic_priv->sd.name, remote->entity->name, local->entity->name);
9941026
9951027 mutex_lock(&priv->lock);
9961028
....@@ -1156,7 +1188,8 @@
11561188 if (priv->stream_count != !enable)
11571189 goto update_count;
11581190
1159
- dev_dbg(ic_priv->dev, "stream %s\n", enable ? "ON" : "OFF");
1191
+ dev_dbg(ic_priv->ipu_dev, "%s: stream %s\n", sd->name,
1192
+ enable ? "ON" : "OFF");
11601193
11611194 if (enable)
11621195 ret = prp_start(priv);
....@@ -1197,32 +1230,30 @@
11971230 if (fi->pad >= PRPENCVF_NUM_PADS)
11981231 return -EINVAL;
11991232
1200
- /* No limits on frame interval */
12011233 mutex_lock(&priv->lock);
1202
- priv->frame_interval = fi->interval;
1234
+
1235
+ /* No limits on valid frame intervals */
1236
+ if (fi->interval.numerator == 0 || fi->interval.denominator == 0)
1237
+ fi->interval = priv->frame_interval;
1238
+ else
1239
+ priv->frame_interval = fi->interval;
1240
+
12031241 mutex_unlock(&priv->lock);
12041242
12051243 return 0;
12061244 }
12071245
1208
-/*
1209
- * retrieve our pads parsed from the OF graph by the media device
1210
- */
12111246 static int prp_registered(struct v4l2_subdev *sd)
12121247 {
12131248 struct prp_priv *priv = sd_to_priv(sd);
1249
+ struct imx_ic_priv *ic_priv = priv->ic_priv;
12141250 int i, ret;
12151251 u32 code;
12161252
1217
- /* get media device */
1218
- priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
1253
+ /* set a default mbus format */
1254
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV);
12191255
12201256 for (i = 0; i < PRPENCVF_NUM_PADS; i++) {
1221
- priv->pad[i].flags = (i == PRPENCVF_SINK_PAD) ?
1222
- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1223
-
1224
- /* set a default mbus format */
1225
- imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
12261257 ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
12271258 640, 480, code, V4L2_FIELD_NONE,
12281259 &priv->cc[i]);
....@@ -1234,26 +1265,26 @@
12341265 priv->frame_interval.numerator = 1;
12351266 priv->frame_interval.denominator = 30;
12361267
1237
- ret = media_entity_pads_init(&sd->entity, PRPENCVF_NUM_PADS,
1238
- priv->pad);
1239
- if (ret)
1240
- return ret;
1268
+ priv->vdev = imx_media_capture_device_init(ic_priv->ipu_dev,
1269
+ &ic_priv->sd,
1270
+ PRPENCVF_SRC_PAD);
1271
+ if (IS_ERR(priv->vdev))
1272
+ return PTR_ERR(priv->vdev);
12411273
12421274 ret = imx_media_capture_device_register(priv->vdev);
12431275 if (ret)
1244
- return ret;
1245
-
1246
- ret = imx_media_add_video_device(priv->md, priv->vdev);
1247
- if (ret)
1248
- goto unreg;
1276
+ goto remove_vdev;
12491277
12501278 ret = prp_init_controls(priv);
12511279 if (ret)
1252
- goto unreg;
1280
+ goto unreg_vdev;
12531281
12541282 return 0;
1255
-unreg:
1283
+
1284
+unreg_vdev:
12561285 imx_media_capture_device_unregister(priv->vdev);
1286
+remove_vdev:
1287
+ imx_media_capture_device_remove(priv->vdev);
12571288 return ret;
12581289 }
12591290
....@@ -1262,6 +1293,8 @@
12621293 struct prp_priv *priv = sd_to_priv(sd);
12631294
12641295 imx_media_capture_device_unregister(priv->vdev);
1296
+ imx_media_capture_device_remove(priv->vdev);
1297
+
12651298 v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
12661299 }
12671300
....@@ -1297,8 +1330,9 @@
12971330 static int prp_init(struct imx_ic_priv *ic_priv)
12981331 {
12991332 struct prp_priv *priv;
1333
+ int i, ret;
13001334
1301
- priv = devm_kzalloc(ic_priv->dev, sizeof(*priv), GFP_KERNEL);
1335
+ priv = devm_kzalloc(ic_priv->ipu_dev, sizeof(*priv), GFP_KERNEL);
13021336 if (!priv)
13031337 return -ENOMEM;
13041338
....@@ -1308,14 +1342,19 @@
13081342 spin_lock_init(&priv->irqlock);
13091343 timer_setup(&priv->eof_timeout_timer, prp_eof_timeout, 0);
13101344
1311
- priv->vdev = imx_media_capture_device_init(&ic_priv->sd,
1312
- PRPENCVF_SRC_PAD);
1313
- if (IS_ERR(priv->vdev))
1314
- return PTR_ERR(priv->vdev);
1315
-
13161345 mutex_init(&priv->lock);
13171346
1318
- return 0;
1347
+ for (i = 0; i < PRPENCVF_NUM_PADS; i++) {
1348
+ priv->pad[i].flags = (i == PRPENCVF_SINK_PAD) ?
1349
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1350
+ }
1351
+
1352
+ ret = media_entity_pads_init(&ic_priv->sd.entity, PRPENCVF_NUM_PADS,
1353
+ priv->pad);
1354
+ if (ret)
1355
+ mutex_destroy(&priv->lock);
1356
+
1357
+ return ret;
13191358 }
13201359
13211360 static void prp_remove(struct imx_ic_priv *ic_priv)
....@@ -1323,7 +1362,6 @@
13231362 struct prp_priv *priv = ic_priv->task_priv;
13241363
13251364 mutex_destroy(&priv->lock);
1326
- imx_media_capture_device_remove(priv->vdev);
13271365 }
13281366
13291367 struct imx_ic_ops imx_ic_prpencvf_ops = {