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

Commit 6cfde9bd authored by Viswanadha Raju Thotakura's avatar Viswanadha Raju Thotakura Committed by Matt Wagantall
Browse files

msm: camera: support for sequential write



Add support for sequential write of data from CCI,
this supports (1,1),(2,1),(1,2) bytes of addr
and data sizes.

Change-Id: Idd398d51f255a3b0a04592e3e6b16d2a6592aa82
Signed-off-by: default avatarViswanadha Raju Thotakura <viswanad@codeaurora.org>
parent 1916b7e8
Loading
Loading
Loading
Loading
+51 −14
Original line number Diff line number Diff line
@@ -178,13 +178,29 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
	return rc;
}

static int32_t msm_cci_get_queue_free_size(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	uint32_t read_val = 0;
	uint32_t reg_offset = master * 0x200 + queue * 0x100;
	read_val = msm_camera_io_r_mb(cci_dev->base +
		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
	CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d\n",
		__func__, __LINE__, read_val,
		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
	return (cci_dev->
		cci_i2c_queue_info[master][queue].max_queue_size) -
		read_val;
}

static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
	struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue)
{
	uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
	int32_t rc = 0;
	int32_t rc = 0, free_size = 0, en_seq_write = 0;
	uint32_t cmd = 0, delay = 0;
	uint8_t data[11];
	uint8_t data[12];
	uint16_t reg_addr = 0;
	struct msm_camera_i2c_reg_setting *i2c_msg =
		&c_ctrl->cfg.cci_i2c_write_cfg;
@@ -231,6 +247,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
		if (c_ctrl->cmd == MSM_CCI_I2C_WRITE)
			reg_addr = i2c_cmd->reg_addr;

		if (en_seq_write == 0) {
			/* either byte or word addr */
			if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
				data[i++] = reg_addr;
@@ -238,27 +255,38 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
				data[i++] = (reg_addr & 0xFF00) >> 8;
				data[i++] = reg_addr & 0x00FF;
			}
		}
		/* max of 10 data bytes */
		do {
			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
				data[i++] = i2c_cmd->reg_data;
				reg_addr++;
			} else {
				if ((i + 1) <= 10) {
				if ((i + 1) <= cci_dev->payload_size) {
					data[i++] = (i2c_cmd->reg_data &
						0xFF00) >> 8; /* MSB */
					data[i++] = i2c_cmd->reg_data &
						0x00FF; /* LSB */
					reg_addr += 2;
					reg_addr++;
				} else
					break;
			}
			i2c_cmd++;
			--cmd_size;
		} while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) &&
				(cmd_size > 0) && (i <= 10));

				(cmd_size > 0) && (i <= cci_dev->payload_size));
		free_size = msm_cci_get_queue_free_size(cci_dev, master,
				queue);
		if ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) &&
			((i-1) == MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11) &&
			cci_dev->support_seq_write && cmd_size > 0 &&
			free_size > BURST_MIN_FREE_SIZE) {
				data[0] |= 0xF0;
				en_seq_write = 1;
		} else {
			data[0] |= ((i-1) << 4);
			en_seq_write = 0;
		}
		len = ((i-1)/4) + 1;
		rc = msm_cci_validate_queue(cci_dev, len, master, queue);
		if (rc < 0) {
@@ -275,7 +303,8 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
				master * 0x200 + queue * 0x100);
		}
		if ((delay > 0) && (delay < CCI_MAX_DELAY)) {
		if ((delay > 0) && (delay < CCI_MAX_DELAY) &&
			en_seq_write == 0) {
			cmd = (uint32_t)((delay * cci_dev->cycles_per_us) /
				0x100);
			cmd <<= 4;
@@ -823,6 +852,14 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
		CCI_HW_VERSION_ADDR);
	pr_info("%s:%d: hw_version = 0x%x\n", __func__, __LINE__,
		cci_dev->hw_version);
	cci_dev->payload_size =
			MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10;
	cci_dev->support_seq_write = 0;
	if (cci_dev->hw_version >= 0x10020000) {
		cci_dev->payload_size =
			MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
		cci_dev->support_seq_write = 1;
	}
	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
	msm_camera_io_w_mb(CCI_RESET_CMD_RMSK, cci_dev->base +
			CCI_RESET_CMD_ADDR);
+5 −1
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@
#define CCI_NUM_CLK_MAX	16
#define CCI_NUM_CLK_CASES 5
#define CCI_CLK_SRC_NAME "cci_src_clk"

#define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_10 10
#define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11 11
#define BURST_MIN_FREE_SIZE 8

enum cci_i2c_queue_t {
	QUEUE_0,
@@ -156,6 +158,8 @@ struct cci_device {
	struct camera_vreg_t *cci_vreg;
	struct regulator *cci_reg_ptr[MAX_REGULATOR];
	int32_t regulator_count;
	uint8_t payload_size;
	uint8_t support_seq_write;
};

enum msm_cci_i2c_cmd_type {