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

Commit 98462fc2 authored by Viswanadha Raju Thotakura's avatar Viswanadha Raju Thotakura Committed by Xu Han
Browse files

msm: camera: Fix state machine for camera sensor subdevs



Fix actuator and ois state machines, otherwise cci release
is called multiple times.

Change-Id: I6e90aa5eda1a07f544dceb3f8522dc0af6e9f05d
Signed-off-by: default avatarViswanadha Raju Thotakura <viswanad@codeaurora.org>
Signed-off-by: default avatarXu Han <hanxu@codeaurora.org>
parent a5f9d251
Loading
Loading
Loading
Loading
+30 −28
Original line number Diff line number Diff line
@@ -925,7 +925,10 @@ static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
		max_code_size *= 2;

	a_ctrl->max_code_size = max_code_size;
	if ((a_ctrl->actuator_state == ACT_OPS_ACTIVE) &&
		(a_ctrl->step_position_table != NULL)) {
		kfree(a_ctrl->step_position_table);
	}
	a_ctrl->step_position_table = NULL;

	if (set_info->af_tuning_params.total_steps
@@ -1032,7 +1035,7 @@ static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
{
	int32_t rc = 0;
	CDBG("Enter\n");
	if (a_ctrl->actuator_state != ACTUATOR_POWER_DOWN) {
	if (a_ctrl->actuator_state != ACT_DISABLE_STATE) {

		if (a_ctrl->func_tbl && a_ctrl->func_tbl->actuator_park_lens) {
			rc = a_ctrl->func_tbl->actuator_park_lens(a_ctrl);
@@ -1052,7 +1055,7 @@ static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
		kfree(a_ctrl->i2c_reg_tbl);
		a_ctrl->i2c_reg_tbl = NULL;
		a_ctrl->i2c_tbl_index = 0;
		a_ctrl->actuator_state = ACTUATOR_POWER_DOWN;
		a_ctrl->actuator_state = ACT_OPS_INACTIVE;
	}
	CDBG("Exit\n");
	return rc;
@@ -1196,7 +1199,10 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl,
		return -EFAULT;
	}

	if ((a_ctrl->actuator_state == ACT_OPS_ACTIVE) &&
		(a_ctrl->i2c_reg_tbl != NULL)) {
		kfree(a_ctrl->i2c_reg_tbl);
	}
	a_ctrl->i2c_reg_tbl = NULL;
	a_ctrl->i2c_reg_tbl =
		kmalloc(sizeof(struct msm_camera_i2c_reg_array) *
@@ -1279,6 +1285,7 @@ static int msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl)
		if (rc < 0)
			pr_err("cci_init failed\n");
	}
	a_ctrl->actuator_state = ACT_OPS_ACTIVE;
	CDBG("Exit\n");
	return rc;
}
@@ -1400,7 +1407,9 @@ static int msm_actuator_close(struct v4l2_subdev *sd,
		pr_err("failed\n");
		return -EINVAL;
	}
	if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
	mutex_lock(a_ctrl->actuator_mutex);
	if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE &&
		a_ctrl->actuator_state != ACT_DISABLE_STATE) {
		rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_util(
			&a_ctrl->i2c_client, MSM_CCI_RELEASE);
		if (rc < 0)
@@ -1408,7 +1417,8 @@ static int msm_actuator_close(struct v4l2_subdev *sd,
	}
	kfree(a_ctrl->i2c_reg_tbl);
	a_ctrl->i2c_reg_tbl = NULL;

	a_ctrl->actuator_state = ACT_DISABLE_STATE;
	mutex_unlock(a_ctrl->actuator_mutex);
	CDBG("Exit\n");
	return rc;
}
@@ -1420,6 +1430,7 @@ static const struct v4l2_subdev_internal_ops msm_actuator_internal_ops = {
static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
			unsigned int cmd, void *arg)
{
	int rc;
	struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
	void __user *argp = (void __user *)arg;
	CDBG("Enter\n");
@@ -1432,8 +1443,16 @@ static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
	case MSM_SD_NOTIFY_FREEZE:
		return 0;
	case MSM_SD_SHUTDOWN:
		msm_actuator_close(sd, NULL);
		return 0;
		if (!a_ctrl->i2c_client.i2c_func_tbl) {
			pr_err("a_ctrl->i2c_client.i2c_func_tbl NULL\n");
			return -EINVAL;
		}
		rc = msm_actuator_power_down(a_ctrl);
		if (rc < 0) {
			pr_err("%s:%d Actuator Power down failed\n",
					__func__, __LINE__);
		}
		return msm_actuator_close(sd, NULL);
	default:
		return -ENOIOCTLCMD;
	}
@@ -1599,30 +1618,14 @@ static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
		return rc;
	}

	a_ctrl->actuator_state = ACTUATOR_POWER_UP;
	a_ctrl->actuator_state = ACT_ENABLE_STATE;

	CDBG("Exit\n");
	return rc;
}

static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
{
	int rc = 0;
	struct msm_actuator_ctrl_t *a_ctrl = v4l2_get_subdevdata(sd);
	CDBG("Enter\n");
	mutex_lock(a_ctrl->actuator_mutex);
	if (on)
		rc = msm_actuator_power_up(a_ctrl);
	else
		rc = msm_actuator_power_down(a_ctrl);
	mutex_unlock(a_ctrl->actuator_mutex);
	CDBG("Exit\n");
	return rc;
}

static struct v4l2_subdev_core_ops msm_actuator_subdev_core_ops = {
	.ioctl = msm_actuator_subdev_ioctl,
	.s_power = msm_actuator_power,
};

static struct v4l2_subdev_ops msm_actuator_subdev_ops = {
@@ -1684,7 +1687,6 @@ static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
	act_ctrl_t->i2c_client.client = client;
	act_ctrl_t->curr_step_pos = 0,
	act_ctrl_t->curr_region_index = 0,
	act_ctrl_t->actuator_state = ACTUATOR_POWER_DOWN;
	/* Set device type as I2C */
	act_ctrl_t->act_device_type = MSM_CAMERA_I2C_DEVICE;
	act_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
@@ -1715,7 +1717,7 @@ static int32_t msm_actuator_i2c_probe(struct i2c_client *client,
#endif
	act_ctrl_t->msm_sd.sd.devnode->fops =
		&msm_actuator_v4l2_subdev_fops;

	act_ctrl_t->actuator_state = ACT_DISABLE_STATE;
	pr_info("msm_actuator_i2c_probe: succeeded\n");
	CDBG("Exit\n");

@@ -1808,7 +1810,7 @@ static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
	msm_actuator_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ACTUATOR;
	msm_actuator_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
	msm_sd_register(&msm_actuator_t->msm_sd);
	msm_actuator_t->actuator_state = ACTUATOR_POWER_DOWN;
	msm_actuator_t->actuator_state = ACT_DISABLE_STATE;
	msm_actuator_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
	msm_actuator_v4l2_subdev_fops.compat_ioctl32 =
+5 −3
Original line number Diff line number Diff line
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -31,8 +31,10 @@
struct msm_actuator_ctrl_t;

enum msm_actuator_state_t {
	ACTUATOR_POWER_UP,
	ACTUATOR_POWER_DOWN,
	ACT_ENABLE_STATE,
	ACT_OPS_ACTIVE,
	ACT_OPS_INACTIVE,
	ACT_DISABLE_STATE,
};

struct msm_actuator_func_tbl {
+10 −0
Original line number Diff line number Diff line
@@ -893,6 +893,11 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
		pr_err("%s:%d cci_dev NULL\n", __func__, __LINE__);
		return -EINVAL;
	}
	if (cci_dev->cci_state != CCI_STATE_ENABLED) {
		pr_err("%s invalid cci state %d\n",
			__func__, cci_dev->cci_state);
		return -EINVAL;
	}

	if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX
			|| c_ctrl->cci_info->cci_i2c_master < 0) {
@@ -945,6 +950,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
		pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
		return -EINVAL;
	}
	if (cci_dev->cci_state != CCI_STATE_ENABLED) {
		pr_err("%s invalid cci state %d\n",
			__func__, cci_dev->cci_state);
		return -EINVAL;
	}
	master = c_ctrl->cci_info->cci_i2c_master;
	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
+22 −25
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ static int32_t msm_ois_power_down(struct msm_ois_ctrl_t *o_ctrl)
{
	int32_t rc = 0;
	CDBG("Enter\n");
	if (o_ctrl->ois_state != OIS_POWER_DOWN) {
	if (o_ctrl->ois_state != OIS_DISABLE_STATE) {

		rc = msm_ois_vreg_control(o_ctrl, 0);
		if (rc < 0) {
@@ -164,7 +164,7 @@ static int32_t msm_ois_power_down(struct msm_ois_ctrl_t *o_ctrl)
		}

		o_ctrl->i2c_tbl_index = 0;
		o_ctrl->ois_state = OIS_POWER_DOWN;
		o_ctrl->ois_state = OIS_OPS_INACTIVE;
	}
	CDBG("Exit\n");
	return rc;
@@ -186,6 +186,7 @@ static int msm_ois_init(struct msm_ois_ctrl_t *o_ctrl)
		if (rc < 0)
			pr_err("cci_init failed\n");
	}
	o_ctrl->ois_state = OIS_OPS_ACTIVE;
	CDBG("Exit\n");
	return rc;
}
@@ -388,13 +389,16 @@ static int msm_ois_close(struct v4l2_subdev *sd,
		pr_err("failed\n");
		return -EINVAL;
	}
	if (o_ctrl->ois_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
	mutex_lock(o_ctrl->ois_mutex);
	if (o_ctrl->ois_device_type == MSM_CAMERA_PLATFORM_DEVICE &&
		o_ctrl->ois_state != OIS_DISABLE_STATE) {
		rc = o_ctrl->i2c_client.i2c_func_tbl->i2c_util(
			&o_ctrl->i2c_client, MSM_CCI_RELEASE);
		if (rc < 0)
			pr_err("cci_init failed\n");
	}

	o_ctrl->ois_state = OIS_DISABLE_STATE;
	mutex_unlock(o_ctrl->ois_mutex);
	CDBG("Exit\n");
	return rc;
}
@@ -406,6 +410,7 @@ static const struct v4l2_subdev_internal_ops msm_ois_internal_ops = {
static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
			unsigned int cmd, void *arg)
{
	int rc;
	struct msm_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
	void __user *argp = (void __user *)arg;
	CDBG("Enter\n");
@@ -416,8 +421,16 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
	case VIDIOC_MSM_OIS_CFG:
		return msm_ois_config(o_ctrl, argp);
	case MSM_SD_SHUTDOWN:
		msm_ois_close(sd, NULL);
		return 0;
		if (!o_ctrl->i2c_client.i2c_func_tbl) {
			pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n");
			return -EINVAL;
		}
		rc = msm_ois_power_down(o_ctrl);
		if (rc < 0) {
			pr_err("%s:%d OIS Power down failed\n",
				__func__, __LINE__);
		}
		return msm_ois_close(sd, NULL);
	default:
		return -ENOIOCTLCMD;
	}
@@ -434,29 +447,13 @@ static int32_t msm_ois_power_up(struct msm_ois_ctrl_t *o_ctrl)
		return rc;
	}

	o_ctrl->ois_state = OIS_POWER_UP;
	CDBG("Exit\n");
	return rc;
}

static int32_t msm_ois_power(struct v4l2_subdev *sd, int on)
{
	int rc = 0;
	struct msm_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
	CDBG("Enter\n");
	mutex_lock(o_ctrl->ois_mutex);
	if (on)
		rc = msm_ois_power_up(o_ctrl);
	else
		rc = msm_ois_power_down(o_ctrl);
	mutex_unlock(o_ctrl->ois_mutex);
	o_ctrl->ois_state = OIS_ENABLE_STATE;
	CDBG("Exit\n");
	return rc;
}

static struct v4l2_subdev_core_ops msm_ois_subdev_core_ops = {
	.ioctl = msm_ois_subdev_ioctl,
	.s_power = msm_ois_power,
};

static struct v4l2_subdev_ops msm_ois_subdev_ops = {
@@ -527,7 +524,7 @@ static int32_t msm_ois_i2c_probe(struct i2c_client *client,
	ois_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_OIS;
	ois_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
	msm_sd_register(&ois_ctrl_t->msm_sd);
	ois_ctrl_t->ois_state = OIS_POWER_DOWN;
	ois_ctrl_t->ois_state = OIS_DISABLE_STATE;
	pr_info("msm_ois_i2c_probe: succeeded\n");
	CDBG("Exit\n");

@@ -690,7 +687,7 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev)
	msm_ois_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_OIS;
	msm_ois_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
	msm_sd_register(&msm_ois_t->msm_sd);
	msm_ois_t->ois_state = OIS_POWER_DOWN;
	msm_ois_t->ois_state = OIS_DISABLE_STATE;
	msm_ois_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
	msm_ois_v4l2_subdev_fops.compat_ioctl32 =
+5 −3
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -29,8 +29,10 @@
struct msm_ois_ctrl_t;

enum msm_ois_state_t {
	OIS_POWER_UP,
	OIS_POWER_DOWN,
	OIS_ENABLE_STATE,
	OIS_OPS_ACTIVE,
	OIS_OPS_INACTIVE,
	OIS_DISABLE_STATE,
};

struct msm_ois_vreg {