static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t                              rc = 0;
	struct msm_camera_sensor_board_info *sensordata = NULL;
	struct device_node                  *of_node = s_ctrl->of_node;
	uint32_t cell_id;

	s_ctrl->sensordata = kzalloc(sizeof(*sensordata), GFP_KERNEL);
	if (!s_ctrl->sensordata) {
		pr_err("failed: no memory");
		return -ENOMEM;
	}

	sensordata = s_ctrl->sensordata;

	/*
	 * Read cell index - this cell index will be the camera slot where
	 * this camera will be mounted
	 */
	rc = of_property_read_u32(of_node, "cell-index", &cell_id);
	if (rc < 0) {
		pr_err("failed: cell-index rc %d", rc);
		goto FREE_SENSOR_DATA;
	}
	s_ctrl->id = cell_id;

	/* Validate cell_id */
	if (cell_id >= MAX_CAMERAS) {
		pr_err("failed: invalid cell_id %d", cell_id);
		rc = -EINVAL;
		goto FREE_SENSOR_DATA;
	}

	/* Check whether g_sctrl is already filled for this cell_id */
	if (g_sctrl[cell_id]) {
		pr_err("failed: sctrl already filled for cell_id %d", cell_id);
		rc = -EINVAL;
		goto FREE_SENSOR_DATA;
	}

	/* Read subdev info */
	rc = msm_sensor_get_sub_module_index(of_node, &sensordata->sensor_info);
	if (rc < 0) {
		pr_err("failed");
		goto FREE_SENSOR_DATA;
	}

	/* Read vreg information */
	rc = msm_camera_get_dt_vreg_data(of_node,
		&sensordata->power_info.cam_vreg,
		&sensordata->power_info.num_vreg);
	if (rc < 0) {
		pr_err("failed: msm_camera_get_dt_vreg_data rc %d", rc);
		goto FREE_SUB_MODULE_DATA;
	}

	/* Read gpio information */
	rc = msm_sensor_driver_get_gpio_data(sensordata, of_node);
	if (rc < 0) {
		pr_err("failed: msm_sensor_driver_get_gpio_data rc %d", rc);
		goto FREE_VREG_DATA;
	}

	/* Get CCI master */
	rc = of_property_read_u32(of_node, "qcom,cci-master",
		&s_ctrl->cci_i2c_master);
	CDBG("qcom,cci-master %d, rc %d", s_ctrl->cci_i2c_master, rc);
	if (rc < 0) {
		/* Set default master 0 */
		s_ctrl->cci_i2c_master = MASTER_0;
		rc = 0;
	}

	/* Get mount angle */
	if (0 > of_property_read_u32(of_node, "qcom,mount-angle",
		&sensordata->sensor_info->sensor_mount_angle)) {
		/* Invalidate mount angle flag */
		sensordata->sensor_info->is_mount_angle_valid = 0;
		sensordata->sensor_info->sensor_mount_angle = 0;
	} else {
		sensordata->sensor_info->is_mount_angle_valid = 1;
	}
	CDBG("%s qcom,mount-angle %d\n", __func__,
		sensordata->sensor_info->sensor_mount_angle);
	if (0 > of_property_read_u32(of_node, "qcom,sensor-position",
		&sensordata->sensor_info->position)) {
		CDBG("%s:%d Invalid sensor position\n", __func__, __LINE__);
		sensordata->sensor_info->position = INVALID_CAMERA_B;
	}
	if (0 > of_property_read_u32(of_node, "qcom,sensor-mode",
		&sensordata->sensor_info->modes_supported)) {
		CDBG("%s:%d Invalid sensor mode supported\n",
			__func__, __LINE__);
		sensordata->sensor_info->modes_supported = CAMERA_MODE_INVALID;
	}
	/* Get vdd-cx regulator */
	/*Optional property, don't return error if absent */
	of_property_read_string(of_node, "qcom,vdd-cx-name",
		&sensordata->misc_regulator);
	CDBG("qcom,misc_regulator %s", sensordata->misc_regulator);

	s_ctrl->set_mclk_23880000 = of_property_read_bool(of_node,
						"qcom,mclk-23880000");

	CDBG("%s qcom,mclk-23880000 = %d\n", __func__,
		s_ctrl->set_mclk_23880000);

	return rc;

FREE_VREG_DATA:
	kfree(sensordata->power_info.cam_vreg);
FREE_SUB_MODULE_DATA:
	kfree(sensordata->sensor_info);
FREE_SENSOR_DATA:
	kfree(sensordata);
	return rc;
}
static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
        struct platform_device *pdev)
{
    int32_t                              rc = 0;
    struct msm_camera_sensor_board_info *sensordata = NULL;
    struct device_node                  *of_node = pdev->dev.of_node;

    s_ctrl->sensordata = kzalloc(sizeof(*sensordata), GFP_KERNEL);
    if (!s_ctrl->sensordata) {
        pr_err("failed: no memory");
        return -ENOMEM;
    }

    sensordata = s_ctrl->sensordata;


    /*
     * Read cell index - this cell index will be the camera slot where
     * this camera will be mounted
     */
    rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
    if (rc < 0) {
        pr_err("failed: cell-index rc %d", rc);
        goto FREE_SENSOR_DATA;
    }

    /* Validate pdev->id */
    if (pdev->id >= MAX_CAMERAS) {
        pr_err("failed: invalid pdev->id %d", pdev->id);
        rc = -EINVAL;
        goto FREE_SENSOR_DATA;
    }

    /* Check whether g_sctrl is already filled for this pdev id */
    if (g_sctrl[pdev->id]) {
        pr_err("failed: sctrl already filled for id %d", pdev->id);
        rc = -EINVAL;
        goto FREE_SENSOR_DATA;
    }

    /* Read subdev info */
    rc = msm_sensor_get_sub_module_index(of_node, &sensordata->sensor_info);
    if (rc < 0) {
        pr_err("failed");
        goto FREE_SENSOR_DATA;
    }

    /* Read vreg information */
    rc = msm_camera_get_dt_vreg_data(of_node,
                                     &sensordata->power_info.cam_vreg,
                                     &sensordata->power_info.num_vreg);
    if (rc < 0) {
        pr_err("failed: msm_camera_get_dt_vreg_data rc %d", rc);
        goto FREE_SUB_MODULE_DATA;
    }

    /* Read gpio information */
    rc = msm_sensor_driver_get_gpio_data(sensordata, of_node);
    if (rc < 0) {
        pr_err("failed: msm_sensor_driver_get_gpio_data rc %d", rc);
        goto FREE_VREG_DATA;
    }

    /* Get CCI master */
    rc = of_property_read_u32(of_node, "qcom,cci-master",
                              &s_ctrl->cci_i2c_master);
    CDBG("qcom,cci-master %d, rc %d", s_ctrl->cci_i2c_master, rc);
    if (rc < 0) {
        /* Set default master 0 */
        s_ctrl->cci_i2c_master = MASTER_0;
        rc = 0;
    }

    /* Get mount angle */
    rc = of_property_read_u32(of_node, "qcom,mount-angle",
                              &sensordata->sensor_info->sensor_mount_angle);
    CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
         sensordata->sensor_info->sensor_mount_angle, rc);
    if (rc < 0) {
        sensordata->sensor_info->is_mount_angle_valid = 0;
        sensordata->sensor_info->sensor_mount_angle = 0;
        rc = 0;
    } else {
        sensordata->sensor_info->is_mount_angle_valid = 1;
    }

    /* Get vdd-cx regulator */
    /*Optional property, don't return error if absent */
    of_property_read_string(of_node, "qcom,vdd-cx-name",
                            &sensordata->misc_regulator);
    CDBG("qcom,misc_regulator %s", sensordata->misc_regulator);

    return rc;

FREE_VREG_DATA:
    kfree(sensordata->power_info.cam_vreg);
FREE_SUB_MODULE_DATA:
    kfree(sensordata->sensor_info);
FREE_SENSOR_DATA:
    kfree(sensordata);
    return rc;
}