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

Commit 0fb02a3a authored by Karthik Anantha Ram's avatar Karthik Anantha Ram Committed by Karthik Anantha Ram
Browse files

msm: camera: Add I2C continuous write support in CCI



Provide functionality to use burst/seq write in
CCI module.

Change-Id: I633400fbaef4c97357696f7899501c60c277b253
Signed-off-by: default avatarKarthik Anantha Ram <kartanan@codeaurora.org>
parent fd4a1668
Loading
Loading
Loading
Loading
+72 −30
Original line number Diff line number Diff line
@@ -16,6 +16,70 @@
#include "cam_sensor_util.h"
#include "cam_trace.h"

static int32_t cam_actuator_i2c_modes_util(
	struct camera_io_master *io_master_info,
	struct i2c_settings_list *i2c_list)
{
	int32_t rc = 0;
	uint32_t i, size;

	if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
		rc = camera_io_dev_write(io_master_info,
			&(i2c_list->i2c_settings));
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR,
				"Failed to random write I2C settings: %d",
				rc);
			return rc;
		}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
		rc = camera_io_dev_write_continuous(
			io_master_info,
			&(i2c_list->i2c_settings),
			0);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR,
				"Failed to seq write I2C settings: %d",
				rc);
			return rc;
			}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_BURST) {
		rc = camera_io_dev_write_continuous(
			io_master_info,
			&(i2c_list->i2c_settings),
			1);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR,
				"Failed to burst write I2C settings: %d",
				rc);
			return rc;
		}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
		size = i2c_list->i2c_settings.size;
		for (i = 0; i < size; i++) {
			rc = camera_io_dev_poll(
			io_master_info,
			i2c_list->i2c_settings.
				reg_setting[i].reg_addr,
			i2c_list->i2c_settings.
				reg_setting[i].reg_data,
			i2c_list->i2c_settings.
				reg_setting[i].data_mask,
			i2c_list->i2c_settings.addr_type,
				i2c_list->i2c_settings.data_type,
			i2c_list->i2c_settings.
				reg_setting[i].delay);
			if (rc < 0) {
				CAM_ERR(CAM_ACTUATOR,
					"i2c poll apply setting Fail: %d", rc);
				return rc;
			}
		}
	}

	return rc;
}

int32_t cam_actuator_slaveInfo_pkt_parser(struct cam_actuator_ctrl_t *a_ctrl,
	uint32_t *cmd_buf)
{
@@ -52,7 +116,6 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
{
	struct i2c_settings_list *i2c_list;
	int32_t rc = 0;
	uint32_t i, size;

	if (a_ctrl == NULL || i2c_set == NULL) {
		CAM_ERR(CAM_ACTUATOR, "Invalid Args");
@@ -66,37 +129,16 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,

	list_for_each_entry(i2c_list,
		&(i2c_set->list_head), list) {
		if (i2c_list->op_code ==  CAM_SENSOR_I2C_WRITE_RANDOM) {
			rc = camera_io_dev_write(&(a_ctrl->io_master_info),
				&(i2c_list->i2c_settings));
			if (rc < 0) {
				CAM_ERR(CAM_ACTUATOR,
					"Failed in Applying i2c wrt settings");
				return rc;
			}
		} else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
			size = i2c_list->i2c_settings.size;
			for (i = 0; i < size; i++) {
				rc = camera_io_dev_poll(
		rc = cam_actuator_i2c_modes_util(
			&(a_ctrl->io_master_info),
					i2c_list->i2c_settings.
						reg_setting[i].reg_addr,
					i2c_list->i2c_settings.
						reg_setting[i].reg_data,
					i2c_list->i2c_settings.
						reg_setting[i].data_mask,
					i2c_list->i2c_settings.addr_type,
					i2c_list->i2c_settings.data_type,
					i2c_list->i2c_settings.
						reg_setting[i].delay);
			i2c_list);
		if (rc < 0) {
			CAM_ERR(CAM_ACTUATOR,
						"i2c poll apply setting Fail");
				"Failed to apply settings: %d",
				rc);
			return rc;
		}
	}
		}
	}

	return rc;
}
+13 −5
Original line number Diff line number Diff line
@@ -424,7 +424,8 @@ static int32_t cam_cci_calc_cmd_len(struct cci_device *cci_dev,
	msg = &c_ctrl->cfg.cci_i2c_write_cfg;
	*pack = 0;

	if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) {
	if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ ||
		c_ctrl->cmd == MSM_CCI_I2C_WRITE_BURST) {
		addr_len = cam_cci_convert_type_to_num_bytes(msg->addr_type);
		len = (size + addr_len) <= (cci_dev->payload_size) ?
			(size + addr_len):cci_dev->payload_size;
@@ -725,6 +726,7 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev,
		do {
			if (i2c_msg->data_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
				data[i++] = i2c_cmd->reg_data;
				if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ)
					reg_addr++;
			} else {
				if ((i + 1) <= cci_dev->payload_size) {
@@ -732,17 +734,21 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev,
						0xFF00) >> 8; /* MSB */
					data[i++] = i2c_cmd->reg_data &
						0x00FF; /* LSB */
					if (c_ctrl->cmd ==
						MSM_CCI_I2C_WRITE_SEQ)
						reg_addr++;
				} else
					break;
			}
			i2c_cmd++;
			--cmd_size;
		} while (((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) || pack--) &&
		} while (((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ ||
			c_ctrl->cmd == MSM_CCI_I2C_WRITE_BURST) || pack--) &&
				(cmd_size > 0) && (i <= cci_dev->payload_size));
		free_size = cam_cci_get_queue_free_size(cci_dev, master,
				queue);
		if ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) &&
		if ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ ||
			c_ctrl->cmd == MSM_CCI_I2C_WRITE_BURST) &&
			((i-1) == MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11) &&
			cci_dev->support_seq_write && cmd_size > 0 &&
			free_size > BURST_MIN_FREE_SIZE) {
@@ -1253,6 +1259,7 @@ static int32_t cam_cci_write(struct v4l2_subdev *sd,
		break;
	case MSM_CCI_I2C_WRITE:
	case MSM_CCI_I2C_WRITE_SEQ:
	case MSM_CCI_I2C_WRITE_BURST:
		for (i = 0; i < NUM_QUEUES; i++) {
			if (mutex_trylock(&cci_master_info->mutex_q[i])) {
				rc = cam_cci_i2c_write(sd, c_ctrl, i,
@@ -1295,6 +1302,7 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd,
		break;
	case MSM_CCI_I2C_WRITE:
	case MSM_CCI_I2C_WRITE_SEQ:
	case MSM_CCI_I2C_WRITE_BURST:
	case MSM_CCI_I2C_WRITE_SYNC:
	case MSM_CCI_I2C_WRITE_ASYNC:
	case MSM_CCI_I2C_WRITE_SYNC_BLOCK:
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ enum cam_cci_cmd_type {
	MSM_CCI_I2C_READ,
	MSM_CCI_I2C_WRITE,
	MSM_CCI_I2C_WRITE_SEQ,
	MSM_CCI_I2C_WRITE_BURST,
	MSM_CCI_I2C_WRITE_ASYNC,
	MSM_CCI_GPIO_WRITE,
	MSM_CCI_I2C_WRITE_SYNC,
+72 −7
Original line number Diff line number Diff line
@@ -127,6 +127,70 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
	return rc;
}

static int32_t cam_sensor_i2c_modes_util(
	struct camera_io_master *io_master_info,
	struct i2c_settings_list *i2c_list)
{
	int32_t rc = 0;
	uint32_t i, size;

	if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
		rc = camera_io_dev_write(io_master_info,
			&(i2c_list->i2c_settings));
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed to random write I2C settings: %d",
				rc);
			return rc;
		}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
		rc = camera_io_dev_write_continuous(
			io_master_info,
			&(i2c_list->i2c_settings),
			0);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed to seq write I2C settings: %d",
				rc);
			return rc;
		}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_BURST) {
		rc = camera_io_dev_write_continuous(
			io_master_info,
			&(i2c_list->i2c_settings),
			1);
		if (rc < 0) {
			CAM_ERR(CAM_SENSOR,
				"Failed to burst write I2C settings: %d",
				rc);
			return rc;
		}
	} else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
		size = i2c_list->i2c_settings.size;
		for (i = 0; i < size; i++) {
			rc = camera_io_dev_poll(
			io_master_info,
			i2c_list->i2c_settings.
				reg_setting[i].reg_addr,
			i2c_list->i2c_settings.
				reg_setting[i].reg_data,
			i2c_list->i2c_settings.
				reg_setting[i].data_mask,
			i2c_list->i2c_settings.addr_type,
				i2c_list->i2c_settings.data_type,
			i2c_list->i2c_settings.
				reg_setting[i].delay);
			if (rc < 0) {
				CAM_ERR(CAM_SENSOR,
					"i2c poll apply setting Fail: %d", rc);
				return rc;
			}
		}
	}

	return rc;
}

int32_t cam_sensor_update_i2c_info(struct cam_cmd_i2c_info *i2c_info,
	struct cam_sensor_ctrl_t *s_ctrl)
{
@@ -715,12 +779,13 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
		if (i2c_set->is_settings_valid == 1) {
			list_for_each_entry(i2c_list,
				&(i2c_set->list_head), list) {
				rc = camera_io_dev_write(
				rc = cam_sensor_i2c_modes_util(
					&(s_ctrl->io_master_info),
					&(i2c_list->i2c_settings));
					i2c_list);
				if (rc < 0) {
					CAM_ERR(CAM_SENSOR,
					"Failed to write the I2C settings");
						"Failed to apply settings: %d",
						rc);
					return rc;
				}
			}
@@ -738,12 +803,12 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
			i2c_set->request_id == req_id) {
			list_for_each_entry(i2c_list,
				&(i2c_set->list_head), list) {
				rc = camera_io_dev_write(
				rc = cam_sensor_i2c_modes_util(
					&(s_ctrl->io_master_info),
					&(i2c_list->i2c_settings));
					i2c_list);
				if (rc < 0) {
					CAM_ERR(CAM_SENSOR,
					"Fail to write the I2C settings: %d",
						"Failed to apply settings: %d",
						rc);
					return rc;
				}
+17 −0
Original line number Diff line number Diff line
@@ -145,6 +145,23 @@ int32_t cam_cci_i2c_write_table(
		MSM_CCI_I2C_WRITE);
}

int32_t cam_cci_i2c_write_continuous_table(
	struct camera_io_master *client,
	struct cam_sensor_i2c_reg_setting *write_setting,
	uint8_t cam_sensor_i2c_write_flag)
{
	int32_t rc = 0;

	if (cam_sensor_i2c_write_flag == 1)
		rc = cam_cci_i2c_write_table_cmd(client, write_setting,
			MSM_CCI_I2C_WRITE_BURST);
	else if (cam_sensor_i2c_write_flag == 0)
		rc = cam_cci_i2c_write_table_cmd(client, write_setting,
			MSM_CCI_I2C_WRITE_SEQ);

	return rc;
}

static int32_t cam_cci_i2c_compare(struct cam_sensor_cci_client *client,
	uint32_t addr, uint16_t data, uint16_t data_mask,
	enum camera_sensor_i2c_type data_type,
Loading