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