static int32_t msm_sensor_driver_create_v4l_subdev
			(struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t rc = 0;
	uint32_t session_id = 0;

	rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
	if (rc < 0) {
		pr_err("failed: camera_init_v4l2 rc %d", rc);
		return rc;
	}
	CDBG("rc %d session_id %d", rc, session_id);
	s_ctrl->sensordata->sensor_info->session_id = session_id;

	/* Create /dev/v4l-subdevX device */
	v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
	snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
		s_ctrl->sensordata->sensor_name);
	v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
	s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
	s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
	s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
	msm_sd_register(&s_ctrl->msm_sd);
	return rc;
}
static int32_t msm_sensor_driver_create_i2c_v4l_subdev
			(struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t rc = 0;
	uint32_t session_id = 0;
	struct i2c_client *client = s_ctrl->sensor_i2c_client->client;

	CDBG("%s %s I2c probe succeeded\n", __func__, client->name);
	rc = camera_init_v4l2(&client->dev, &session_id);
	if (rc < 0) {
		pr_err("failed: camera_init_i2c_v4l2 rc %d", rc);
		return rc;
	}
	CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
	snprintf(s_ctrl->msm_sd.sd.name,
		sizeof(s_ctrl->msm_sd.sd.name), "%s",
		s_ctrl->sensordata->sensor_name);
	v4l2_i2c_subdev_init(&s_ctrl->msm_sd.sd, client,
		s_ctrl->sensor_v4l2_subdev_ops);
	v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client);
	s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
	s_ctrl->msm_sd.sd.entity.name =	s_ctrl->msm_sd.sd.name;
	s_ctrl->sensordata->sensor_info->session_id = session_id;
	s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
	msm_sd_register(&s_ctrl->msm_sd);
	CDBG("%s:%d\n", __func__, __LINE__);
	return rc;
}
/* static function definition */
int32_t msm_sensor_driver_probe(void *setting)
{
    int32_t                              rc = 0;
    int32_t                              is_power_off = 0;
    uint16_t                             i = 0, size = 0, off_size = 0;
    uint32_t                             session_id = 0;
    struct msm_sensor_ctrl_t            *s_ctrl = NULL;
    struct msm_camera_cci_client        *cci_client = NULL;
    struct msm_camera_sensor_slave_info *slave_info = NULL;
    struct msm_sensor_power_setting     *power_setting = NULL;
    struct msm_sensor_power_setting     *power_off_setting = NULL;
    struct msm_camera_slave_info        *camera_info = NULL;
    struct msm_camera_power_ctrl_t      *power_info = NULL;

    /* Validate input parameters */
    if (!setting) {
        pr_err("failed: slave_info %p", setting);
        return -EINVAL;
    }

    /* Allocate memory for slave info */
    slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
    if (!slave_info) {
        pr_err("failed: no memory slave_info %p", slave_info);
        return -ENOMEM;
    }

    if (copy_from_user(slave_info, (void *)setting, sizeof(*slave_info))) {
        pr_err("failed: copy_from_user");
        rc = -EFAULT;
        goto FREE_SLAVE_INFO;
    }

    /* Print slave info */
    pr_err("camera id %d", slave_info->camera_id);
    pr_err("slave_addr %x", slave_info->slave_addr);
    CDBG("addr_type %d", slave_info->addr_type);
    CDBG("sensor_id_reg_addr %x",
         slave_info->sensor_id_info.sensor_id_reg_addr);
    CDBG("sensor_id %x", slave_info->sensor_id_info.sensor_id);
    CDBG("size %x", slave_info->power_setting_array.size);

    /* Validate camera id */
    if (slave_info->camera_id >= MAX_CAMERAS) {
        pr_err("failed: invalid camera id %d max %d",
               slave_info->camera_id, MAX_CAMERAS);
        rc = -EINVAL;
        goto FREE_SLAVE_INFO;
    }

    /* Extract s_ctrl from camera id */
    s_ctrl = g_sctrl[slave_info->camera_id];
    if (!s_ctrl) {
        pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
               slave_info->camera_id);
        rc = -EINVAL;
        goto FREE_SLAVE_INFO;
    }

#if defined (CONFIG_SEC_MILLET_PROJECT) || defined(CONFIG_SEC_MATISSE_PROJECT) \
	|| defined(CONFIG_SEC_DEGAS_PROJECT) || defined (CONFIG_SEC_T8_PROJECT) \
	|| defined (CONFIG_SEC_T10_PROJECT) \
	|| defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) \
	|| defined (CONFIG_SEC_RUBENS_PROJECT)
    if(slave_info->camera_id == CAMERA_2) {
#if defined(CONFIG_SR130PC20)
        s_ctrl->func_tbl = &sr130pc20_sensor_func_tbl ;
        sr130pc20_set_default_settings();
#endif
    } else if (slave_info->camera_id == CAMERA_0) {
#if defined(CONFIG_SR352)
        s_ctrl->func_tbl = &sr352_sensor_func_tbl ;
        sr352_set_default_settings();
#endif
#if defined(CONFIG_SR200PC20)
        s_ctrl->func_tbl = &sr200pc20_sensor_func_tbl ;
        sr200pc20_set_default_settings();
#endif
    }
#elif defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \
	|| defined (CONFIG_MACH_AFYONLTE_MTR)
    if(slave_info->camera_id == CAMERA_2) {
#if defined(CONFIG_S5K4ECGX)
        s_ctrl->func_tbl = &sr030pc50_sensor_func_tbl;
#endif
    } else if (slave_info->camera_id == CAMERA_0) {
#if defined(CONFIG_SR030PC50)
        s_ctrl->func_tbl = &s5k4ecgx_sensor_func_tbl;
#endif
    }

#elif defined(CONFIG_MACH_CRATERQ_CHN_OPEN)
    if(slave_info->camera_id == CAMERA_2) {
        s_ctrl->func_tbl = &sr200pc20_sensor_func_tbl ;

    }
#elif defined(CONFIG_MACH_VICTORLTE_CTC)
    if (slave_info->camera_id == CAMERA_0) {
        s_ctrl->func_tbl = &s5k4ecgx_sensor_func_tbl;
    }
#endif

    CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);

    if (s_ctrl->is_probe_succeed == 1) {
        /*
         * Different sensor on this camera slot has been connected
         * and probe already succeeded for that sensor. Ignore this
         * probe
         */
        pr_err("slot %d has some other sensor", slave_info->camera_id);
        kfree(slave_info);
        return 0;
    }

    size = slave_info->power_setting_array.size;
    /* Allocate memory for power setting */
    power_setting = kzalloc(sizeof(*power_setting) * size, GFP_KERNEL);
    if (!power_setting) {
        pr_err("failed: no memory power_setting %p", power_setting);
        rc = -ENOMEM;
        goto FREE_SLAVE_INFO;
    }

    if (copy_from_user(power_setting,
                       (void *)slave_info->power_setting_array.power_setting,
                       sizeof(*power_setting) * size)) {
        pr_err("failed: copy_from_user");
        rc = -EFAULT;
        goto FREE_POWER_SETTING;
    }

    /* Print power setting */
    for (i = 0; i < size; i++) {
        CDBG("seq_type %d seq_val %d config_val %ld delay %d",
             power_setting[i].seq_type, power_setting[i].seq_val,
             power_setting[i].config_val, power_setting[i].delay);
    }

    off_size = slave_info->power_setting_array.off_size;
    if (off_size > 0) {
        /* Allocate memory for power setting */
        power_off_setting = kzalloc(sizeof(*power_off_setting) * off_size, GFP_KERNEL);
        if (!power_off_setting) {
            pr_err("failed: no memory power_setting %p", power_off_setting);
            rc = -ENOMEM;
            goto FREE_POWER_SETTING;
        }

        if (copy_from_user(power_off_setting,
                           (void *)slave_info->power_setting_array.power_off_setting,
                           sizeof(*power_off_setting) * off_size)) {
            pr_err("failed: copy_from_user");
            rc = -EFAULT;
            goto FREE_POWER_OFF_SETTING;
        }

        /* Print power setting */
        for (i = 0; i < off_size; i++) {
            CDBG("seq_type %d seq_val %d config_val %ld delay %d",
                 power_off_setting[i].seq_type, power_off_setting[i].seq_val,
                 power_off_setting[i].config_val, power_off_setting[i].delay);
        }
        is_power_off = 1;
    }

    camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
    if (!camera_info) {
        pr_err("failed: no memory slave_info %p", camera_info);
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }

    /* Fill power up setting and power up setting size */
    power_info = &s_ctrl->sensordata->power_info;
    power_info->power_setting = power_setting;
    power_info->power_setting_size = size;
    power_info->power_off_setting = power_off_setting;
    power_info->power_off_setting_size = off_size;

    s_ctrl->sensordata->slave_info = camera_info;

    /* Fill sensor slave info */
    camera_info->sensor_slave_addr = slave_info->slave_addr;
    camera_info->sensor_id_reg_addr =
        slave_info->sensor_id_info.sensor_id_reg_addr;
    camera_info->sensor_id = slave_info->sensor_id_info.sensor_id;

    pr_err(" %s line %d camera_info->sensor_id = 0x%X = 0x%X\n",
           __func__, __LINE__, camera_info->sensor_id, s_ctrl->sensordata->slave_info->sensor_id);
    /* Fill CCI master, slave address and CCI default params */
    if (!s_ctrl->sensor_i2c_client) {
        pr_err("failed: sensor_i2c_client %p",
               s_ctrl->sensor_i2c_client);
        rc = -EINVAL;
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }
    /* Fill sensor address type */
    s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
    s_ctrl->sensor_i2c_client->data_type = slave_info->data_type;

    cci_client = s_ctrl->sensor_i2c_client->cci_client;
    if (!cci_client) {
        pr_err("failed: cci_client %p", cci_client);
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }
    cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
    cci_client->sid = slave_info->slave_addr >> 1;
    cci_client->retries = 3;
    cci_client->id_map = 0;

    /* Parse and fill vreg params */
    rc = msm_camera_fill_vreg_params(
             power_info->cam_vreg,
             power_info->num_vreg,
             power_info->power_setting,
             power_info->power_setting_size);
    if (rc < 0) {
        pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
               rc);
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }
#if !defined (CONFIG_SEC_MILLET_PROJECT) && !defined (CONFIG_SEC_MATISSE_PROJECT) \
	&& !defined(CONFIG_MACH_AFYONLTE_TMO) && !defined(CONFIG_MACH_AFYONLTE_CAN) && !defined (CONFIG_MACH_VICTORLTE_CTC) \
	&& !defined(CONFIG_SEC_DEGAS_PROJECT) && !defined (CONFIG_SEC_T8_PROJECT) \
	&& !defined (CONFIG_SEC_T10_PROJECT) && !defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) \
	&& !defined (CONFIG_MACH_AFYONLTE_MTR)	\
	&& !defined (CONFIG_SEC_RUBENS_PROJECT) //Commenting for Millet, Matisse

    if (power_info->power_off_setting && (power_info->power_off_setting_size > 0)) {
        /* Parse and fill vreg params */
        rc = msm_camera_fill_vreg_params(
                 power_info->cam_vreg,
                 power_info->num_vreg,
                 power_info->power_off_setting,
                 power_info->power_off_setting_size);
        if (rc < 0) {
            pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
                   rc);
            if (is_power_off)
                goto FREE_POWER_OFF_SETTING;
            else
                goto FREE_POWER_SETTING;
        }
    }
#endif
    /* remove this code for DFMS test for MS01 */
#if defined(CONFIG_MACH_ULC83G_EUR) || defined (CONFIG_SEC_MILLET_PROJECT) \
	|| defined(CONFIG_SEC_MATISSE_PROJECT)|| defined(CONFIG_MACH_CRATERQ_CHN_OPEN) \
	|| defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \
	|| defined (CONFIG_MACH_VICTORLTE_CTC) || defined(CONFIG_SEC_DEGAS_PROJECT) \
	|| defined (CONFIG_SEC_T8_PROJECT) || defined (CONFIG_SEC_T10_PROJECT) \
	|| defined (CONFIG_MACH_AFYONLTE_MTR) \
	|| defined (CONFIG_SEC_RUBENS_PROJECT) // Added for YUV bringup
    /* Power up and probe sensor */
    rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl,
                                           &s_ctrl->sensordata->power_info,
                                           s_ctrl->sensor_i2c_client,
                                           s_ctrl->sensordata->slave_info,
                                           slave_info->sensor_name);
    if (rc < 0) {
        pr_err("%s power up failed", slave_info->sensor_name);
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }

#endif

#if defined (CONFIG_MACH_VICTOR3GDSDTV_LTN)
    if(slave_info->camera_id == CAMERA_2) {
        /* Power up and probe sensor */
        rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl,
                                               &s_ctrl->sensordata->power_info,
                                               s_ctrl->sensor_i2c_client,
                                               s_ctrl->sensordata->slave_info,
                                               slave_info->sensor_name);
        if (rc < 0) {
            pr_err("%s power up failed", slave_info->sensor_name);
            if (is_power_off)
                goto FREE_POWER_OFF_SETTING;
            else
                goto FREE_POWER_SETTING;
        }
    } else {
        if (power_info->power_off_setting && (power_info->power_off_setting_size > 0)) {
            /* Parse and fill vreg params */
            rc = msm_camera_fill_vreg_params(
                     power_info->cam_vreg,
                     power_info->num_vreg,
                     power_info->power_off_setting,
                     power_info->power_off_setting_size);
            if (rc < 0) {
                pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
                       rc);
                if (is_power_off)
                    goto FREE_POWER_OFF_SETTING;
                else
                    goto FREE_POWER_SETTING;
            }
        }
    }


#endif

    /* Update sensor name in sensor control structure */
    s_ctrl->sensordata->sensor_name = slave_info->sensor_name;

    /*
      Set probe succeeded flag to 1 so that no other camera shall
      * probed on this slot
      */
    s_ctrl->is_probe_succeed = 1;

    /*
     * Create /dev/videoX node, comment for now until dummy /dev/videoX
     * node is created and used by HAL
     */
    rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
    if (rc < 0) {
        pr_err("failed: camera_init_v4l2 rc %d", rc);
        if (is_power_off)
            goto FREE_POWER_OFF_SETTING;
        else
            goto FREE_POWER_SETTING;
    }
    s_ctrl->sensordata->sensor_info->session_id = session_id;

    /* Create /dev/v4l-subdevX device */
    v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
    snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
             s_ctrl->sensordata->sensor_name);
    v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
    s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
    media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
    s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
    s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
    s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
    pr_err("%s: name : %s, type = %d group_id = %d\n", __func__, s_ctrl->msm_sd.sd.entity.name, s_ctrl->msm_sd.sd.entity.type, s_ctrl->msm_sd.sd.entity.group_id);
    s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;


    pr_err("FAILED- 3: %d\n", msm_sd_register(&s_ctrl->msm_sd));

    memcpy(slave_info->subdev_name, s_ctrl->msm_sd.sd.entity.name,
           sizeof(slave_info->subdev_name));
    slave_info->is_probe_succeed = 1;

    slave_info->sensor_info.session_id =
        s_ctrl->sensordata->sensor_info->session_id;
    for (i = 0; i < SUB_MODULE_MAX; i++)
        slave_info->sensor_info.subdev_id[i] =
            s_ctrl->sensordata->sensor_info->subdev_id[i];
    slave_info->sensor_info.is_mount_angle_valid =
        s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
    slave_info->sensor_info.sensor_mount_angle =
        s_ctrl->sensordata->sensor_info->sensor_mount_angle;
    CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
         slave_info->sensor_info.sensor_name);
    CDBG("%s:%d session id %d\n", __func__, __LINE__,
         slave_info->sensor_info.session_id);
    for (i = 0; i < SUB_MODULE_MAX; i++)
        CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
             slave_info->sensor_info.subdev_id[i]);
    CDBG("%s:%d mount angle valid %d value %d\n", __func__,
         __LINE__, slave_info->sensor_info.is_mount_angle_valid,
         slave_info->sensor_info.sensor_mount_angle);

    if (copy_to_user((void __user *)setting,
                     (void *)slave_info, sizeof(*slave_info))) {
        pr_err("%s:%d copy failed\n", __func__, __LINE__);
        rc = -EFAULT;
    }

    pr_warn("rc %d session_id %d", rc, session_id);
    pr_warn("%s probe succeeded", slave_info->sensor_name);

    /* remove this code for DFMS test for MS01*/
#if defined(CONFIG_MACH_ULC83G_EUR) || defined (CONFIG_SEC_MILLET_PROJECT) \
	|| defined(CONFIG_SEC_MATISSE_PROJECT) || defined(CONFIG_MACH_CRATERQ_CHN_OPEN) \
	|| defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \
	|| defined(CONFIG_MACH_VICTORLTE_CTC) || defined(CONFIG_SEC_DEGAS_PROJECT) \
	|| defined (CONFIG_SEC_T8_PROJECT) || defined (CONFIG_SEC_T10_PROJECT) \
	|| defined (CONFIG_MACH_AFYONLTE_MTR) \
	|| defined (CONFIG_SEC_RUBENS_PROJECT) // Added for YUV bringup ToDo
    /* Power down */
    s_ctrl->func_tbl->sensor_power_down(
        s_ctrl,
        &s_ctrl->sensordata->power_info,
        s_ctrl->sensor_device_type,
        s_ctrl->sensor_i2c_client);
#elif defined (CONFIG_MACH_VICTOR3GDSDTV_LTN)
    if(slave_info->camera_id == CAMERA_2) {
        /* Power down */
        s_ctrl->func_tbl->sensor_power_down(
            s_ctrl,
            &s_ctrl->sensordata->power_info,
            s_ctrl->sensor_device_type,
            s_ctrl->sensor_i2c_client);
    }
#endif

    return rc;

FREE_POWER_OFF_SETTING:
    kfree(power_off_setting);
FREE_POWER_SETTING:
    kfree(power_setting);
FREE_SLAVE_INFO:
    kfree(slave_info);
    return rc;
}