Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8e674d8 authored by Sureshnaidu Laveti's avatar Sureshnaidu Laveti
Browse files

msm: camera: Apply power settings from userspace



Parse and apply power settings received from
user space for Actuator and OIS devices.
In the absence of power settings from user space,
default power settings will be used.

Change-Id: I46925e43cba279eed690a876ccba54aef28cd4bf
Signed-off-by: default avatarSureshnaidu Laveti <lsuresh@codeaurora.org>
parent 0bd74f63
Loading
Loading
Loading
Loading
+156 −78
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ int32_t cam_actuator_construct_default_power_setting(
	power_info->power_setting[0].seq_type = SENSOR_VAF;
	power_info->power_setting[0].seq_val = CAM_VAF;
	power_info->power_setting[0].config_val = 1;
	power_info->power_setting[0].delay = 2;

	power_info->power_down_setting_size = 1;
	power_info->power_down_setting =
@@ -67,6 +68,18 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
	power_info = &soc_private->power_info;

	if ((power_info->power_setting == NULL) &&
		(power_info->power_down_setting == NULL)) {
		CAM_INFO(CAM_ACTUATOR,
			"Using default power settings");
		rc = cam_actuator_construct_default_power_setting(power_info);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR,
				"Construct default actuator power setting failed.");
			return rc;
		}
	}

	/* Parse and fill vreg params for power up settings */
	rc = msm_camera_fill_vreg_params(
		&a_ctrl->soc_info,
@@ -93,16 +106,14 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)

	rc = cam_sensor_core_power_up(power_info, soc_info);
	if (rc) {
		CAM_ERR(CAM_ACTUATOR, "failed in ois power up rc %d", rc);
		CAM_ERR(CAM_ACTUATOR,
			"failed in actuator power up rc %d", rc);
		return rc;
	}

	/* VREG needs some delay to power up */
	usleep_range(2000, 2050);

	rc = camera_io_init(&a_ctrl->io_master_info);
	if (rc < 0)
		CAM_ERR(CAM_ACTUATOR, "cci_init failed: rc: %d", rc);
		CAM_ERR(CAM_ACTUATOR, "cci init failed: rc: %d", rc);

	return rc;
}
@@ -115,7 +126,7 @@ static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
	struct cam_actuator_soc_private  *soc_private;

	if (!a_ctrl) {
		CAM_ERR(CAM_ACTUATOR, "failed: e_ctrl %pK", a_ctrl);
		CAM_ERR(CAM_ACTUATOR, "failed: a_ctrl %pK", a_ctrl);
		return -EINVAL;
	}

@@ -370,22 +381,33 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
	void *arg)
{
	int32_t  rc = 0;
	int32_t  i = 0;
	uint32_t total_cmd_buf_in_bytes = 0;
	size_t   len_of_buff = 0;
	uint32_t *offset = NULL;
	uint32_t *cmd_buf = NULL;
	uint64_t generic_ptr;
	struct common_header      *cmm_hdr = NULL;
	struct cam_control        *ioctl_ctrl = NULL;
	struct cam_packet         *csl_packet = NULL;
	struct cam_config_dev_cmd config;
	struct i2c_data_settings  *i2c_data = NULL;
	struct i2c_settings_array *i2c_reg_settings = NULL;
	struct cam_cmd_buf_desc   *cmd_desc = NULL;
	size_t len_of_buff = 0;
	uint32_t *offset = NULL, *cmd_buf;
	struct cam_req_mgr_add_request  add_req;
	struct cam_actuator_soc_private *soc_private = NULL;
	struct cam_sensor_power_ctrl_t  *power_info = NULL;

	if (!a_ctrl || !arg) {
		CAM_ERR(CAM_ACTUATOR, "Invalid Args");
		return -EINVAL;
	}

	soc_private =
		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;

	power_info = &soc_private->power_info;

	ioctl_ctrl = (struct cam_control *)arg;
	if (copy_from_user(&config, (void __user *) ioctl_ctrl->handle,
		sizeof(config)))
@@ -405,53 +427,99 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
		return -EINVAL;
	}

	csl_packet = (struct cam_packet *)(generic_ptr +
		config.offset);
	csl_packet = (struct cam_packet *)(generic_ptr + config.offset);
	CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code);

	if ((csl_packet->header.op_code & 0xFFFFFF) ==
			CAM_ACTUATOR_PACKET_OPCODE_INIT) {
		i2c_data = &(a_ctrl->i2c_data);
		i2c_reg_settings = &i2c_data->init_settings;

	switch (csl_packet->header.op_code & 0xFFFFFF) {
	case CAM_ACTUATOR_PACKET_OPCODE_INIT:
		offset = (uint32_t *)&csl_packet->payload;
		offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
		cmd_desc = (struct cam_cmd_buf_desc *)(offset);

		if (csl_packet->num_cmd_buf != 2) {
			CAM_ERR(CAM_ACTUATOR, "cmd Buffers in Init : %d",
				csl_packet->num_cmd_buf);
			return -EINVAL;
		}

		rc = cam_mem_get_cpu_buf(cmd_desc[0].mem_handle,
		/* Loop through multiple command buffers */
		for (i = 0; i < csl_packet->num_cmd_buf; i++) {
			total_cmd_buf_in_bytes = cmd_desc[i].length;
			if (!total_cmd_buf_in_bytes)
				continue;
			rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
					(uint64_t *)&generic_ptr, &len_of_buff);
			if (rc < 0) {
				CAM_ERR(CAM_ACTUATOR, "Failed to get cpu buf");
				return rc;
			}
			cmd_buf = (uint32_t *)generic_ptr;
		cmd_buf += cmd_desc->offset / sizeof(uint32_t);
		rc = cam_actuator_slaveInfo_pkt_parser(a_ctrl, cmd_buf);
			if (!cmd_buf) {
				CAM_ERR(CAM_ACTUATOR, "invalid cmd buf");
				return -EINVAL;
			}
			cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
			cmm_hdr = (struct common_header *)cmd_buf;

			switch (cmm_hdr->cmd_type) {
			case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
				CAM_DBG(CAM_ACTUATOR,
					"Received slave info buffer");
				rc = cam_actuator_slaveInfo_pkt_parser(
					a_ctrl, cmd_buf);
				if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Failed in parsing the pkt");
					CAM_ERR(CAM_ACTUATOR,
					"Failed to parse slave info: %d", rc);
					return rc;
				}
				break;
			case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
			case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN:
				CAM_DBG(CAM_ACTUATOR,
					"Received power settings buffer");
				rc = cam_sensor_update_power_settings(
					cmd_buf,
					total_cmd_buf_in_bytes,
					power_info);
				if (rc) {
					CAM_ERR(CAM_ACTUATOR,
					"Failed:parse power settings: %d",
					rc);
					return rc;
				}
		cmd_buf += (sizeof(struct cam_cmd_i2c_info)/sizeof(uint32_t));
		i2c_data->init_settings.request_id = 0;
				break;
			default:
				CAM_DBG(CAM_ACTUATOR,
					"Received initSettings buffer");
				i2c_data = &(a_ctrl->i2c_data);
				i2c_reg_settings =
					&i2c_data->init_settings;

				i2c_reg_settings->request_id = 0;
				i2c_reg_settings->is_settings_valid = 1;
		rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
			&cmd_desc[1], 1);
				rc = cam_sensor_i2c_command_parser(
					i2c_reg_settings,
					&cmd_desc[i], 1);
				if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
					CAM_ERR(CAM_ACTUATOR,
					"Failed:parse init settings: %d",
					rc);
					return rc;
				}
				break;
			}
		}

		if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE) {
			rc = cam_actuator_power_up(a_ctrl);
			if (rc < 0) {
				CAM_ERR(CAM_ACTUATOR,
					" Actuator Power up failed");
				return rc;
			}
			a_ctrl->cam_act_state = CAM_ACTUATOR_CONFIG;
		}

		rc = cam_actuator_apply_settings(a_ctrl,
			&a_ctrl->i2c_data.init_settings);
		if (rc < 0)
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
			return rc;
		}

		/* Delete the request even if the apply is failed */
		rc = delete_request(&a_ctrl->i2c_data.init_settings);
@@ -460,10 +528,16 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
				"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 =
			ACT_APPLY_SETTINGS_NOW;
		break;
	case CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS:
		if (a_ctrl->cam_act_state < CAM_ACTUATOR_CONFIG) {
			rc = -EINVAL;
			CAM_WARN(CAM_ACTUATOR,
				"Not in right state to move lens: %d",
				a_ctrl->cam_act_state);
			return rc;
		}
		a_ctrl->setting_apply_state = ACT_APPLY_SETTINGS_NOW;

		i2c_data = &(a_ctrl->i2c_data);
		i2c_reg_settings = &i2c_data->init_settings;
@@ -477,16 +551,22 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
		rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
			cmd_desc, 1);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
				rc);
			CAM_ERR(CAM_ACTUATOR,
				"Auto move lens parsing failed: %d", rc);
			return rc;
		}
		break;
	case CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS:
		if (a_ctrl->cam_act_state < CAM_ACTUATOR_CONFIG) {
			rc = -EINVAL;
			CAM_WARN(CAM_ACTUATOR,
				"Not in right state to move lens: %d",
				a_ctrl->cam_act_state);
			return rc;
		}
	} else if ((csl_packet->header.op_code & 0xFFFFFF) ==
		CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS) {
		i2c_data = &(a_ctrl->i2c_data);
		i2c_reg_settings =
			&i2c_data->per_frame
			[csl_packet->header.request_id % MAX_PER_FRAME_ARRAY];
		i2c_reg_settings = &i2c_data->per_frame[
			csl_packet->header.request_id % MAX_PER_FRAME_ARRAY];

		i2c_data->init_settings.request_id =
			csl_packet->header.request_id;
@@ -497,10 +577,11 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
		rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
			cmd_desc, 1);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
				rc);
			CAM_ERR(CAM_ACTUATOR,
				"Manual move lens parsing failed: %d", rc);
			return rc;
		}
		break;
	}

	if ((csl_packet->header.op_code & 0xFFFFFF) !=
@@ -526,12 +607,13 @@ void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl)
	if (a_ctrl->cam_act_state == CAM_ACTUATOR_INIT)
		return;

	if ((a_ctrl->cam_act_state == CAM_ACTUATOR_START) ||
		(a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE)) {
	if (a_ctrl->cam_act_state >= CAM_ACTUATOR_CONFIG) {
		rc = cam_actuator_power_down(a_ctrl);
		if (rc < 0)
			CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
	}

	if (a_ctrl->cam_act_state >= CAM_ACTUATOR_ACQUIRE) {
		rc = cam_destroy_device_hdl(a_ctrl->bridge_intf.device_hdl);
		if (rc < 0)
			CAM_ERR(CAM_ACTUATOR, "destroying  dhdl failed");
@@ -595,29 +677,25 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
			goto release_mutex;
		}

		rc = cam_actuator_power_up(a_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed");
			goto release_mutex;
		}

		a_ctrl->cam_act_state = CAM_ACTUATOR_ACQUIRE;
	}
		break;
	case CAM_RELEASE_DEV: {
		if (a_ctrl->cam_act_state != CAM_ACTUATOR_ACQUIRE) {
		if (a_ctrl->cam_act_state == CAM_ACTUATOR_START) {
			rc = -EINVAL;
			CAM_WARN(CAM_ACTUATOR,
			"Not in right state to release : %d",
			a_ctrl->cam_act_state);
				"Cant release actuator: in start state");
			goto release_mutex;
		}

		if (a_ctrl->cam_act_state == CAM_ACTUATOR_CONFIG) {
			rc = cam_actuator_power_down(a_ctrl);
			if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
				CAM_ERR(CAM_ACTUATOR,
					"Actuator Power down failed");
				goto release_mutex;
			}
		}

		if (a_ctrl->bridge_intf.device_hdl == -1) {
			CAM_ERR(CAM_ACTUATOR, "link hdl: %d device hdl: %d",
@@ -648,7 +726,7 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
	}
		break;
	case CAM_START_DEV: {
		if (a_ctrl->cam_act_state != CAM_ACTUATOR_ACQUIRE) {
		if (a_ctrl->cam_act_state != CAM_ACTUATOR_CONFIG) {
			rc = -EINVAL;
			CAM_WARN(CAM_ACTUATOR,
			"Not in right state to start : %d",
@@ -681,7 +759,7 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
						i2c_set->request_id, rc);
			}
		}
		a_ctrl->cam_act_state = CAM_ACTUATOR_ACQUIRE;
		a_ctrl->cam_act_state = CAM_ACTUATOR_CONFIG;
	}
		break;
	case CAM_CONFIG_DEV: {
+5 −22
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
	rc = cam_actuator_parse_dt(a_ctrl, &client->dev);
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR, "failed: cam_sensor_parse_dt rc %d", rc);
		goto free_ctrl;
		goto free_soc;
	}

	rc = cam_actuator_init_subdev(a_ctrl);
@@ -218,19 +218,10 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,

	v4l2_set_subdevdata(&(a_ctrl->v4l2_dev_str.sd), a_ctrl);

	rc = cam_actuator_construct_default_power_setting(
		&soc_private->power_info);
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR,
			"Construct default actuator power setting failed.");
		goto free_mem;
	}

	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;

	return rc;
free_mem:
	kfree(a_ctrl->i2c_data.per_frame);

unreg_subdev:
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
free_soc:
@@ -311,7 +302,7 @@ static int32_t cam_actuator_driver_platform_probe(
	struct cam_actuator_ctrl_t      *a_ctrl = NULL;
	struct cam_actuator_soc_private *soc_private = NULL;

	/* Create sensor control structure */
	/* Create actuator control structure */
	a_ctrl = devm_kzalloc(&pdev->dev,
		sizeof(struct cam_actuator_ctrl_t), GFP_KERNEL);
	if (!a_ctrl)
@@ -379,18 +370,10 @@ static int32_t cam_actuator_driver_platform_probe(

	platform_set_drvdata(pdev, a_ctrl);
	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, a_ctrl);

	rc = cam_actuator_construct_default_power_setting(
		&soc_private->power_info);
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR,
			"Construct default actuator power setting failed.");
		goto unreg_subdev;
	}
	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;

	return rc;
unreg_subdev:
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));

free_mem:
	kfree(a_ctrl->i2c_data.per_frame);
free_soc:
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ enum cam_actuator_apply_state_t {
enum cam_actuator_state {
	CAM_ACTUATOR_INIT,
	CAM_ACTUATOR_ACQUIRE,
	CAM_ACTUATOR_CONFIG,
	CAM_ACTUATOR_START,
};

+4 −2
Original line number Diff line number Diff line
@@ -46,8 +46,10 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl,
		CAM_DBG(CAM_ACTUATOR, "cci-master %d, rc %d",
			a_ctrl->cci_i2c_master, rc);
		if ((rc < 0) || (a_ctrl->cci_i2c_master >= MASTER_MAX)) {
			CAM_ERR(CAM_ACTUATOR, "Wrong info: dt CCI master:%d",
				a_ctrl->cci_i2c_master);
			CAM_ERR(CAM_ACTUATOR,
				"Wrong info: rc: %d, dt CCI master:%d",
				rc, a_ctrl->cci_i2c_master);
			rc = -EFAULT;
			return rc;
		}
	}
+8 −7
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
		power_info->power_setting_size);
	if (rc) {
		CAM_ERR(CAM_EEPROM,
			"failed to fill vreg params for power up rc:%d", rc);
			"failed to fill power up vreg params rc:%d", rc);
		return rc;
	}

@@ -171,7 +171,7 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
		power_info->power_down_setting_size);
	if (rc) {
		CAM_ERR(CAM_EEPROM,
			"failed to fill vreg params power down rc:%d", rc);
			"failed to fill power down vreg params  rc:%d", rc);
		return rc;
	}

@@ -588,17 +588,18 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
					sizeof(struct cam_cmd_i2c_info);
				processed_cmd_buf_in_bytes +=
					cmd_length_in_bytes;
				cmd_buf += cmd_length_in_bytes/4;
				cmd_buf += cmd_length_in_bytes/
					sizeof(uint32_t);
				break;
			case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
			case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN:
				cmd_length_in_bytes =
					sizeof(struct cam_cmd_power);
				cmd_length_in_bytes = total_cmd_buf_in_bytes;
				rc = cam_sensor_update_power_settings(cmd_buf,
					cmd_length_in_bytes, power_info);
				processed_cmd_buf_in_bytes +=
					cmd_length_in_bytes;
				cmd_buf += cmd_length_in_bytes/4;
				cmd_buf += cmd_length_in_bytes/
					sizeof(uint32_t);
				if (rc) {
					CAM_ERR(CAM_EEPROM, "Failed");
					return rc;
@@ -614,7 +615,7 @@ static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
					&cmd_length_in_bytes, &num_map);
				processed_cmd_buf_in_bytes +=
					cmd_length_in_bytes;
				cmd_buf += cmd_length_in_bytes/4;
				cmd_buf += cmd_length_in_bytes/sizeof(uint32_t);
				break;
			default:
				break;
Loading