static int32_t msm_sensor_driver_create_v4l_subdev (struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; uint32_t session_id = 0; rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id); if (rc < 0) { pr_err("failed: camera_init_v4l2 rc %d", rc); return rc; } CDBG("rc %d session_id %d", rc, session_id); s_ctrl->sensordata->sensor_info->session_id = session_id; /* Create /dev/v4l-subdevX device */ v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops); snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s", s_ctrl->sensordata->sensor_name); v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev); s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0); s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; msm_sd_register(&s_ctrl->msm_sd); return rc; }
static int32_t msm_sensor_driver_create_i2c_v4l_subdev (struct msm_sensor_ctrl_t *s_ctrl) { int32_t rc = 0; uint32_t session_id = 0; struct i2c_client *client = s_ctrl->sensor_i2c_client->client; CDBG("%s %s I2c probe succeeded\n", __func__, client->name); rc = camera_init_v4l2(&client->dev, &session_id); if (rc < 0) { pr_err("failed: camera_init_i2c_v4l2 rc %d", rc); return rc; } CDBG("%s rc %d session_id %d\n", __func__, rc, session_id); snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s", s_ctrl->sensordata->sensor_name); v4l2_i2c_subdev_init(&s_ctrl->msm_sd.sd, client, s_ctrl->sensor_v4l2_subdev_ops); v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client); s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0); s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->sensordata->sensor_info->session_id = session_id; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; msm_sd_register(&s_ctrl->msm_sd); CDBG("%s:%d\n", __func__, __LINE__); return rc; }
/* static function definition */ int32_t msm_sensor_driver_probe(void *setting) { int32_t rc = 0; int32_t is_power_off = 0; uint16_t i = 0, size = 0, off_size = 0; uint32_t session_id = 0; struct msm_sensor_ctrl_t *s_ctrl = NULL; struct msm_camera_cci_client *cci_client = NULL; struct msm_camera_sensor_slave_info *slave_info = NULL; struct msm_sensor_power_setting *power_setting = NULL; struct msm_sensor_power_setting *power_off_setting = NULL; struct msm_camera_slave_info *camera_info = NULL; struct msm_camera_power_ctrl_t *power_info = NULL; /* Validate input parameters */ if (!setting) { pr_err("failed: slave_info %p", setting); return -EINVAL; } /* Allocate memory for slave info */ slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL); if (!slave_info) { pr_err("failed: no memory slave_info %p", slave_info); return -ENOMEM; } if (copy_from_user(slave_info, (void *)setting, sizeof(*slave_info))) { pr_err("failed: copy_from_user"); rc = -EFAULT; goto FREE_SLAVE_INFO; } /* Print slave info */ pr_err("camera id %d", slave_info->camera_id); pr_err("slave_addr %x", slave_info->slave_addr); CDBG("addr_type %d", slave_info->addr_type); CDBG("sensor_id_reg_addr %x", slave_info->sensor_id_info.sensor_id_reg_addr); CDBG("sensor_id %x", slave_info->sensor_id_info.sensor_id); CDBG("size %x", slave_info->power_setting_array.size); /* Validate camera id */ if (slave_info->camera_id >= MAX_CAMERAS) { pr_err("failed: invalid camera id %d max %d", slave_info->camera_id, MAX_CAMERAS); rc = -EINVAL; goto FREE_SLAVE_INFO; } /* Extract s_ctrl from camera id */ s_ctrl = g_sctrl[slave_info->camera_id]; if (!s_ctrl) { pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl, slave_info->camera_id); rc = -EINVAL; goto FREE_SLAVE_INFO; } #if defined (CONFIG_SEC_MILLET_PROJECT) || defined(CONFIG_SEC_MATISSE_PROJECT) \ || defined(CONFIG_SEC_DEGAS_PROJECT) || defined (CONFIG_SEC_T8_PROJECT) \ || defined (CONFIG_SEC_T10_PROJECT) \ || defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) \ || defined (CONFIG_SEC_RUBENS_PROJECT) if(slave_info->camera_id == CAMERA_2) { #if defined(CONFIG_SR130PC20) s_ctrl->func_tbl = &sr130pc20_sensor_func_tbl ; sr130pc20_set_default_settings(); #endif } else if (slave_info->camera_id == CAMERA_0) { #if defined(CONFIG_SR352) s_ctrl->func_tbl = &sr352_sensor_func_tbl ; sr352_set_default_settings(); #endif #if defined(CONFIG_SR200PC20) s_ctrl->func_tbl = &sr200pc20_sensor_func_tbl ; sr200pc20_set_default_settings(); #endif } #elif defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \ || defined (CONFIG_MACH_AFYONLTE_MTR) if(slave_info->camera_id == CAMERA_2) { #if defined(CONFIG_S5K4ECGX) s_ctrl->func_tbl = &sr030pc50_sensor_func_tbl; #endif } else if (slave_info->camera_id == CAMERA_0) { #if defined(CONFIG_SR030PC50) s_ctrl->func_tbl = &s5k4ecgx_sensor_func_tbl; #endif } #elif defined(CONFIG_MACH_CRATERQ_CHN_OPEN) if(slave_info->camera_id == CAMERA_2) { s_ctrl->func_tbl = &sr200pc20_sensor_func_tbl ; } #elif defined(CONFIG_MACH_VICTORLTE_CTC) if (slave_info->camera_id == CAMERA_0) { s_ctrl->func_tbl = &s5k4ecgx_sensor_func_tbl; } #endif CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl); if (s_ctrl->is_probe_succeed == 1) { /* * Different sensor on this camera slot has been connected * and probe already succeeded for that sensor. Ignore this * probe */ pr_err("slot %d has some other sensor", slave_info->camera_id); kfree(slave_info); return 0; } size = slave_info->power_setting_array.size; /* Allocate memory for power setting */ power_setting = kzalloc(sizeof(*power_setting) * size, GFP_KERNEL); if (!power_setting) { pr_err("failed: no memory power_setting %p", power_setting); rc = -ENOMEM; goto FREE_SLAVE_INFO; } if (copy_from_user(power_setting, (void *)slave_info->power_setting_array.power_setting, sizeof(*power_setting) * size)) { pr_err("failed: copy_from_user"); rc = -EFAULT; goto FREE_POWER_SETTING; } /* Print power setting */ for (i = 0; i < size; i++) { CDBG("seq_type %d seq_val %d config_val %ld delay %d", power_setting[i].seq_type, power_setting[i].seq_val, power_setting[i].config_val, power_setting[i].delay); } off_size = slave_info->power_setting_array.off_size; if (off_size > 0) { /* Allocate memory for power setting */ power_off_setting = kzalloc(sizeof(*power_off_setting) * off_size, GFP_KERNEL); if (!power_off_setting) { pr_err("failed: no memory power_setting %p", power_off_setting); rc = -ENOMEM; goto FREE_POWER_SETTING; } if (copy_from_user(power_off_setting, (void *)slave_info->power_setting_array.power_off_setting, sizeof(*power_off_setting) * off_size)) { pr_err("failed: copy_from_user"); rc = -EFAULT; goto FREE_POWER_OFF_SETTING; } /* Print power setting */ for (i = 0; i < off_size; i++) { CDBG("seq_type %d seq_val %d config_val %ld delay %d", power_off_setting[i].seq_type, power_off_setting[i].seq_val, power_off_setting[i].config_val, power_off_setting[i].delay); } is_power_off = 1; } camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL); if (!camera_info) { pr_err("failed: no memory slave_info %p", camera_info); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } /* Fill power up setting and power up setting size */ power_info = &s_ctrl->sensordata->power_info; power_info->power_setting = power_setting; power_info->power_setting_size = size; power_info->power_off_setting = power_off_setting; power_info->power_off_setting_size = off_size; s_ctrl->sensordata->slave_info = camera_info; /* Fill sensor slave info */ camera_info->sensor_slave_addr = slave_info->slave_addr; camera_info->sensor_id_reg_addr = slave_info->sensor_id_info.sensor_id_reg_addr; camera_info->sensor_id = slave_info->sensor_id_info.sensor_id; pr_err(" %s line %d camera_info->sensor_id = 0x%X = 0x%X\n", __func__, __LINE__, camera_info->sensor_id, s_ctrl->sensordata->slave_info->sensor_id); /* Fill CCI master, slave address and CCI default params */ if (!s_ctrl->sensor_i2c_client) { pr_err("failed: sensor_i2c_client %p", s_ctrl->sensor_i2c_client); rc = -EINVAL; if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } /* Fill sensor address type */ s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type; s_ctrl->sensor_i2c_client->data_type = slave_info->data_type; cci_client = s_ctrl->sensor_i2c_client->cci_client; if (!cci_client) { pr_err("failed: cci_client %p", cci_client); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } cci_client->cci_i2c_master = s_ctrl->cci_i2c_master; cci_client->sid = slave_info->slave_addr >> 1; cci_client->retries = 3; cci_client->id_map = 0; /* Parse and fill vreg params */ rc = msm_camera_fill_vreg_params( power_info->cam_vreg, power_info->num_vreg, power_info->power_setting, power_info->power_setting_size); if (rc < 0) { pr_err("failed: msm_camera_get_dt_power_setting_data rc %d", rc); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } #if !defined (CONFIG_SEC_MILLET_PROJECT) && !defined (CONFIG_SEC_MATISSE_PROJECT) \ && !defined(CONFIG_MACH_AFYONLTE_TMO) && !defined(CONFIG_MACH_AFYONLTE_CAN) && !defined (CONFIG_MACH_VICTORLTE_CTC) \ && !defined(CONFIG_SEC_DEGAS_PROJECT) && !defined (CONFIG_SEC_T8_PROJECT) \ && !defined (CONFIG_SEC_T10_PROJECT) && !defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) \ && !defined (CONFIG_MACH_AFYONLTE_MTR) \ && !defined (CONFIG_SEC_RUBENS_PROJECT) //Commenting for Millet, Matisse if (power_info->power_off_setting && (power_info->power_off_setting_size > 0)) { /* Parse and fill vreg params */ rc = msm_camera_fill_vreg_params( power_info->cam_vreg, power_info->num_vreg, power_info->power_off_setting, power_info->power_off_setting_size); if (rc < 0) { pr_err("failed: msm_camera_get_dt_power_setting_data rc %d", rc); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } } #endif /* remove this code for DFMS test for MS01 */ #if defined(CONFIG_MACH_ULC83G_EUR) || defined (CONFIG_SEC_MILLET_PROJECT) \ || defined(CONFIG_SEC_MATISSE_PROJECT)|| defined(CONFIG_MACH_CRATERQ_CHN_OPEN) \ || defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \ || defined (CONFIG_MACH_VICTORLTE_CTC) || defined(CONFIG_SEC_DEGAS_PROJECT) \ || defined (CONFIG_SEC_T8_PROJECT) || defined (CONFIG_SEC_T10_PROJECT) \ || defined (CONFIG_MACH_AFYONLTE_MTR) \ || defined (CONFIG_SEC_RUBENS_PROJECT) // Added for YUV bringup /* Power up and probe sensor */ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl, &s_ctrl->sensordata->power_info, s_ctrl->sensor_i2c_client, s_ctrl->sensordata->slave_info, slave_info->sensor_name); if (rc < 0) { pr_err("%s power up failed", slave_info->sensor_name); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } #endif #if defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) if(slave_info->camera_id == CAMERA_2) { /* Power up and probe sensor */ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl, &s_ctrl->sensordata->power_info, s_ctrl->sensor_i2c_client, s_ctrl->sensordata->slave_info, slave_info->sensor_name); if (rc < 0) { pr_err("%s power up failed", slave_info->sensor_name); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } } else { if (power_info->power_off_setting && (power_info->power_off_setting_size > 0)) { /* Parse and fill vreg params */ rc = msm_camera_fill_vreg_params( power_info->cam_vreg, power_info->num_vreg, power_info->power_off_setting, power_info->power_off_setting_size); if (rc < 0) { pr_err("failed: msm_camera_get_dt_power_setting_data rc %d", rc); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } } } #endif /* Update sensor name in sensor control structure */ s_ctrl->sensordata->sensor_name = slave_info->sensor_name; /* Set probe succeeded flag to 1 so that no other camera shall * probed on this slot */ s_ctrl->is_probe_succeed = 1; /* * Create /dev/videoX node, comment for now until dummy /dev/videoX * node is created and used by HAL */ rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id); if (rc < 0) { pr_err("failed: camera_init_v4l2 rc %d", rc); if (is_power_off) goto FREE_POWER_OFF_SETTING; else goto FREE_POWER_SETTING; } s_ctrl->sensordata->sensor_info->session_id = session_id; /* Create /dev/v4l-subdevX device */ v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops); snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s", s_ctrl->sensordata->sensor_name); v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev); s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0); s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; pr_err("%s: name : %s, type = %d group_id = %d\n", __func__, s_ctrl->msm_sd.sd.entity.name, s_ctrl->msm_sd.sd.entity.type, s_ctrl->msm_sd.sd.entity.group_id); s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; pr_err("FAILED- 3: %d\n", msm_sd_register(&s_ctrl->msm_sd)); memcpy(slave_info->subdev_name, s_ctrl->msm_sd.sd.entity.name, sizeof(slave_info->subdev_name)); slave_info->is_probe_succeed = 1; slave_info->sensor_info.session_id = s_ctrl->sensordata->sensor_info->session_id; for (i = 0; i < SUB_MODULE_MAX; i++) slave_info->sensor_info.subdev_id[i] = s_ctrl->sensordata->sensor_info->subdev_id[i]; slave_info->sensor_info.is_mount_angle_valid = s_ctrl->sensordata->sensor_info->is_mount_angle_valid; slave_info->sensor_info.sensor_mount_angle = s_ctrl->sensordata->sensor_info->sensor_mount_angle; CDBG("%s:%d sensor name %s\n", __func__, __LINE__, slave_info->sensor_info.sensor_name); CDBG("%s:%d session id %d\n", __func__, __LINE__, slave_info->sensor_info.session_id); for (i = 0; i < SUB_MODULE_MAX; i++) CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i, slave_info->sensor_info.subdev_id[i]); CDBG("%s:%d mount angle valid %d value %d\n", __func__, __LINE__, slave_info->sensor_info.is_mount_angle_valid, slave_info->sensor_info.sensor_mount_angle); if (copy_to_user((void __user *)setting, (void *)slave_info, sizeof(*slave_info))) { pr_err("%s:%d copy failed\n", __func__, __LINE__); rc = -EFAULT; } pr_warn("rc %d session_id %d", rc, session_id); pr_warn("%s probe succeeded", slave_info->sensor_name); /* remove this code for DFMS test for MS01*/ #if defined(CONFIG_MACH_ULC83G_EUR) || defined (CONFIG_SEC_MILLET_PROJECT) \ || defined(CONFIG_SEC_MATISSE_PROJECT) || defined(CONFIG_MACH_CRATERQ_CHN_OPEN) \ || defined(CONFIG_MACH_AFYONLTE_TMO) || defined(CONFIG_MACH_AFYONLTE_CAN) \ || defined(CONFIG_MACH_VICTORLTE_CTC) || defined(CONFIG_SEC_DEGAS_PROJECT) \ || defined (CONFIG_SEC_T8_PROJECT) || defined (CONFIG_SEC_T10_PROJECT) \ || defined (CONFIG_MACH_AFYONLTE_MTR) \ || defined (CONFIG_SEC_RUBENS_PROJECT) // Added for YUV bringup ToDo /* Power down */ s_ctrl->func_tbl->sensor_power_down( s_ctrl, &s_ctrl->sensordata->power_info, s_ctrl->sensor_device_type, s_ctrl->sensor_i2c_client); #elif defined (CONFIG_MACH_VICTOR3GDSDTV_LTN) if(slave_info->camera_id == CAMERA_2) { /* Power down */ s_ctrl->func_tbl->sensor_power_down( s_ctrl, &s_ctrl->sensordata->power_info, s_ctrl->sensor_device_type, s_ctrl->sensor_i2c_client); } #endif return rc; FREE_POWER_OFF_SETTING: kfree(power_off_setting); FREE_POWER_SETTING: kfree(power_setting); FREE_SLAVE_INFO: kfree(slave_info); return rc; }