#define OV5670_REG_SOFTWARE_RST                0x0103
 #define OV5670_SOFTWARE_RST            0x01
 
+#define OV5670_MIPI_SC_CTRL0_REG               0x3018
+#define OV5670_MIPI_SC_CTRL0_LANES(v)          ((((v) - 1) << 5) & \
+                                                GENMASK(7, 5))
+#define OV5670_MIPI_SC_CTRL0_MIPI_EN           BIT(4)
+#define OV5670_MIPI_SC_CTRL0_RESERVED          BIT(1)
+
 /* vertical-timings from sensor */
 #define OV5670_REG_VTS                 0x380e
 #define OV5670_VTS_30FPS               0x0808 /* default for 30 fps */
 };
 
 struct ov5670_link_freq_config {
-       u32 pixel_rate;
        const struct ov5670_reg_list reg_list;
 };
 
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
        {0x3005, 0xf0},
        {0x3007, 0x00},
        {0x3015, 0x0f},
-       {0x3018, 0x32},
        {0x301a, 0xf0},
        {0x301b, 0xf0},
        {0x301c, 0xf0},
 #define OV5670_LINK_FREQ_422MHZ_INDEX  0
 static const struct ov5670_link_freq_config link_freq_configs[] = {
        {
-               /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
-               .pixel_rate = (OV5670_LINK_FREQ_422MHZ * 2 * 2) / 10,
                .reg_list = {
                        .num_of_regs = ARRAY_SIZE(mipi_data_rate_840mbps),
                        .regs = mipi_data_rate_840mbps,
 struct ov5670 {
        struct v4l2_subdev sd;
        struct media_pad pad;
+       struct v4l2_fwnode_endpoint endpoint;
 
        struct v4l2_ctrl_handler ctrl_handler;
        /* V4L2 Controls */
 /* Initialize control handlers */
 static int ov5670_init_controls(struct ov5670 *ov5670)
 {
+       struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
+               &ov5670->endpoint.bus.mipi_csi2;
        struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
        struct v4l2_fwnode_device_properties props;
        struct v4l2_ctrl_handler *ctrl_hdlr;
+       unsigned int lanes_count;
+       s64 mipi_pixel_rate;
        s64 vblank_max;
        s64 vblank_def;
        s64 vblank_min;
                ov5670->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
        /* By default, V4L2_CID_PIXEL_RATE is read only */
+       lanes_count = bus_mipi_csi2->num_data_lanes;
+       mipi_pixel_rate = OV5670_LINK_FREQ_422MHZ * 2 * lanes_count / 10;
+
        ov5670->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops,
                                               V4L2_CID_PIXEL_RATE,
-                                              link_freq_configs[0].pixel_rate,
-                                              link_freq_configs[0].pixel_rate,
+                                              mipi_pixel_rate,
+                                              mipi_pixel_rate,
                                               1,
-                                              link_freq_configs[0].pixel_rate);
+                                              mipi_pixel_rate);
 
        vblank_max = OV5670_VTS_MAX - ov5670->cur_mode->height;
        vblank_def = ov5670->cur_mode->vts_def - ov5670->cur_mode->height;
                                 struct v4l2_subdev_format *fmt)
 {
        struct ov5670 *ov5670 = to_ov5670(sd);
+       struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
+               &ov5670->endpoint.bus.mipi_csi2;
        const struct ov5670_mode *mode;
+       unsigned int lanes_count;
+       s64 mipi_pixel_rate;
        s32 vblank_def;
+       s64 link_freq;
        s32 h_blank;
 
        mutex_lock(&ov5670->mutex);
        } else {
                ov5670->cur_mode = mode;
                __v4l2_ctrl_s_ctrl(ov5670->link_freq, mode->link_freq_index);
+
+               lanes_count = bus_mipi_csi2->num_data_lanes;
+               link_freq = link_freq_menu_items[mode->link_freq_index];
+               /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
+               mipi_pixel_rate = div_s64(link_freq * 2 * lanes_count, 10);
                __v4l2_ctrl_s_ctrl_int64(
                        ov5670->pixel_rate,
-                       link_freq_configs[mode->link_freq_index].pixel_rate);
+                       mipi_pixel_rate);
                /* Update limits and set FPS to default */
                vblank_def = ov5670->cur_mode->vts_def -
                             ov5670->cur_mode->height;
        return 0;
 }
 
+static int ov5670_mipi_configure(struct ov5670 *ov5670)
+{
+       struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
+               &ov5670->endpoint.bus.mipi_csi2;
+       unsigned int lanes_count = bus_mipi_csi2->num_data_lanes;
+
+       return ov5670_write_reg(ov5670, OV5670_MIPI_SC_CTRL0_REG,
+                               OV5670_REG_VALUE_08BIT,
+                               OV5670_MIPI_SC_CTRL0_LANES(lanes_count) |
+                               OV5670_MIPI_SC_CTRL0_MIPI_EN |
+                               OV5670_MIPI_SC_CTRL0_RESERVED);
+}
+
 /* Prepare streaming by writing default values and customized values */
 static int ov5670_start_streaming(struct ov5670 *ov5670)
 {
                return ret;
        }
 
+       ret = ov5670_mipi_configure(ov5670);
+       if (ret) {
+               dev_err(&client->dev, "%s failed to configure MIPI\n", __func__);
+               return ret;
+       }
+
        ret = __v4l2_ctrl_handler_setup(ov5670->sd.ctrl_handler);
        if (ret)
                return ret;
 
 static int ov5670_probe(struct i2c_client *client)
 {
+       struct fwnode_handle *handle;
        struct ov5670 *ov5670;
        u32 input_clk = 0;
        bool full_power;
        if (ret)
                return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");
 
+       /* Graph Endpoint */
+       handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+       if (!handle)
+               return dev_err_probe(&client->dev, -ENXIO, "Endpoint for node get failed\n");
+
+       ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
+       ov5670->endpoint.bus.mipi_csi2.num_data_lanes = 2;
+
+       ret = v4l2_fwnode_endpoint_alloc_parse(handle, &ov5670->endpoint);
+       fwnode_handle_put(handle);
+       if (ret)
+               return dev_err_probe(&client->dev, ret, "Endpoint parse failed\n");
+
        full_power = acpi_dev_state_d0(&client->dev);
        if (full_power) {
                ret = ov5670_runtime_resume(&client->dev);
-               if (ret)
-                       return dev_err_probe(&client->dev, ret, "Power up failed\n");
+               if (ret) {
+                       dev_err_probe(&client->dev, ret, "Power up failed\n");
+                       goto error_endpoint;
+               }
 
                /* Check module identity */
                ret = ov5670_identify_module(ov5670);
        if (full_power)
                ov5670_runtime_suspend(&client->dev);
 
+error_endpoint:
+       v4l2_fwnode_endpoint_free(&ov5670->endpoint);
+
        return ret;
 }
 
 
        pm_runtime_disable(&client->dev);
        ov5670_runtime_suspend(&client->dev);
+
+       v4l2_fwnode_endpoint_free(&ov5670->endpoint);
 }
 
 static const struct dev_pm_ops ov5670_pm_ops = {