@@ -1358,7 +1358,13 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
struct v4l2_rect rect;
struct device *dev = icd->parent;
int shift;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ struct media_pad *remote_pad;
+ remote_pad = media_entity_remote_pad(
+ &icd->vdev->entity.pads[0]);
+ fmt.pad = remote_pad->index;
+#endif
ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
if (ret < 0)
return ret;
@@ -1293,6 +1293,7 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
struct v4l2_mbus_framefmt *mf = &fmt.format;
+ int src_pad_idx = -1;
int ret;
sd->grp_id = soc_camera_grp_id(icd);
@@ -1310,8 +1311,30 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
return ret;
}
+#if defined(CONFIG_MEDIA_CONTROLLER)
/* At this point client .probe() should have run already */
+ ret = media_entity_init(&icd->vdev->entity, 1, &icd->pad, 0);
+ if (!ret) {
+ for (src_pad_idx = 0; src_pad_idx < sd->entity.num_pads;
+ src_pad_idx++)
+ if (sd->entity.pads[src_pad_idx].flags
+ == MEDIA_PAD_FL_SOURCE)
+ break;
+
+ if (src_pad_idx < sd->entity.num_pads) {
+ if (!media_entity_create_link(
+ &icd->vdev->entity, 0,
+ &sd->entity, src_pad_idx,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED)) {
+ ret = soc_camera_init_user_formats(icd);
+ }
+ }
+ }
+#else
ret = soc_camera_init_user_formats(icd);
+#endif
+
if (ret < 0)
goto eusrfmt;
@@ -1322,6 +1345,7 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
goto evidstart;
/* Try to improve our guess of a reasonable window format */
+ fmt.pad = src_pad_idx;
if (!v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) {
icd->user_width = mf->width;
icd->user_height = mf->height;
@@ -1335,6 +1359,9 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
evidstart:
soc_camera_free_user_formats(icd);
eusrfmt:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&icd->vdev->entity);
+#endif
soc_camera_remove_device(icd);
return ret;
@@ -1856,6 +1883,11 @@ static int soc_camera_remove(struct soc_camera_device *icd)
if (icd->num_user_formats)
soc_camera_free_user_formats(icd);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ if (icd->vdev->entity.num_pads)
+ media_entity_cleanup(&icd->vdev->entity);
+#endif
+
if (icd->clk) {
/* For the synchronous case */
v4l2_clk_unregister(icd->clk);
@@ -42,6 +42,7 @@ struct soc_camera_device {
unsigned char devnum; /* Device number per host */
struct soc_camera_sense *sense; /* See comment in struct definition */
struct video_device *vdev;
+ struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
const struct soc_camera_format_xlate *current_fmt;
struct soc_camera_format_xlate *user_formats;