Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +109 −111 Original line number Diff line number Diff line Loading @@ -16,6 +16,91 @@ #include "cam_sensor_util.h" #include "cam_trace.h" static int32_t cam_actuator_vreg_control( struct cam_actuator_ctrl_t *a_ctrl, int config) { int rc = 0, cnt; struct cam_hw_soc_info *soc_info; soc_info = &a_ctrl->soc_info; cnt = soc_info->num_rgltr; if (!cnt) return 0; if (cnt >= CAM_SOC_MAX_REGULATOR) { CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt); return -EINVAL; } if (config) { rc = cam_soc_util_request_platform_resource(soc_info, NULL, NULL); rc = cam_soc_util_enable_platform_resource(soc_info, false, 0, false); } else { rc = cam_soc_util_disable_platform_resource(soc_info, false, false); rc = cam_soc_util_release_platform_resource(soc_info); } return rc; } static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl) { int rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; rc = cam_actuator_vreg_control(a_ctrl, 1); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc); return rc; } gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], 1); } /* VREG needs some delay to power up */ usleep_range(2000, 2050); return rc; } static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl) { int32_t rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], GPIOF_OUT_INIT_LOW); } rc = cam_actuator_vreg_control(a_ctrl, 0); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc); return rc; } static int32_t cam_actuator_i2c_modes_util( struct camera_io_master *io_master_info, struct i2c_settings_list *i2c_list) Loading Loading @@ -324,6 +409,30 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc); return rc; } rc = cam_actuator_power_up(a_ctrl); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed"); return rc; } rc = camera_io_init(&a_ctrl->io_master_info); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "cci_init failed"); cam_actuator_power_down(a_ctrl); return rc; } rc = cam_actuator_apply_settings(a_ctrl, &a_ctrl->i2c_data.init_settings); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings"); /* Delete the request even if the apply is failed */ rc = delete_request(&a_ctrl->i2c_data.init_settings); if (rc < 0) { CAM_WARN(CAM_ACTUATOR, "Fail in deleting the Init settings"); rc = 0; } } else if ((csl_packet->header.op_code & 0xFFFFFF) == CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS) { a_ctrl->setting_apply_state = Loading Loading @@ -383,92 +492,6 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, return rc; } static int32_t cam_actuator_vreg_control( struct cam_actuator_ctrl_t *a_ctrl, int config) { int rc = 0, cnt; struct cam_hw_soc_info *soc_info; soc_info = &a_ctrl->soc_info; cnt = soc_info->num_rgltr; if (!cnt) return 0; if (cnt >= CAM_SOC_MAX_REGULATOR) { CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt); return -EINVAL; } if (config) { rc = cam_soc_util_request_platform_resource(soc_info, NULL, NULL); rc = cam_soc_util_enable_platform_resource(soc_info, false, 0, false); } else { rc = cam_soc_util_disable_platform_resource(soc_info, false, false); rc = cam_soc_util_release_platform_resource(soc_info); } return rc; } static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl) { int rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; rc = cam_actuator_vreg_control(a_ctrl, 1); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc); return rc; } gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], 1); } /* VREG needs some delay to power up */ usleep_range(2000, 2050); return rc; } static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl) { int32_t rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], GPIOF_OUT_INIT_LOW); } rc = cam_actuator_vreg_control(a_ctrl, 0); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc); return rc; } void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl) { int rc; Loading Loading @@ -597,31 +620,6 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, a_ctrl->cam_act_state); goto release_mutex; } rc = cam_actuator_power_up(a_ctrl); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed"); goto release_mutex; } rc = camera_io_init(&a_ctrl->io_master_info); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "cci_init failed"); cam_actuator_power_down(a_ctrl); } rc = cam_actuator_apply_settings(a_ctrl, &a_ctrl->i2c_data.init_settings); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings"); /* Delete the request even if the apply is failed */ rc = delete_request(&a_ctrl->i2c_data.init_settings); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Fail in deleting the Init settings"); rc = -EINVAL; goto release_mutex; } a_ctrl->cam_act_state = CAM_ACTUATOR_START; } break; Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +61 −38 Original line number Diff line number Diff line Loading @@ -436,6 +436,54 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return rc; } } rc = cam_ois_power_up(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, " OIS Power up failed"); return rc; } rc = camera_io_init(&o_ctrl->io_master_info); if (rc) { CAM_ERR(CAM_OIS, "cci_init failed"); goto pwr_dwn; } if (o_ctrl->ois_fw_flag) { rc = cam_ois_fw_download(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, "Failed OIS FW Download"); goto pwr_dwn; } } rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply Init settings"); goto pwr_dwn; } if (o_ctrl->is_ois_calib) { rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_calib_data); if (rc) { CAM_ERR(CAM_OIS, "Cannot apply calib data"); goto pwr_dwn; } } rc = delete_request(&o_ctrl->i2c_init_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Init data: rc: %d", rc); rc = 0; } rc = delete_request(&o_ctrl->i2c_calib_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Calibration data: rc: %d", rc); rc = 0; } break; case CAM_OIS_PACKET_OPCODE_OIS_CONTROL: offset = (uint32_t *)&csl_packet->payload; Loading @@ -452,13 +500,23 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings); if (rc < 0) if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply mode settings"); return rc; } rc = delete_request(i2c_reg_settings); if (rc < 0) CAM_ERR(CAM_OIS, "Fail deleting Mode data: rc: %d", rc); break; default: break; } return rc; pwr_dwn: cam_ois_power_down(o_ctrl); return rc; } void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) Loading Loading @@ -517,7 +575,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) &ois_cap, sizeof(struct cam_ois_query_cap_t))) { CAM_ERR(CAM_OIS, "Failed Copy to User"); return -EFAULT; rc = -EFAULT; goto release_mutex; } CAM_DBG(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); Loading @@ -536,41 +594,8 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state for start : %d", o_ctrl->cam_ois_state); } rc = cam_ois_power_up(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, " OIS Power up failed"); goto release_mutex; } rc = camera_io_init(&o_ctrl->io_master_info); if (rc) { CAM_ERR(CAM_OIS, "cci_init failed"); goto pwr_dwn; } if (o_ctrl->ois_fw_flag) { rc = cam_ois_fw_download(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, "Failed OIS FW Download"); goto pwr_dwn; } } rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply Init settings"); goto pwr_dwn; } if (o_ctrl->is_ois_calib) { rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_calib_data); if (rc) { CAM_ERR(CAM_OIS, "Cannot apply calib data"); goto pwr_dwn; } } o_ctrl->cam_ois_state = CAM_OIS_START; break; case CAM_CONFIG_DEV: Loading @@ -586,6 +611,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state for release : %d", o_ctrl->cam_ois_state); goto release_mutex; } if (o_ctrl->bridge_intf.device_hdl == -1) { Loading Loading @@ -625,10 +651,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "invalid opcode"); goto release_mutex; } pwr_dwn: cam_ois_power_down(o_ctrl); release_mutex: mutex_unlock(&(o_ctrl->ois_mutex)); return rc; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c +109 −111 Original line number Diff line number Diff line Loading @@ -16,6 +16,91 @@ #include "cam_sensor_util.h" #include "cam_trace.h" static int32_t cam_actuator_vreg_control( struct cam_actuator_ctrl_t *a_ctrl, int config) { int rc = 0, cnt; struct cam_hw_soc_info *soc_info; soc_info = &a_ctrl->soc_info; cnt = soc_info->num_rgltr; if (!cnt) return 0; if (cnt >= CAM_SOC_MAX_REGULATOR) { CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt); return -EINVAL; } if (config) { rc = cam_soc_util_request_platform_resource(soc_info, NULL, NULL); rc = cam_soc_util_enable_platform_resource(soc_info, false, 0, false); } else { rc = cam_soc_util_disable_platform_resource(soc_info, false, false); rc = cam_soc_util_release_platform_resource(soc_info); } return rc; } static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl) { int rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; rc = cam_actuator_vreg_control(a_ctrl, 1); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc); return rc; } gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], 1); } /* VREG needs some delay to power up */ usleep_range(2000, 2050); return rc; } static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl) { int32_t rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], GPIOF_OUT_INIT_LOW); } rc = cam_actuator_vreg_control(a_ctrl, 0); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc); return rc; } static int32_t cam_actuator_i2c_modes_util( struct camera_io_master *io_master_info, struct i2c_settings_list *i2c_list) Loading Loading @@ -324,6 +409,30 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc); return rc; } rc = cam_actuator_power_up(a_ctrl); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed"); return rc; } rc = camera_io_init(&a_ctrl->io_master_info); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "cci_init failed"); cam_actuator_power_down(a_ctrl); return rc; } rc = cam_actuator_apply_settings(a_ctrl, &a_ctrl->i2c_data.init_settings); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings"); /* Delete the request even if the apply is failed */ rc = delete_request(&a_ctrl->i2c_data.init_settings); if (rc < 0) { CAM_WARN(CAM_ACTUATOR, "Fail in deleting the Init settings"); rc = 0; } } else if ((csl_packet->header.op_code & 0xFFFFFF) == CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS) { a_ctrl->setting_apply_state = Loading Loading @@ -383,92 +492,6 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, return rc; } static int32_t cam_actuator_vreg_control( struct cam_actuator_ctrl_t *a_ctrl, int config) { int rc = 0, cnt; struct cam_hw_soc_info *soc_info; soc_info = &a_ctrl->soc_info; cnt = soc_info->num_rgltr; if (!cnt) return 0; if (cnt >= CAM_SOC_MAX_REGULATOR) { CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt); return -EINVAL; } if (config) { rc = cam_soc_util_request_platform_resource(soc_info, NULL, NULL); rc = cam_soc_util_enable_platform_resource(soc_info, false, 0, false); } else { rc = cam_soc_util_disable_platform_resource(soc_info, false, false); rc = cam_soc_util_release_platform_resource(soc_info); } return rc; } static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl) { int rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; rc = cam_actuator_vreg_control(a_ctrl, 1); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc); return rc; } gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], 1); } /* VREG needs some delay to power up */ usleep_range(2000, 2050); return rc; } static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl) { int32_t rc = 0; struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info; struct msm_camera_gpio_num_info *gpio_num_info = NULL; gpio_num_info = a_ctrl->gpio_num_info; if (soc_info->gpio_data && gpio_num_info && gpio_num_info->valid[SENSOR_VAF] == 1) { gpio_set_value_cansleep( gpio_num_info->gpio_num[SENSOR_VAF], GPIOF_OUT_INIT_LOW); } rc = cam_actuator_vreg_control(a_ctrl, 0); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc); return rc; } void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl) { int rc; Loading Loading @@ -597,31 +620,6 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, a_ctrl->cam_act_state); goto release_mutex; } rc = cam_actuator_power_up(a_ctrl); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed"); goto release_mutex; } rc = camera_io_init(&a_ctrl->io_master_info); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "cci_init failed"); cam_actuator_power_down(a_ctrl); } rc = cam_actuator_apply_settings(a_ctrl, &a_ctrl->i2c_data.init_settings); if (rc < 0) CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings"); /* Delete the request even if the apply is failed */ rc = delete_request(&a_ctrl->i2c_data.init_settings); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Fail in deleting the Init settings"); rc = -EINVAL; goto release_mutex; } a_ctrl->cam_act_state = CAM_ACTUATOR_START; } break; Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c +61 −38 Original line number Diff line number Diff line Loading @@ -436,6 +436,54 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return rc; } } rc = cam_ois_power_up(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, " OIS Power up failed"); return rc; } rc = camera_io_init(&o_ctrl->io_master_info); if (rc) { CAM_ERR(CAM_OIS, "cci_init failed"); goto pwr_dwn; } if (o_ctrl->ois_fw_flag) { rc = cam_ois_fw_download(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, "Failed OIS FW Download"); goto pwr_dwn; } } rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply Init settings"); goto pwr_dwn; } if (o_ctrl->is_ois_calib) { rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_calib_data); if (rc) { CAM_ERR(CAM_OIS, "Cannot apply calib data"); goto pwr_dwn; } } rc = delete_request(&o_ctrl->i2c_init_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Init data: rc: %d", rc); rc = 0; } rc = delete_request(&o_ctrl->i2c_calib_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Calibration data: rc: %d", rc); rc = 0; } break; case CAM_OIS_PACKET_OPCODE_OIS_CONTROL: offset = (uint32_t *)&csl_packet->payload; Loading @@ -452,13 +500,23 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings); if (rc < 0) if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply mode settings"); return rc; } rc = delete_request(i2c_reg_settings); if (rc < 0) CAM_ERR(CAM_OIS, "Fail deleting Mode data: rc: %d", rc); break; default: break; } return rc; pwr_dwn: cam_ois_power_down(o_ctrl); return rc; } void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) Loading Loading @@ -517,7 +575,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) &ois_cap, sizeof(struct cam_ois_query_cap_t))) { CAM_ERR(CAM_OIS, "Failed Copy to User"); return -EFAULT; rc = -EFAULT; goto release_mutex; } CAM_DBG(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); Loading @@ -536,41 +594,8 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state for start : %d", o_ctrl->cam_ois_state); } rc = cam_ois_power_up(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, " OIS Power up failed"); goto release_mutex; } rc = camera_io_init(&o_ctrl->io_master_info); if (rc) { CAM_ERR(CAM_OIS, "cci_init failed"); goto pwr_dwn; } if (o_ctrl->ois_fw_flag) { rc = cam_ois_fw_download(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, "Failed OIS FW Download"); goto pwr_dwn; } } rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data); if (rc < 0) { CAM_ERR(CAM_OIS, "Cannot apply Init settings"); goto pwr_dwn; } if (o_ctrl->is_ois_calib) { rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_calib_data); if (rc) { CAM_ERR(CAM_OIS, "Cannot apply calib data"); goto pwr_dwn; } } o_ctrl->cam_ois_state = CAM_OIS_START; break; case CAM_CONFIG_DEV: Loading @@ -586,6 +611,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_WARN(CAM_OIS, "Not in right state for release : %d", o_ctrl->cam_ois_state); goto release_mutex; } if (o_ctrl->bridge_intf.device_hdl == -1) { Loading Loading @@ -625,10 +651,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "invalid opcode"); goto release_mutex; } pwr_dwn: cam_ois_power_down(o_ctrl); release_mutex: mutex_unlock(&(o_ctrl->ois_mutex)); return rc; }