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

Commit dfb9f0bd authored by depengs's avatar depengs Committed by Depeng Shao
Browse files

msm: camera: Enhance shared gpio support



Add shared pinctrl post init to suspend unused pinctrl,
and change actuator and ois module use cam_sensor_utils
interface instead of cam_utils interface.

Change-Id: I76746aee476886bf678b297a1c33ed0a23472499
Signed-off-by: default avatarDepeng Shao <depengs@codeaurora.org>
parent 4d29a0cb
Loading
Loading
Loading
Loading
+77 −47
Original line number Original line Diff line number Diff line
@@ -17,36 +17,42 @@
#include "cam_trace.h"
#include "cam_trace.h"
#include "cam_res_mgr_api.h"
#include "cam_res_mgr_api.h"


static int32_t cam_actuator_vreg_control(
int32_t cam_actuator_construct_default_power_setting(
	struct cam_actuator_ctrl_t *a_ctrl,
	struct cam_sensor_power_ctrl_t *power_info)
	int config)
{
{
	int rc = 0, cnt;
	int rc = 0;
	struct cam_hw_soc_info  *soc_info;


	soc_info = &a_ctrl->soc_info;
	power_info->power_setting_size = 1;
	cnt = soc_info->num_rgltr;
	power_info->power_setting =
		(struct cam_sensor_power_setting *)
		kzalloc(sizeof(struct cam_sensor_power_setting),
			GFP_KERNEL);
	if (!power_info->power_setting)
		return -ENOMEM;


	if (!cnt)
	power_info->power_setting[0].seq_type = SENSOR_VAF;
		return 0;
	power_info->power_setting[0].seq_val = CAM_VAF;
	power_info->power_setting[0].config_val = 1;


	if (cnt >= CAM_SOC_MAX_REGULATOR) {
	power_info->power_down_setting_size = 1;
		CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt);
	power_info->power_down_setting =
		return -EINVAL;
		(struct cam_sensor_power_setting *)
		kzalloc(sizeof(struct cam_sensor_power_setting),
			GFP_KERNEL);
	if (!power_info->power_down_setting) {
		rc = -ENOMEM;
		goto free_power_settings;
	}
	}


	if (config) {
	power_info->power_setting[0].seq_type = SENSOR_VAF;
		rc = cam_soc_util_request_platform_resource(soc_info,
	power_info->power_setting[0].seq_val = CAM_VAF;
			NULL, NULL);
	power_info->power_setting[0].config_val = 0;
		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;
	return rc;

free_power_settings:
	kfree(power_info->power_setting);
	return rc;
}
}


static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
@@ -54,22 +60,41 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
	int rc = 0;
	int rc = 0;
	struct cam_hw_soc_info  *soc_info =
	struct cam_hw_soc_info  *soc_info =
		&a_ctrl->soc_info;
		&a_ctrl->soc_info;
	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
	struct cam_actuator_soc_private  *soc_private;
	struct cam_sensor_power_ctrl_t *power_info;

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

	/* Parse and fill vreg params for power up settings */
	rc = msm_camera_fill_vreg_params(
		&a_ctrl->soc_info,
		power_info->power_setting,
		power_info->power_setting_size);
	if (rc) {
		CAM_ERR(CAM_ACTUATOR,
			"failed to fill vreg params for power up rc:%d", rc);
		return rc;
	}


	rc = cam_actuator_vreg_control(a_ctrl, 1);
	/* Parse and fill vreg params for power down settings*/
	if (rc < 0) {
	rc = msm_camera_fill_vreg_params(
		CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc);
		&a_ctrl->soc_info,
		power_info->power_down_setting,
		power_info->power_down_setting_size);
	if (rc) {
		CAM_ERR(CAM_ACTUATOR,
			"failed to fill vreg params power down rc:%d", rc);
		return rc;
		return rc;
	}
	}


	gpio_num_info = a_ctrl->gpio_num_info;
	power_info->dev = soc_info->dev;


	if (soc_info->gpio_data &&
	rc = cam_sensor_core_power_up(power_info, soc_info);
		gpio_num_info &&
	if (rc) {
		gpio_num_info->valid[SENSOR_VAF] == 1) {
		CAM_ERR(CAM_ACTUATOR, "failed in ois power up rc %d", rc);
		cam_res_mgr_gpio_set_value(
		return rc;
			gpio_num_info->gpio_num[SENSOR_VAF],
			1);
	}
	}


	/* VREG needs some delay to power up */
	/* VREG needs some delay to power up */
@@ -85,24 +110,29 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
{
{
	int32_t rc = 0;
	int32_t rc = 0;
	struct cam_hw_soc_info *soc_info =
	struct cam_sensor_power_ctrl_t *power_info;
		&a_ctrl->soc_info;
	struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info;
	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
	struct cam_actuator_soc_private  *soc_private;


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


	if (soc_info->gpio_data &&
	soc_private =
		gpio_num_info &&
		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
		gpio_num_info->valid[SENSOR_VAF] == 1) {
	power_info = &soc_private->power_info;
	soc_info = &a_ctrl->soc_info;


		cam_res_mgr_gpio_set_value(
	if (!power_info) {
			gpio_num_info->gpio_num[SENSOR_VAF],
		CAM_ERR(CAM_ACTUATOR, "failed: power_info %pK", power_info);
			GPIOF_OUT_INIT_LOW);
		return -EINVAL;
	}
	rc = msm_camera_power_down(power_info, soc_info);
	if (rc) {
		CAM_ERR(CAM_ACTUATOR, "power down the core is failed:%d", rc);
		return rc;
	}
	}

	rc = cam_actuator_vreg_control(a_ctrl, 0);
	if (rc < 0)
		CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc);


	camera_io_release(&a_ctrl->io_master_info);
	camera_io_release(&a_ctrl->io_master_info);


+10 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,16 @@


#include "cam_actuator_dev.h"
#include "cam_actuator_dev.h"


/**
 * @power_info: power setting info to control the power
 *
 * This API construct the default actuator power setting.
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int32_t cam_actuator_construct_default_power_setting(
	struct cam_sensor_power_ctrl_t *power_info);

/**
/**
 * @apply: Req mgr structure for applying request
 * @apply: Req mgr structure for applying request
 *
 *
+69 −27
Original line number Original line Diff line number Diff line
@@ -140,9 +140,11 @@ static int cam_actuator_init_subdev(struct cam_actuator_ctrl_t *a_ctrl)
static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
	const struct i2c_device_id *id)
{
{
	int32_t rc = 0, i = 0;
	int32_t                         rc = 0;
	int32_t                         i = 0;
	struct cam_actuator_ctrl_t      *a_ctrl;
	struct cam_actuator_ctrl_t      *a_ctrl;
	struct cam_hw_soc_info          *soc_info = NULL;
	struct cam_hw_soc_info          *soc_info = NULL;
	struct cam_actuator_soc_private *soc_private = NULL;


	if (client == NULL || id == NULL) {
	if (client == NULL || id == NULL) {
		CAM_ERR(CAM_ACTUATOR, "Invalid Args client: %pK id: %pK",
		CAM_ERR(CAM_ACTUATOR, "Invalid Args client: %pK id: %pK",
@@ -164,6 +166,14 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,


	i2c_set_clientdata(client, a_ctrl);
	i2c_set_clientdata(client, a_ctrl);


	soc_private = kzalloc(sizeof(struct cam_actuator_soc_private),
		GFP_KERNEL);
	if (!soc_private) {
		rc = -ENOMEM;
		goto free_ctrl;
	}
	a_ctrl->soc_info.soc_private = soc_private;

	a_ctrl->io_master_info.client = client;
	a_ctrl->io_master_info.client = client;
	soc_info = &a_ctrl->soc_info;
	soc_info = &a_ctrl->soc_info;
	soc_info->dev = &client->dev;
	soc_info->dev = &client->dev;
@@ -176,9 +186,20 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
		goto free_ctrl;
		goto free_ctrl;
	}
	}


	soc_private = (struct cam_actuator_soc_private *)(id->driver_data);
	if (!soc_private) {
		CAM_ERR(CAM_EEPROM, "board info NULL");
		rc = -EINVAL;
		goto free_ctrl;
	}

	rc = cam_actuator_init_subdev(a_ctrl);
	rc = cam_actuator_init_subdev(a_ctrl);
	if (rc)
	if (rc)
		goto free_ctrl;
		goto free_soc;

	if (soc_private->i2c_info.slave_addr != 0)
		a_ctrl->io_master_info.client->addr =
			soc_private->i2c_info.slave_addr;


	a_ctrl->i2c_data.per_frame =
	a_ctrl->i2c_data.per_frame =
		(struct i2c_settings_array *)
		(struct i2c_settings_array *)
@@ -194,14 +215,6 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
		INIT_LIST_HEAD(&(a_ctrl->i2c_data.per_frame[i].list_head));
		INIT_LIST_HEAD(&(a_ctrl->i2c_data.per_frame[i].list_head));


	rc = cam_soc_util_request_platform_resource(&a_ctrl->soc_info,
		NULL, NULL);
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR,
			"Requesting Platform Resources failed rc %d", rc);
		goto free_mem;
	}

	a_ctrl->bridge_intf.device_hdl = -1;
	a_ctrl->bridge_intf.device_hdl = -1;
	a_ctrl->bridge_intf.ops.get_dev_info =
	a_ctrl->bridge_intf.ops.get_dev_info =
		cam_actuator_publish_dev_info;
		cam_actuator_publish_dev_info;
@@ -212,6 +225,14 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,


	v4l2_set_subdevdata(&(a_ctrl->v4l2_dev_str.sd), 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 free_mem;
	}

	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;
	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;


	return rc;
	return rc;
@@ -219,6 +240,8 @@ static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
	kfree(a_ctrl->i2c_data.per_frame);
	kfree(a_ctrl->i2c_data.per_frame);
unreg_subdev:
unreg_subdev:
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
free_soc:
	kfree(soc_private);
free_ctrl:
free_ctrl:
	kfree(a_ctrl);
	kfree(a_ctrl);
	return rc;
	return rc;
@@ -269,8 +292,10 @@ static const struct of_device_id cam_actuator_driver_dt_match[] = {
static int32_t cam_actuator_driver_platform_probe(
static int32_t cam_actuator_driver_platform_probe(
	struct platform_device *pdev)
	struct platform_device *pdev)
{
{
	int32_t rc = 0, i = 0;
	int32_t                         rc = 0;
	int32_t                         i = 0;
	struct cam_actuator_ctrl_t      *a_ctrl = NULL;
	struct cam_actuator_ctrl_t      *a_ctrl = NULL;
	struct cam_actuator_soc_private *soc_private = NULL;


	/* Create sensor control structure */
	/* Create sensor control structure */
	a_ctrl = devm_kzalloc(&pdev->dev,
	a_ctrl = devm_kzalloc(&pdev->dev,
@@ -287,15 +312,28 @@ static int32_t cam_actuator_driver_platform_probe(


	a_ctrl->io_master_info.cci_client = kzalloc(sizeof(
	a_ctrl->io_master_info.cci_client = kzalloc(sizeof(
		struct cam_sensor_cci_client), GFP_KERNEL);
		struct cam_sensor_cci_client), GFP_KERNEL);
	if (!(a_ctrl->io_master_info.cci_client))
	if (!(a_ctrl->io_master_info.cci_client)) {
		return -ENOMEM;
		rc = -ENOMEM;
		goto free_ctrl;
	}

	soc_private = kzalloc(sizeof(struct cam_actuator_soc_private),
		GFP_KERNEL);
	if (!soc_private) {
		rc = -ENOMEM;
		goto free_cci_client;
	}
	a_ctrl->soc_info.soc_private = soc_private;
	soc_private->power_info.dev = &pdev->dev;


	a_ctrl->i2c_data.per_frame =
	a_ctrl->i2c_data.per_frame =
		(struct i2c_settings_array *)
		(struct i2c_settings_array *)
		kzalloc(sizeof(struct i2c_settings_array) *
		kzalloc(sizeof(struct i2c_settings_array) *
		MAX_PER_FRAME_ARRAY, GFP_KERNEL);
		MAX_PER_FRAME_ARRAY, GFP_KERNEL);
	if (a_ctrl->i2c_data.per_frame == NULL)
	if (a_ctrl->i2c_data.per_frame == NULL) {
		return -ENOMEM;
		rc = -ENOMEM;
		goto free_soc;
	}


	INIT_LIST_HEAD(&(a_ctrl->i2c_data.init_settings.list_head));
	INIT_LIST_HEAD(&(a_ctrl->i2c_data.init_settings.list_head));


@@ -305,7 +343,7 @@ static int32_t cam_actuator_driver_platform_probe(
	rc = cam_actuator_parse_dt(a_ctrl, &(pdev->dev));
	rc = cam_actuator_parse_dt(a_ctrl, &(pdev->dev));
	if (rc < 0) {
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR, "Paring actuator dt failed rc %d", rc);
		CAM_ERR(CAM_ACTUATOR, "Paring actuator dt failed rc %d", rc);
		goto free_ctrl;
		goto free_mem;
	}
	}


	/* Fill platform device id*/
	/* Fill platform device id*/
@@ -315,14 +353,6 @@ static int32_t cam_actuator_driver_platform_probe(
	if (rc)
	if (rc)
		goto free_mem;
		goto free_mem;


	rc = cam_soc_util_request_platform_resource(&a_ctrl->soc_info,
			NULL, NULL);
	if (rc < 0) {
		CAM_ERR(CAM_ACTUATOR,
			"Requesting Platform Resources failed rc %d", rc);
		goto unreg_subdev;
	}

	a_ctrl->bridge_intf.device_hdl = -1;
	a_ctrl->bridge_intf.device_hdl = -1;
	a_ctrl->bridge_intf.ops.get_dev_info =
	a_ctrl->bridge_intf.ops.get_dev_info =
		cam_actuator_publish_dev_info;
		cam_actuator_publish_dev_info;
@@ -336,11 +366,23 @@ static int32_t cam_actuator_driver_platform_probe(
	platform_set_drvdata(pdev, a_ctrl);
	platform_set_drvdata(pdev, a_ctrl);
	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, 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;
	}

	return rc;
	return rc;
unreg_subdev:
unreg_subdev:
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
free_mem:
free_mem:
	kfree(a_ctrl->i2c_data.per_frame);
	kfree(a_ctrl->i2c_data.per_frame);
free_soc:
	kfree(soc_private);
free_cci_client:
	kfree(a_ctrl->io_master_info.cci_client);
free_ctrl:
free_ctrl:
	devm_kfree(&pdev->dev, a_ctrl);
	devm_kfree(&pdev->dev, a_ctrl);
	return rc;
	return rc;
+17 −3
Original line number Original line Diff line number Diff line
@@ -53,12 +53,27 @@ enum cam_actuator_apply_state_t {
	ACT_APPLY_SETTINGS_LATER,
	ACT_APPLY_SETTINGS_LATER,
};
};


enum cam_actator_state {
enum cam_actuator_state {
	CAM_ACTUATOR_INIT,
	CAM_ACTUATOR_INIT,
	CAM_ACTUATOR_ACQUIRE,
	CAM_ACTUATOR_ACQUIRE,
	CAM_ACTUATOR_START,
	CAM_ACTUATOR_START,
};
};


/**
 * struct cam_actuator_i2c_info_t - I2C info
 * @slave_addr      :   slave address
 * @i2c_freq_mode   :   i2c frequency mode
 */
struct cam_actuator_i2c_info_t {
	uint16_t slave_addr;
	uint8_t i2c_freq_mode;
};

struct cam_actuator_soc_private {
	struct cam_actuator_i2c_info_t i2c_info;
	struct cam_sensor_power_ctrl_t power_info;
};

/**
/**
 * struct intf_params
 * struct intf_params
 * @device_hdl: Device Handle
 * @device_hdl: Device Handle
@@ -101,8 +116,7 @@ struct cam_actuator_ctrl_t {
	struct mutex actuator_mutex;
	struct mutex actuator_mutex;
	uint32_t id;
	uint32_t id;
	enum cam_actuator_apply_state_t setting_apply_state;
	enum cam_actuator_apply_state_t setting_apply_state;
	enum cam_actator_state cam_act_state;
	enum cam_actuator_state cam_act_state;
	struct msm_camera_gpio_num_info *gpio_num_info;
	uint8_t cam_pinctrl_status;
	uint8_t cam_pinctrl_status;
	struct cam_subdev v4l2_dev_str;
	struct cam_subdev v4l2_dev_str;
	struct i2c_data_settings i2c_data;
	struct i2c_data_settings i2c_data;
+8 −6
Original line number Original line Diff line number Diff line
@@ -24,6 +24,9 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl,
{
{
	int32_t                         rc = 0;
	int32_t                         rc = 0;
	struct cam_hw_soc_info          *soc_info = &a_ctrl->soc_info;
	struct cam_hw_soc_info          *soc_info = &a_ctrl->soc_info;
	struct cam_actuator_soc_private *soc_private =
		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
	struct cam_sensor_power_ctrl_t  *power_info = &soc_private->power_info;
	struct device_node              *of_node = NULL;
	struct device_node              *of_node = NULL;


	/* Initialize mutex */
	/* Initialize mutex */
@@ -61,9 +64,8 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl,
	}
	}


	rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
	rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
		&a_ctrl->gpio_num_info);
		&power_info->gpio_num_info);

	if ((rc < 0) || (!power_info->gpio_num_info)) {
	if ((rc < 0) || (!a_ctrl->gpio_num_info)) {
		CAM_ERR(CAM_ACTUATOR, "No/Error Actuator GPIOs");
		CAM_ERR(CAM_ACTUATOR, "No/Error Actuator GPIOs");
		return -EINVAL;
		return -EINVAL;
	}
	}
Loading