/* static function definition */
int32_t msm_sensor_driver_probe(void *setting)
{
	int32_t                              rc = 0;
	uint16_t                             i = 0, size = 0, size_down = 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_down_setting = NULL;
	struct msm_camera_slave_info        *camera_info = NULL;
	struct msm_camera_power_ctrl_t      *power_info = NULL;
	int c, end;
	struct msm_sensor_power_setting     power_down_setting_t;
	unsigned long mount_pos = 0;
	int probe_fail = 0;

	/* 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 */
	CDBG("camera id %d", slave_info->camera_id);
	CDBG("slave_addr 0x%x", slave_info->slave_addr);
	CDBG("addr_type %d", slave_info->addr_type);
	CDBG("sensor_id_reg_addr 0x%x",
		slave_info->sensor_id_info.sensor_id_reg_addr);
	CDBG("sensor_id 0x%x", slave_info->sensor_id_info.sensor_id);
	CDBG("size %d", slave_info->power_setting_array.size);
	CDBG("size down %d", slave_info->power_setting_array.size_down);

	if (slave_info->is_init_params_valid) {
		CDBG("position %d",
			slave_info->sensor_init_params.position);
		CDBG("mount %d",
			slave_info->sensor_init_params.sensor_mount_angle);
	}

	/* 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;
	}

	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);
		rc = 0;
		goto FREE_SLAVE_INFO;
	}

	size = slave_info->power_setting_array.size;
	/* Allocate memory for power up 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("UP 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);
	}
	/*DOWN*/
	size_down = slave_info->power_setting_array.size_down;
	if (!size_down)
		size_down = size;
	/* Allocate memory for power down setting */
	power_down_setting =
		kzalloc(sizeof(*power_setting) * size_down, GFP_KERNEL);
	if (!power_down_setting) {
		pr_err("failed: no memory power_setting %p",
						power_down_setting);
		rc = -ENOMEM;
		goto FREE_POWER_SETTING;
	}

	if (slave_info->power_setting_array.power_down_setting) {
		if (copy_from_user(power_down_setting,
			(void *)slave_info->power_setting_array.
						power_down_setting,
			sizeof(*power_down_setting) * size_down)) {
			pr_err("failed: copy_from_user");
			rc = -EFAULT;
			goto FREE_POWER_DOWN_SETTING;
		}
	} else {
		pr_err("failed: no power_down_setting");
		if (copy_from_user(power_down_setting,
			(void *)slave_info->power_setting_array.
						power_setting,
			sizeof(*power_down_setting) * size_down)) {
			pr_err("failed: copy_from_user");
			rc = -EFAULT;
			goto FREE_POWER_DOWN_SETTING;
		}

		/*reverce*/
		end = size_down - 1;
		for (c = 0; c < size_down/2; c++) {
			power_down_setting_t = power_down_setting[c];
			power_down_setting[c] = power_down_setting[end];
			power_down_setting[end] = power_down_setting_t;
			end--;
		}

	}

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

	camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
	if (!camera_info) {
		pr_err("failed: no memory slave_info %p", camera_info);
		goto FREE_POWER_DOWN_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_down_setting = power_down_setting;
	power_info->power_down_setting_size = size_down;

	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;

	/* 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;
		goto FREE_CAMERA_INFO;
	}
	/* Fill sensor address type */
	s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
	if (s_ctrl->sensor_i2c_client->client)
		s_ctrl->sensor_i2c_client->client->addr =
			camera_info->sensor_slave_addr;

	cci_client = s_ctrl->sensor_i2c_client->cci_client;
	if (!cci_client) {
		pr_err("failed: cci_client %p", cci_client);
		goto FREE_CAMERA_INFO;
	}
	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;
	cci_client->i2c_freq_mode = slave_info->i2c_freq_mode;

	/* Parse and fill vreg params for powerup settings */
	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);
		goto FREE_CAMERA_INFO;
	}

	/* Parse and fill vreg params for powerdown settings*/
	rc = msm_camera_fill_vreg_params(
		power_info->cam_vreg,
		power_info->num_vreg,
		power_info->power_down_setting,
		power_info->power_down_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
			rc);
		goto FREE_CAMERA_INFO;
	}

	/* Update sensor, actuator and eeprom name in
	*  sensor control structure */
	s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
	s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
	s_ctrl->sensordata->actuator_name = slave_info->actuator_name;

	/*
	 * Update eeporm subdevice Id by input eeprom name
	 */
	rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto FREE_CAMERA_INFO;
	}
	/*
	 * Update actuator subdevice Id by input actuator name
	 */
	rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto FREE_CAMERA_INFO;
	}

	/* Power up and probe sensor */
	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
	if (rc < 0) {
		pr_err("%s power up failed", slave_info->sensor_name);
		probe_fail = rc;
//		goto FREE_CAMERA_INFO;
	}

	pr_err("%s probe succeeded", 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
	 */

	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
		rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
	else
		rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
	if (rc < 0) {
		pr_err("failed: camera creat v4l2 rc %d", rc);
		goto CAMERA_POWER_DOWN;
	}

	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];
		pr_err("sensor_subdev_id = %d i = %d\n",slave_info->sensor_info.subdev_id[i], i);
	}
	if (copy_to_user((void __user *)setting,
		(void *)slave_info, sizeof(*slave_info))) {
		pr_err("%s:%d copy failed\n", __func__, __LINE__);
		rc = -EFAULT;
	}

	/* Power down */
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);

	rc = msm_sensor_fill_slave_info_init_params(
		slave_info,
		s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Fill slave info failed", slave_info->sensor_name);
		goto FREE_CAMERA_INFO;
	}
	rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Validate slave info failed",
			slave_info->sensor_name);
		goto FREE_CAMERA_INFO;
	}
	/* Update sensor mount angle and position in media entity flag */
	mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
	mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
		sensor_mount_angle / 90) << 8);
	s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;

	/*Save sensor info*/
	s_ctrl->sensordata->cam_slave_info = slave_info;

	if(probe_fail) {
		rc = probe_fail;
	}

	return rc;

CAMERA_POWER_DOWN:
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
FREE_CAMERA_INFO:
	kfree(camera_info);
FREE_POWER_DOWN_SETTING:
	kfree(power_down_setting);
FREE_POWER_SETTING:
	kfree(power_setting);
FREE_SLAVE_INFO:
	kfree(slave_info);
	return rc;
}
int32_t msm_sensor_driver_probe(void *setting,
	struct msm_sensor_info_t *probed_info, char *entity_name)
{
	int32_t                              rc = 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_camera_slave_info        *camera_info = NULL;
 
    struct msm_sensor_cam_id_t          *cam_id =NULL;
    
	unsigned long                        mount_pos = 0;
	int32_t index = -1;
	uint32_t                             i = 0;

	/* 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;
	}
#ifdef CONFIG_COMPAT
	if (is_compat_task()) {
		struct msm_camera_sensor_slave_info32 setting32;
		if (copy_from_user((void *)&setting32, setting,
			sizeof(setting32))) {
				pr_err("failed: copy_from_user");
				rc = -EFAULT;
				goto free_slave_info;
			}

		strlcpy(slave_info->actuator_name, setting32.actuator_name,
			sizeof(slave_info->actuator_name));

		strlcpy(slave_info->eeprom_name, setting32.eeprom_name,
			sizeof(slave_info->eeprom_name));

		strlcpy(slave_info->sensor_name, setting32.sensor_name,
			sizeof(slave_info->sensor_name));

		strlcpy(slave_info->ois_name, setting32.ois_name,
			sizeof(slave_info->ois_name));

		strlcpy(slave_info->flash_name, setting32.flash_name,
			sizeof(slave_info->flash_name));

		slave_info->addr_type = setting32.addr_type;
		slave_info->camera_id = setting32.camera_id;

		slave_info->i2c_freq_mode = setting32.i2c_freq_mode;
		slave_info->sensor_id_info = setting32.sensor_id_info;

		slave_info->slave_addr = setting32.slave_addr;
		slave_info->power_setting_array.size =
			setting32.power_setting_array.size;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.power_setting =
			compat_ptr(setting32.power_setting_array.power_setting);
		slave_info->power_setting_array.power_down_setting =
			compat_ptr(setting32.
				power_setting_array.power_down_setting);
		slave_info->is_init_params_valid =
			setting32.is_init_params_valid;
		slave_info->sensor_init_params = setting32.sensor_init_params;
		slave_info->is_flash_supported = setting32.is_flash_supported;
	} else
#endif
	{
		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 */
	CDBG("camera id %d", slave_info->camera_id);
	CDBG("slave_addr 0x%x", slave_info->slave_addr);
	CDBG("addr_type %d", slave_info->addr_type);
	CDBG("sensor_id_reg_addr 0x%x",
		slave_info->sensor_id_info.sensor_id_reg_addr);
	CDBG("sensor_id 0x%x", slave_info->sensor_id_info.sensor_id);
	CDBG("size %d", slave_info->power_setting_array.size);
	CDBG("size down %d", slave_info->power_setting_array.size_down);
	/* Print dump reg info */
	CDBG("dump_reg_num:%d \n", slave_info->dump_reg_num);
	for(i = 0; i < slave_info->dump_reg_num; i++)
		CDBG("load dump_reg_addr:0x%X,default value:0x%X \n",
			slave_info->dump_reg_info[i].addr,
			slave_info->dump_reg_info[i].value);

	if (slave_info->is_init_params_valid) {
		CDBG("position %d",
			slave_info->sensor_init_params.position);
		CDBG("mount %d",
			slave_info->sensor_init_params.sensor_mount_angle);
	}

	/* 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;
	}

	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
		 */
		if (slave_info->sensor_id_info.sensor_id ==
			s_ctrl->sensordata->cam_slave_info->
				sensor_id_info.sensor_id) {
			pr_err("slot%d: sensor id%d already probed\n",
				slave_info->camera_id,
				s_ctrl->sensordata->cam_slave_info->
					sensor_id_info.sensor_id);
			msm_sensor_fill_sensor_info(s_ctrl,
				probed_info, entity_name);
		} else
			pr_err("slot %d has some other sensor\n",
				slave_info->camera_id);

		rc = 0;
		goto free_slave_info;
	}

	if (s_ctrl->sensordata->special_support_size > 0) {
		if (!msm_sensor_driver_is_special_support(s_ctrl,
			slave_info->sensor_name)) {
			pr_err("%s:%s is not support on this board\n",
				__func__, slave_info->sensor_name);
			rc = 0;
			goto free_slave_info;
		}
	}

	rc = msm_sensor_get_power_settings(setting, slave_info,
		&s_ctrl->sensordata->power_info);
	if (rc < 0) {
		pr_err("failed");
		goto free_slave_info;
	}


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

	}

	s_ctrl->sensordata->slave_info = camera_info;
	
   	/* used for confirmed MCAM_ID */
	cam_id = kzalloc(sizeof(*cam_id),GFP_KERNEL);
	if(!cam_id){
		pr_err("failed: no memory cam_id %p",cam_id);
		rc = -ENOMEM;
		goto free_camera_info;
	}
	if(slave_info->sensor_cam_id){
		if (copy_from_user(cam_id,(void *)slave_info->sensor_cam_id,sizeof(*cam_id))) {
			pr_err("sensor_cam_id failed: copy_from_user");
			rc = -EFAULT;
			goto free_camera_id;
		}
		camera_info->mcam_id = cam_id->cam_excepted_id;
		CDBG("%s expect camera id %d",slave_info->sensor_name,camera_info->mcam_id);
	}else{
		CDBG("%s no need to match camera id",slave_info->sensor_name);
		camera_info->mcam_id = 2;
	}

	/* 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;
        camera_info->sensor_id_data_type = slave_info->sensor_id_info.sensor_id_data_type;

	//Fill dump reg info
	if (0 !=  slave_info->dump_reg_num && slave_info->dump_reg_info) {
		camera_info->dump_reg_num = slave_info->dump_reg_num;
		camera_info->dump_reg_info = kzalloc( (sizeof (struct dump_reg_info_t)) *
			slave_info->dump_reg_num, GFP_KERNEL);

		if (!camera_info->dump_reg_info) {
			pr_err("failed: no memory dump reg info %p", camera_info->dump_reg_info);
			return -ENOMEM;
		} else if (copy_from_user(camera_info->dump_reg_info,slave_info->dump_reg_info,
					sizeof(struct dump_reg_info_t) * slave_info->dump_reg_num)) {
			pr_err("failed: copy_dump_reg");
			rc = -EFAULT;
			kfree(camera_info->dump_reg_info);
			return rc;
		} else {
			for(i = 0; i < (camera_info->dump_reg_num); i++)
				CDBG("cam_dump_reg: 0x%X",
				camera_info->dump_reg_info[i].addr);
		}
	} else {
		pr_err("sensor %s have no dump_reg_info",slave_info->sensor_name);
	}

	/* 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;
		goto free_camera_info;
	}
	/* Fill sensor address type */
	s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
	if (s_ctrl->sensor_i2c_client->client)
		s_ctrl->sensor_i2c_client->client->addr =
			camera_info->sensor_slave_addr;

	cci_client = s_ctrl->sensor_i2c_client->cci_client;
	if (!cci_client) {
		pr_err("failed: cci_client %p", cci_client);
		goto free_camera_info;
	}
	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;
	cci_client->i2c_freq_mode = slave_info->i2c_freq_mode;

	/* Parse and fill vreg params for powerup settings */
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_setting,
		s_ctrl->sensordata->power_info.power_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
			rc);
		goto free_camera_info;
	}

	/* Parse and fill vreg params for powerdown settings*/
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_down_setting,
		s_ctrl->sensordata->power_info.power_down_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
			rc);
		goto free_camera_info;
	}

	/* Update sensor, actuator and eeprom name in
	*  sensor control structure */
	s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
	s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
	s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
	s_ctrl->sensordata->ois_name = slave_info->ois_name;
	/*
	 * Update eeporm subdevice Id by input eeprom name
	 */
	rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}
	/*
	 * Update actuator subdevice Id by input actuator name
	 */
	rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

	rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

	/* Power up and probe sensor */
	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
	if (rc < 0) {
		pr_err("%s power up failed", slave_info->sensor_name);
		goto free_camera_info;
	}
	if ( is_exist_otp_function(s_ctrl, &index)){
		if(otp_function_lists[index].is_boot_load){
			rc = otp_function_lists[index].sensor_otp_function(s_ctrl, index);
			if (rc < 0){
				pr_err("%s:%d failed rc %d\n", __func__,__LINE__, rc);
			}
		}
	}
	pr_err("%s probe succeeded", slave_info->sensor_name);
	if (0 == slave_info->camera_id){
		rc = app_info_set("camera_main", slave_info->sensor_name);
	}
	else if (1 == slave_info->camera_id){
		rc = app_info_set("camera_slave", slave_info->sensor_name);
	}
	else{
		pr_err("%s app_info_set id err", slave_info->sensor_name);
	}

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	if(0 == slave_info->camera_id) //detet main senor or sub sensor
	{
		set_hw_dev_flag(DEV_I2C_CAMERA_MAIN);   //set sensor flag
	}
	else if (1 == slave_info->camera_id)       //sub sensor
	{
		set_hw_dev_flag(DEV_I2C_CAMERA_SLAVE);  //set sensor flag
	}
	else
	{
		pr_err("%s set_hw_dev_flag id err", slave_info->sensor_name);
	}
#endif
	/*
	  Set probe succeeded flag to 1 so that no other camera shall
	 * probed on this slot
	 */
	s_ctrl->is_probe_succeed = 1;

	/*
	 * Update the subdevice id of flash-src based on availability in kernel.
	 */
	if (slave_info->is_flash_supported == 0) {
		s_ctrl->sensordata->sensor_info->
			subdev_id[SUB_MODULE_LED_FLASH] = -1;
	}

	/*
	 * Create /dev/videoX node, comment for now until dummy /dev/videoX
	 * node is created and used by HAL
	 */

	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
		rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
	else
		rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
	if (rc < 0) {
		pr_err("failed: camera creat v4l2 rc %d", rc);
		goto camera_power_down;
	}

	/* Power down */
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);

	rc = msm_sensor_fill_slave_info_init_params(
		slave_info,
		s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Fill slave info failed", slave_info->sensor_name);
		goto free_camera_info;
	}
	rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Validate slave info failed",
			slave_info->sensor_name);
		goto free_camera_info;
	}
	/* Update sensor mount angle and position in media entity flag */
	mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
	mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
		sensor_mount_angle / 90) << 8);
	s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;

	/*Save sensor info*/
	s_ctrl->sensordata->cam_slave_info = slave_info;

	msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);

	return rc;

camera_power_down:
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
free_camera_info:
	kfree(camera_info);
free_camera_id:
	kfree(cam_id);
free_slave_info:
	kfree(slave_info);
	return rc;
}
/* static function definition */
int32_t msm_sensor_driver_probe(void *setting,
                                struct msm_sensor_info_t *probed_info, char *entity_name)
{
    int32_t                              rc = 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_camera_slave_info        *camera_info = NULL;

    unsigned long                        mount_pos = 0;

    /* 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;
    }
#ifdef CONFIG_COMPAT
    if (is_compat_task()) {
        struct msm_camera_sensor_slave_info32 setting32;
        if (copy_from_user((void *)&setting32, setting,
                           sizeof(setting32))) {
            pr_err("failed: copy_from_user");
            rc = -EFAULT;
            goto free_slave_info;
        }

        strlcpy(slave_info->actuator_name, setting32.actuator_name,
                sizeof(slave_info->actuator_name));

        strlcpy(slave_info->eeprom_name, setting32.eeprom_name,
                sizeof(slave_info->eeprom_name));

        strlcpy(slave_info->sensor_name, setting32.sensor_name,
                sizeof(slave_info->sensor_name));

        strlcpy(slave_info->ois_name, setting32.ois_name,
                sizeof(slave_info->ois_name));

        strlcpy(slave_info->flash_name, setting32.flash_name,
                sizeof(slave_info->flash_name));

        slave_info->addr_type = setting32.addr_type;
        slave_info->camera_id = setting32.camera_id;

        slave_info->i2c_freq_mode = setting32.i2c_freq_mode;
        slave_info->sensor_id_info = setting32.sensor_id_info;

        slave_info->slave_addr = setting32.slave_addr;
        slave_info->power_setting_array.size =
            setting32.power_setting_array.size;
        slave_info->power_setting_array.size_down =
            setting32.power_setting_array.size_down;
        slave_info->power_setting_array.size_down =
            setting32.power_setting_array.size_down;
        slave_info->power_setting_array.power_setting =
            compat_ptr(setting32.power_setting_array.power_setting);
        slave_info->power_setting_array.power_down_setting =
            compat_ptr(setting32.
                       power_setting_array.power_down_setting);
        slave_info->is_init_params_valid =
            setting32.is_init_params_valid;
        slave_info->sensor_init_params = setting32.sensor_init_params;
        slave_info->is_flash_supported = setting32.is_flash_supported;
    } else
#endif
    {
        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 */
    CDBG("camera id %d", slave_info->camera_id);
    CDBG("slave_addr 0x%x", slave_info->slave_addr);
    CDBG("addr_type %d", slave_info->addr_type);
    CDBG("sensor_id_reg_addr 0x%x",
         slave_info->sensor_id_info.sensor_id_reg_addr);
    CDBG("sensor_id 0x%x", slave_info->sensor_id_info.sensor_id);
    CDBG("size %d", slave_info->power_setting_array.size);
    CDBG("size down %d", slave_info->power_setting_array.size_down);

    if (slave_info->is_init_params_valid) {
        CDBG("position %d",
             slave_info->sensor_init_params.position);
        CDBG("mount %d",
             slave_info->sensor_init_params.sensor_mount_angle);
    }

    /* 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;
    }

    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
         */
        if (slave_info->sensor_id_info.sensor_id ==
                s_ctrl->sensordata->cam_slave_info->
                sensor_id_info.sensor_id) {
            pr_err("slot%d: sensor id%d already probed\n",
                   slave_info->camera_id,
                   s_ctrl->sensordata->cam_slave_info->
                   sensor_id_info.sensor_id);
            msm_sensor_fill_sensor_info(s_ctrl,
                                        probed_info, entity_name);
        } else
            pr_err("slot %d has some other sensor\n",
                   slave_info->camera_id);

        rc = 0;
        goto free_slave_info;
    }

    rc = msm_sensor_get_power_settings(setting, slave_info,
                                       &s_ctrl->sensordata->power_info);
    if (rc < 0) {
        pr_err("failed");
        goto free_slave_info;
    }


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

    }

    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;

    /* 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;
        goto free_camera_info;
    }
    /* Fill sensor address type */
    s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
    if (s_ctrl->sensor_i2c_client->client)
        s_ctrl->sensor_i2c_client->client->addr =
            camera_info->sensor_slave_addr;

    cci_client = s_ctrl->sensor_i2c_client->cci_client;
    if (!cci_client) {
        pr_err("failed: cci_client %p", cci_client);
        goto free_camera_info;
    }
    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;
    cci_client->i2c_freq_mode = slave_info->i2c_freq_mode;

    /* Parse and fill vreg params for powerup settings */
    rc = msm_camera_fill_vreg_params(
             s_ctrl->sensordata->power_info.cam_vreg,
             s_ctrl->sensordata->power_info.num_vreg,
             s_ctrl->sensordata->power_info.power_setting,
             s_ctrl->sensordata->power_info.power_setting_size);
    if (rc < 0) {
        pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
               rc);
        goto free_camera_info;
    }

    /* Parse and fill vreg params for powerdown settings*/
    rc = msm_camera_fill_vreg_params(
             s_ctrl->sensordata->power_info.cam_vreg,
             s_ctrl->sensordata->power_info.num_vreg,
             s_ctrl->sensordata->power_info.power_down_setting,
             s_ctrl->sensordata->power_info.power_down_setting_size);
    if (rc < 0) {
        pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
               rc);
        goto free_camera_info;
    }

    /* Update sensor, actuator and eeprom name in
    *  sensor control structure */
    s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
    s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
    s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
    s_ctrl->sensordata->ois_name = slave_info->ois_name;
    /*
     * Update eeporm subdevice Id by input eeprom name
     */
    rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
    if (rc < 0) {
        pr_err("%s failed %d\n", __func__, __LINE__);
        goto free_camera_info;
    }
    /*
     * Update actuator subdevice Id by input actuator name
     */
    rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
    if (rc < 0) {
        pr_err("%s failed %d\n", __func__, __LINE__);
        goto free_camera_info;
    }

    rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);
    if (rc < 0) {
        pr_err("%s failed %d\n", __func__, __LINE__);
        goto free_camera_info;
    }

    /* Power up and probe sensor */
    rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
    if (rc < 0) {
        pr_err("%s power up failed", slave_info->sensor_name);
        goto free_camera_info;
    }

    pr_err("%s probe succeeded", 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;

    /*
     * Update the subdevice id of flash-src based on availability in kernel.
     */
    if (slave_info->is_flash_supported == 0) {
        s_ctrl->sensordata->sensor_info->
        subdev_id[SUB_MODULE_LED_FLASH] = -1;
    }

    /*
     * Create /dev/videoX node, comment for now until dummy /dev/videoX
     * node is created and used by HAL
     */

    if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
        rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
    else
        rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
    if (rc < 0) {
        pr_err("failed: camera creat v4l2 rc %d", rc);
        goto camera_power_down;
    }

    /* Power down */
    s_ctrl->func_tbl->sensor_power_down(s_ctrl);

    rc = msm_sensor_fill_slave_info_init_params(
             slave_info,
             s_ctrl->sensordata->sensor_info);
    if (rc < 0) {
        pr_err("%s Fill slave info failed", slave_info->sensor_name);
        goto free_camera_info;
    }
    rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
    if (rc < 0) {
        pr_err("%s Validate slave info failed",
               slave_info->sensor_name);
        goto free_camera_info;
    }
    /* Update sensor mount angle and position in media entity flag */
    mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
    mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
                              sensor_mount_angle / 90) << 8);
    s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;

    /*Save sensor info*/
    s_ctrl->sensordata->cam_slave_info = slave_info;

    msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);

    return rc;

camera_power_down:
    s_ctrl->func_tbl->sensor_power_down(s_ctrl);
free_camera_info:
    kfree(camera_info);
free_slave_info:
    kfree(slave_info);
    return rc;
}
/* static function definition */
int32_t msm_sensor_driver_probe(void *setting,
	struct msm_sensor_info_t *probed_info, char *entity_name)
{
	int32_t                              rc = 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_camera_slave_info        *camera_info = NULL;

	unsigned long                        mount_pos = 0;

	/* 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;
	}
#ifdef CONFIG_COMPAT
	if (is_compat_task()) {
		struct msm_camera_sensor_slave_info32 setting32;
		if (copy_from_user((void *)&setting32, setting,
			sizeof(setting32))) {
				pr_err("failed: copy_from_user");
				rc = -EFAULT;
				goto free_slave_info;
			}

		strlcpy(slave_info->actuator_name, setting32.actuator_name,
			sizeof(slave_info->actuator_name));

		strlcpy(slave_info->eeprom_name, setting32.eeprom_name,
			sizeof(slave_info->eeprom_name));

		strlcpy(slave_info->sensor_name, setting32.sensor_name,
			sizeof(slave_info->sensor_name));

		strlcpy(slave_info->ois_name, setting32.ois_name,
			sizeof(slave_info->ois_name));

		strlcpy(slave_info->flash_name, setting32.flash_name,
			sizeof(slave_info->flash_name));

		slave_info->addr_type = setting32.addr_type;
		slave_info->camera_id = setting32.camera_id;

		slave_info->i2c_freq_mode = setting32.i2c_freq_mode;
		slave_info->sensor_id_info = setting32.sensor_id_info;

		slave_info->slave_addr = setting32.slave_addr;
		slave_info->power_setting_array.size =
			setting32.power_setting_array.size;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.power_setting =
			compat_ptr(setting32.power_setting_array.power_setting);
		slave_info->power_setting_array.power_down_setting =
			compat_ptr(setting32.
				power_setting_array.power_down_setting);
		slave_info->is_init_params_valid =
			setting32.is_init_params_valid;
		slave_info->sensor_init_params = setting32.sensor_init_params;
		slave_info->is_flash_supported = setting32.is_flash_supported;
	} else
#endif
	{
		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 */
	CDBG("camera id %d", slave_info->camera_id);
	CDBG("slave_addr 0x%x", slave_info->slave_addr);
	CDBG("addr_type %d", slave_info->addr_type);
	CDBG("sensor_id_reg_addr 0x%x",
		slave_info->sensor_id_info.sensor_id_reg_addr);
	CDBG("sensor_id 0x%x", slave_info->sensor_id_info.sensor_id);
	CDBG("size %d", slave_info->power_setting_array.size);
	CDBG("size down %d", slave_info->power_setting_array.size_down);

	if (slave_info->is_init_params_valid) {
		CDBG("position %d",
			slave_info->sensor_init_params.position);
		CDBG("mount %d",
			slave_info->sensor_init_params.sensor_mount_angle);
	}

	/* 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;
	}

	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
		 */
		if (slave_info->sensor_id_info.sensor_id ==
			s_ctrl->sensordata->cam_slave_info->
				sensor_id_info.sensor_id) {
			pr_err("slot%d: sensor id%d already probed\n",
				slave_info->camera_id,
				s_ctrl->sensordata->cam_slave_info->
					sensor_id_info.sensor_id);
			msm_sensor_fill_sensor_info(s_ctrl,
				probed_info, entity_name);
		} else
			pr_err("slot %d has some other sensor\n",
				slave_info->camera_id);

		rc = 0;
		goto free_slave_info;
	}

	rc = msm_sensor_get_power_settings(setting, slave_info,
		&s_ctrl->sensordata->power_info);
	if (rc < 0) {
		pr_err("failed");
		goto free_slave_info;
	}


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

	}

	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;

	/* 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;
		goto free_camera_info;
	}
	/* Fill sensor address type */
	s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
	if (s_ctrl->sensor_i2c_client->client)
		s_ctrl->sensor_i2c_client->client->addr =
			camera_info->sensor_slave_addr;

	cci_client = s_ctrl->sensor_i2c_client->cci_client;
	if (!cci_client) {
		pr_err("failed: cci_client %p", cci_client);
		goto free_camera_info;
	}
	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;
	cci_client->i2c_freq_mode = slave_info->i2c_freq_mode;

	/* Parse and fill vreg params for powerup settings */
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_setting,
		s_ctrl->sensordata->power_info.power_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
			rc);
		goto free_camera_info;
	}

	/* Parse and fill vreg params for powerdown settings*/
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_down_setting,
		s_ctrl->sensordata->power_info.power_down_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
			rc);
		goto free_camera_info;
	}

	/* Update sensor, actuator and eeprom name in
	*  sensor control structure */
	s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
	s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
	s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
	s_ctrl->sensordata->ois_name = slave_info->ois_name;
	/*
	 * Update eeporm subdevice Id by input eeprom name
	 */
	rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}
	/*
	 * Update actuator subdevice Id by input actuator name
	 */
	rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

	rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

#ifdef CONFIG_TCT_8X16_ALTO5
	if (!strcmp(s_ctrl->sensordata->sensor_name, "ov5670_truly_ff") ||
		!strcmp(s_ctrl->sensordata->sensor_name, "ov5670_truly"))
	{
        printk(KERN_DEBUG"%s:%d, free gpio %d for gpio_vdig\n", __func__, __LINE__,
		    s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG]);
		gpio_request(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG], 
		    s_ctrl->sensordata->sensor_name);
        gpio_free(s_ctrl->sensordata->power_info.gpio_conf->gpio_num_info->gpio_num[SENSOR_GPIO_VDIG]);
	}
#endif // CONFIG_TCT_8X16_ALTO5
	/* Power up and probe sensor */
	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
	if (rc < 0) {
		pr_err("%s power up failed", slave_info->sensor_name);
		goto free_camera_info;
	}
#if defined(CONFIG_TCT_8X16_ALTO45_LATAM_B28)
	/*
	 * Update actuator subdevice Id by input actuator name
	 */
	rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}
#endif
    /* add by [email protected], distinguish OV5670 Truly FF/AF module 
       through OTP VCM ID, 2014.8.13 */
#ifdef CONFIG_TCT_8X16_ALTO5
	if (!strcmp(s_ctrl->sensordata->sensor_name, "ov5670_truly_ff") &&
	    ov5670_truly_otp_get_vcm_id(s_ctrl)) {
		printk(KERN_ERR"%s:%d, detect error: ov5670 truly FF module have VCM ID\n",
			   __func__, __LINE__);
        goto camera_power_down;
	}
    if (!strcmp(s_ctrl->sensordata->sensor_name, "ov5670_truly") &&
		!ov5670_truly_otp_get_vcm_id(s_ctrl)) {
		printk(KERN_ERR"%s:%d, detect error: ov5670 truly AF module have not VCM ID\n",
			   __func__, __LINE__);
        goto camera_power_down;
    }
#endif // CONFIG_TCT_8X16_ALTO5
//[PLATFROM]-ADD-SATRT TCTSZ.ZKX 2014.08.27
#ifdef CONFIG_TCT_8X16_POP10
	if (!strcmp(s_ctrl->sensordata->sensor_name, "ov5670_truly_cm9607")){
		uint16_t vcm_id;
		vcm_id = ov5670_truly_otp_get_vcm_id(s_ctrl);
		printk(KERN_ERR"%s, %d,vcm_id %d\n",__func__, __LINE__,vcm_id);
		if(vcm_id != 0x00){
			printk(KERN_ERR"%s:%d, detect error: ov5670 truly FF module have not VCM ID\n",
				   __func__, __LINE__);
            goto camera_power_down;
		}
	}

	printk("%s, this a %s\n",__func__,s_ctrl->sensordata->sensor_name);
	if (!strcmp(s_ctrl->sensordata->sensor_name, "s5k5e2_sunny_p5s12e")){
		if(s5k5e2_check_module(s_ctrl->sensor_i2c_client)==0x13){//FF camera should not have vcm id
			printk("%s:%d, camera is not %s!!!\n",__func__, __LINE__,s_ctrl->sensordata->sensor_name);
            goto camera_power_down;
		}
		else{
			printk("%s:%d, camera is %s!!!\n",__func__, __LINE__,s_ctrl->sensordata->sensor_name);
		}
	}
	else if(!strcmp(s_ctrl->sensordata->sensor_name, "s5k5e2_sunny_p5s13b")){
		if(s5k5e2_check_module(s_ctrl->sensor_i2c_client)!=0x13){//AF camera should have vcm id, this module VCM id is 0x13
			printk("%s:%d, camera is not %s!!!\n",__func__, __LINE__,s_ctrl->sensordata->sensor_name);
			goto CAMERA_POWER_DOWN;
		}
		else{
			printk("%s:%d, camera is %s!!!\n",__func__, __LINE__,s_ctrl->sensordata->sensor_name);
		}
	}
#endif // CONFIG_TCT_8X16_POP10
//[PLATFROM]-ADD-END TCTSZ.ZKX
	pr_err("%s probe succeeded", 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;

	/*
	 * Update the subdevice id of flash-src based on availability in kernel.
	 */
	if (slave_info->is_flash_supported == 0) {
		s_ctrl->sensordata->sensor_info->
			subdev_id[SUB_MODULE_LED_FLASH] = -1;
	}

	/*
	 * Create /dev/videoX node, comment for now until dummy /dev/videoX
	 * node is created and used by HAL
	 */

	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
		rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
	else
		rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
	if (rc < 0) {
		pr_err("failed: camera creat v4l2 rc %d", rc);
		goto camera_power_down;
	}

	/* Power down */
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);

	rc = msm_sensor_fill_slave_info_init_params(
		slave_info,
		s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Fill slave info failed", slave_info->sensor_name);
		goto free_camera_info;
	}
	rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Validate slave info failed",
			slave_info->sensor_name);
		goto free_camera_info;
	}
	/* Update sensor mount angle and position in media entity flag */
	mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
	mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
		sensor_mount_angle / 90) << 8);
	s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;

	/*Save sensor info*/
	s_ctrl->sensordata->cam_slave_info = slave_info;

	msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);

	return rc;

camera_power_down:
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
free_camera_info:
	kfree(camera_info);
free_slave_info:
	kfree(slave_info);
	return rc;
}