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

Commit 9ff57cf5 authored by Om Parkash's avatar Om Parkash
Browse files

msm: camera: sensor: Add support to write sensor registers in probe



Few sensors needs to unlock register bank for reading
sensor ID from sensor register for probe. This change
adds support to write sensor registers in probe cmd
just after power on and before reading the sensor ID.

CRs-Fixed: 3034934
Change-Id: I42ad13921c8510fb5a6dde361d62b442688a99b4
Signed-off-by: default avatarOm Parkash <oparkash@codeaurora.org>
parent 0d649632
Loading
Loading
Loading
Loading
+93 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -58,6 +58,31 @@ static void cam_sensor_release_stream_rsc(
	}
}

static void cam_sensor_free_power_reg_rsc(
	struct cam_sensor_ctrl_t *s_ctrl)
{
	struct i2c_settings_array *i2c_set = NULL;
	int rc;

	i2c_set = &(s_ctrl->i2c_data.poweron_reg_settings);
	if (i2c_set->is_settings_valid == 1) {
		i2c_set->is_settings_valid = -1;
		rc = delete_request(i2c_set);
		if (rc < 0)
			CAM_ERR(CAM_SENSOR,
				"failed while deleting PowerOnReg settings");
	}

	i2c_set = &(s_ctrl->i2c_data.poweroff_reg_settings);
	if (i2c_set->is_settings_valid == 1) {
		i2c_set->is_settings_valid = -1;
		rc = delete_request(i2c_set);
		if (rc < 0)
			CAM_ERR(CAM_SENSOR,
				"failed while deleting PowerOffReg settings");
	}
}

static void cam_sensor_release_per_frame_resource(
	struct cam_sensor_ctrl_t *s_ctrl)
{
@@ -462,7 +487,8 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info,

int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf,
	struct cam_sensor_ctrl_t *s_ctrl,
	int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len)
	int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len,
	struct cam_cmd_buf_desc   *cmd_desc)
{
	int32_t rc = 0;

@@ -505,6 +531,42 @@ int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf,
		}
	}
		break;
	case 2: {
		struct i2c_settings_array *i2c_reg_settings = NULL;
		struct i2c_data_settings *i2c_data = NULL;
		struct cam_buf_io_cfg *io_cfg = NULL;

		CAM_DBG(CAM_SENSOR, "poweron_reg_settings");
		i2c_data = &(s_ctrl->i2c_data);
		i2c_reg_settings = &i2c_data->poweron_reg_settings;
		i2c_reg_settings->request_id = 0;
		rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info,
				i2c_reg_settings, cmd_desc, 1, io_cfg);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed in updating power register settings");
			return rc;
		}
	}
		break;
	case 3: {
		struct i2c_settings_array *i2c_reg_settings = NULL;
		struct i2c_data_settings *i2c_data = NULL;
		struct cam_buf_io_cfg *io_cfg = NULL;

		CAM_DBG(CAM_SENSOR, "poweroff_reg_settings");
		i2c_data = &(s_ctrl->i2c_data);
		i2c_reg_settings = &i2c_data->poweroff_reg_settings;
		i2c_reg_settings->request_id = 0;
		rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info,
				i2c_reg_settings, cmd_desc, 1, io_cfg);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed in updating power register settings");
			return rc;
		}
	}
		break;
	default:
		CAM_ERR(CAM_SENSOR, "Invalid command buffer");
		break;
@@ -552,7 +614,7 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
		rc = -EINVAL;
		goto end;
	}
	if (pkt->num_cmd_buf != 2) {
	if (pkt->num_cmd_buf < 2) {
		CAM_ERR(CAM_SENSOR, "Expected More Command Buffers : %d",
			 pkt->num_cmd_buf);
		rc = -EINVAL;
@@ -587,7 +649,7 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
		ptr = (void *) cmd_buf;

		rc = cam_handle_cmd_buffers_for_probe(ptr, s_ctrl,
			i, cmd_desc[i].length, remain_len);
			i, cmd_desc[i].length, remain_len, &cmd_desc[i]);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed to parse the command Buffer Header");
@@ -783,6 +845,14 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			CAM_ERR(CAM_SENSOR, "power up failed");
			goto free_power_settings;
		}
		if (s_ctrl->i2c_data.poweron_reg_settings.is_settings_valid) {
			rc = cam_sensor_apply_settings(s_ctrl, 0,
				CAM_SENSOR_PACKET_OPCODE_SENSOR_POWERON_REG);
			if (rc < 0) {
				CAM_ERR(CAM_SENSOR, "PowerOn REG_WR failed");
				goto free_power_settings;
			}
		}

		/* Match sensor ID */
		rc = cam_sensor_match_id(s_ctrl);
@@ -792,12 +862,22 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
			goto free_power_settings;
		}

		if (s_ctrl->i2c_data.poweroff_reg_settings.is_settings_valid) {
			rc = cam_sensor_apply_settings(s_ctrl, 0,
				CAM_SENSOR_PACKET_OPCODE_SENSOR_POWEROFF_REG);
			if (rc < 0) {
				CAM_ERR(CAM_SENSOR, "PowerOff REG_WR failed");
				goto free_power_settings;
			}
		}

		CAM_INFO(CAM_SENSOR,
			"Probe success,slot:%d,slave_addr:0x%x,sensor_id:0x%x",
			s_ctrl->soc_info.index,
			s_ctrl->sensordata->slave_info.sensor_slave_addr,
			s_ctrl->sensordata->slave_info.sensor_id);

		cam_sensor_free_power_reg_rsc(s_ctrl);
		rc = cam_sensor_power_down(s_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR, "fail in Sensor Power Down");
@@ -1099,6 +1179,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
	power_info->power_down_setting = NULL;
	power_info->power_down_setting_size = 0;
	power_info->power_setting_size = 0;
	cam_sensor_free_power_reg_rsc(s_ctrl);
	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
	return rc;
}
@@ -1285,6 +1366,14 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
			i2c_set = &s_ctrl->i2c_data.read_settings;
			break;
		}
		case CAM_SENSOR_PACKET_OPCODE_SENSOR_POWERON_REG: {
			i2c_set = &s_ctrl->i2c_data.poweron_reg_settings;
			break;
		}
		case CAM_SENSOR_PACKET_OPCODE_SENSOR_POWEROFF_REG: {
			i2c_set = &s_ctrl->i2c_data.poweroff_reg_settings;
			break;
		}
		case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE:
		case CAM_SENSOR_PACKET_OPCODE_SENSOR_PROBE:
		default:
+5 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#include "cam_sensor_dev.h"
@@ -210,6 +210,8 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client,
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.poweron_reg_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.poweroff_reg_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));

	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
@@ -347,6 +349,8 @@ static int32_t cam_sensor_driver_platform_probe(
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.poweron_reg_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.poweroff_reg_settings.list_head));
	INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head));

	for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
+5 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_SENSOR_CMN_HEADER_
@@ -153,6 +153,8 @@ enum cam_sensor_packet_opcodes {
	CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG,
	CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF,
	CAM_SENSOR_PACKET_OPCODE_SENSOR_READ,
	CAM_SENSOR_PACKET_OPCODE_SENSOR_POWERON_REG,
	CAM_SENSOR_PACKET_OPCODE_SENSOR_POWEROFF_REG,
	CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127
};

@@ -306,6 +308,8 @@ struct i2c_data_settings {
	struct i2c_settings_array streamon_settings;
	struct i2c_settings_array streamoff_settings;
	struct i2c_settings_array read_settings;
	struct i2c_settings_array poweron_reg_settings;
	struct i2c_settings_array poweroff_reg_settings;
	struct i2c_settings_array *per_frame;
};