static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
 {
        struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint;
-       struct device_node *ep_node;
        char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES * 2];
+       struct device_node *ep_node;
        unsigned int i;
        int ret;
 
                endpoint->bus.mipi_csi2.flags);
 
        /* Retrieve the connected device and store it for later use. */
-       phy->sensor_node = of_graph_get_remote_port_parent(ep_node);
+       phy->sensor_ep_node = of_graph_get_remote_endpoint(ep_node);
+       phy->sensor_node = of_graph_get_port_parent(phy->sensor_ep_node);
        if (!phy->sensor_node) {
                phy_dbg(3, phy, "Can't get remote parent\n");
+               of_node_put(phy->sensor_ep_node);
                ret = -EINVAL;
                goto done;
        }
        return ret;
 }
 
+/* ------------------------------------------------------------------
+ *     V4L2 Subdev Operations
+ * ------------------------------------------------------------------
+ */
+
+static const struct v4l2_subdev_ops cal_camerarx_subdev_ops = {
+};
+
+/* ------------------------------------------------------------------
+ *     Create and Destroy
+ * ------------------------------------------------------------------
+ */
+
 struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
                                         unsigned int instance)
 {
        struct platform_device *pdev = to_platform_device(cal->dev);
        struct cal_camerarx *phy;
+       struct v4l2_subdev *sd;
        int ret;
 
        phy = kzalloc(sizeof(*phy), GFP_KERNEL);
        if (ret)
                goto error;
 
+       /* Initialize the V4L2 subdev and media entity. */
+       sd = &phy->subdev;
+       v4l2_subdev_init(sd, &cal_camerarx_subdev_ops);
+       sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+       snprintf(sd->name, sizeof(sd->name), "CAMERARX%u", instance);
+       sd->dev = cal->dev;
+
+       phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+       phy->pads[CAL_CAMERARX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads),
+                                    phy->pads);
+       if (ret)
+               goto error;
+
+       ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd);
+       if (ret)
+               goto error;
+
        return phy;
 
 error:
+       media_entity_cleanup(&phy->subdev.entity);
        kfree(phy);
        return ERR_PTR(ret);
 }
        if (!phy)
                return;
 
+       v4l2_device_unregister_subdev(&phy->subdev);
+       media_entity_cleanup(&phy->subdev.entity);
+       of_node_put(phy->sensor_ep_node);
        of_node_put(phy->sensor_node);
        kfree(phy);
 }
 
                return ret;
        }
 
+       ret = media_create_pad_link(&ctx->phy->subdev.entity,
+                                   CAL_CAMERARX_PAD_SOURCE,
+                                   &vfd->entity, 0,
+                                   MEDIA_LNK_FL_IMMUTABLE |
+                                   MEDIA_LNK_FL_ENABLED);
+       if (ret) {
+               ctx_err(ctx, "Failed to create media link for context %u\n",
+                       ctx->index);
+               video_unregister_device(vfd);
+               return ret;
+       }
+
        ctx_info(ctx, "V4L2 device registered as %s\n",
                 video_device_node_name(vfd));
 
 
                                    struct v4l2_async_subdev *asd)
 {
        struct cal_camerarx *phy = to_cal_asd(asd)->phy;
+       int pad;
+       int ret;
 
        if (phy->sensor) {
                phy_info(phy, "Rejecting subdev %s (Already set!!)",
        phy->sensor = subdev;
        phy_dbg(1, phy, "Using sensor %s for capture\n", subdev->name);
 
+       pad = media_entity_get_fwnode_pad(&subdev->entity,
+                                         of_fwnode_handle(phy->sensor_ep_node),
+                                         MEDIA_PAD_FL_SOURCE);
+       if (pad < 0) {
+               phy_err(phy, "Sensor %s has no connected source pad\n",
+                       subdev->name);
+               return pad;
+       }
+
+       ret = media_create_pad_link(&subdev->entity, pad,
+                                   &phy->subdev.entity, CAL_CAMERARX_PAD_SINK,
+                                   MEDIA_LNK_FL_IMMUTABLE |
+                                   MEDIA_LNK_FL_ENABLED);
+       if (ret) {
+               phy_err(phy, "Failed to create media link for sensor %s\n",
+                       subdev->name);
+               return ret;
+       }
+
        return 0;
 }
 
        cal_get_hwinfo(cal);
        pm_runtime_put_sync(&pdev->dev);
 
+       /* Initialize the media device. */
+       ret = cal_media_init(cal);
+       if (ret < 0)
+               goto error_pm_runtime;
+
        /* Create CAMERARX PHYs. */
        for (i = 0; i < cal->data->num_csi2_phy; ++i) {
                cal->phy[i] = cal_camerarx_create(cal, i);
                goto error_camerarx;
        }
 
-       /* Initialize the media device. */
-       ret = cal_media_init(cal);
-       if (ret < 0)
-               goto error_camerarx;
-
        /* Create contexts. */
        for (i = 0; i < cal->data->num_csi2_phy; ++i) {
                if (!cal->phy[i]->sensor_node)
                        cal_ctx_v4l2_cleanup(ctx);
        }
 
-       cal_media_cleanup(cal);
-
 error_camerarx:
        for (i = 0; i < ARRAY_SIZE(cal->phy); i++)
                cal_camerarx_destroy(cal->phy[i]);
 
+       cal_media_cleanup(cal);
+
 error_pm_runtime:
        pm_runtime_disable(&pdev->dev);
 
 
 #include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
 #include <media/videobuf2-v4l2.h>
 
 #define CAL_MODULE_NAME                        "cal"
 #define MAX_WIDTH_BYTES                        (8192 * 8)
 #define MAX_HEIGHT_LINES               16383
 
+#define CAL_CAMERARX_PAD_SINK          0
+#define CAL_CAMERARX_PAD_SOURCE                1
+
 struct device;
 struct device_node;
 struct resource;
 struct regmap;
 struct regmap_fied;
-struct v4l2_subdev;
 
 /* CTRL_CORE_CAMERRX_CONTROL register field id */
 enum cal_camerarx_field {
        unsigned int            instance;
 
        struct v4l2_fwnode_endpoint     endpoint;
+       struct device_node      *sensor_ep_node;
        struct device_node      *sensor_node;
        struct v4l2_subdev      *sensor;
+
+       struct v4l2_subdev      subdev;
+       struct media_pad        pads[2];
 };
 
 struct cal_dev {