/* Copyright (c) 2017, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include "cam_cci_core.h"
#include "cam_cci_dev.h"

static int32_t cam_cci_convert_type_to_num_bytes(
	enum camera_sensor_i2c_type type)
{
	int32_t num_bytes;

	switch (type) {
	case CAMERA_SENSOR_I2C_TYPE_BYTE:
		num_bytes = 1;
		break;
	case CAMERA_SENSOR_I2C_TYPE_WORD:
		num_bytes = 2;
		break;
	case CAMERA_SENSOR_I2C_TYPE_3B:
		num_bytes = 3;
		break;
	case CAMERA_SENSOR_I2C_TYPE_DWORD:
		num_bytes = 4;
		break;
	default:
		CAM_ERR(CAM_CCI, "failed: %d", type);
		num_bytes = 0;
		break;
	}
	return num_bytes;
}

static void cam_cci_flush_queue(struct cci_device *cci_dev,
	enum cci_i2c_master_t master)
{
	int32_t rc = 0;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	cam_io_w_mb(1 << master, base + CCI_HALT_REQ_ADDR);
	rc = wait_for_completion_timeout(
		&cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "wait failed");
	} else if (rc == 0) {
		CAM_ERR(CAM_CCI, "wait timeout");

		/* Set reset pending flag to TRUE */
		cci_dev->cci_master_info[master].reset_pending = TRUE;

		/* Set proper mask to RESET CMD address based on MASTER */
		if (master == MASTER_0)
			cam_io_w_mb(CCI_M0_RESET_RMSK,
				base + CCI_RESET_CMD_ADDR);
		else
			cam_io_w_mb(CCI_M1_RESET_RMSK,
				base + CCI_RESET_CMD_ADDR);

		/* wait for reset done irq */
		rc = wait_for_completion_timeout(
			&cci_dev->cci_master_info[master].reset_complete,
			CCI_TIMEOUT);
		if (rc <= 0)
			CAM_ERR(CAM_CCI, "wait failed %d", rc);
	}
}

static int32_t cam_cci_validate_queue(struct cci_device *cci_dev,
	uint32_t len,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;
	uint32_t read_val = 0;
	uint32_t reg_offset = master * 0x200 + queue * 0x100;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	read_val = cam_io_r_mb(base +
		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d",
		read_val, len,
		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
	if ((read_val + len + 1) > cci_dev->
		cci_i2c_queue_info[master][queue].max_queue_size) {
		uint32_t reg_val = 0;
		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);

		CAM_DBG(CAM_CCI, "CCI_I2C_REPORT_CMD");
		cam_io_w_mb(report_val,
			base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
			reg_offset);
		read_val++;
		CAM_DBG(CAM_CCI,
			"CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d, queue: %d",
			read_val, queue);
		cam_io_w_mb(read_val, base +
			CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
		reg_val = 1 << ((master * 2) + queue);
		CAM_DBG(CAM_CCI, "CCI_QUEUE_START_ADDR");
		atomic_set(&cci_dev->cci_master_info[master].
						done_pending[queue], 1);
		cam_io_w_mb(reg_val, base +
			CCI_QUEUE_START_ADDR);
		CAM_DBG(CAM_CCI, "wait_for_completion_timeout");
		atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
		rc = wait_for_completion_timeout(&cci_dev->
			cci_master_info[master].report_q[queue], CCI_TIMEOUT);
		if (rc <= 0) {
			CAM_ERR(CAM_CCI, "Wait_for_completion_timeout %d");
			if (rc == 0)
				rc = -ETIMEDOUT;
			cam_cci_flush_queue(cci_dev, master);
			return rc;
		}
		rc = cci_dev->cci_master_info[master].status;
		if (rc < 0)
			CAM_ERR(CAM_CCI, "Failed rc %d", rc);
	}

	return rc;
}

static int32_t cam_cci_write_i2c_queue(struct cci_device *cci_dev,
	uint32_t val,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;
	uint32_t reg_offset = master * 0x200 + queue * 0x100;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	if (!cci_dev) {
		CAM_ERR(CAM_CCI, "Failed");
		return -EINVAL;
	}

	rc = cam_cci_validate_queue(cci_dev, 1, master, queue);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "Failed %d", rc);
		return rc;
	}
	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x",
		CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
		reg_offset, val);
	cam_io_w_mb(val, base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
		reg_offset);
	return rc;
}

static int32_t cam_cci_lock_queue(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue, uint32_t en)
{
	uint32_t val;

	if (queue != PRIORITY_QUEUE)
		return 0;

	val = en ? CCI_I2C_LOCK_CMD : CCI_I2C_UNLOCK_CMD;
	return cam_cci_write_i2c_queue(cci_dev, val, master, queue);
}

#ifdef DUMP_CCI_REGISTERS
static void cam_cci_dump_registers(struct cci_device *cci_dev,
	enum cci_i2c_master_t master, enum cci_i2c_queue_t queue)
{
	uint32_t read_val = 0;
	uint32_t i = 0;
	uint32_t reg_offset = 0;

	/* CCI Top Registers */
	CAM_DBG(CAM_CCI, "****CCI TOP Registers ****");
	for (i = 0; i < DEBUG_TOP_REG_COUNT; i++) {
		reg_offset = DEBUG_TOP_REG_START + i * 4;
		read_val = cam_io_r_mb(cci_dev->base + reg_offset);
		CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
			reg_offset, read_val);
	}

	/* CCI Master registers */
	CAM_DBG(CAM_CCI, "****CCI MASTER %d Registers ****",
		master);
	for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) {
		if (i == 6)
			continue;
		reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4;
		read_val = cam_io_r_mb(cci_dev->base + reg_offset);
		CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
			reg_offset, read_val);
	}

	/* CCI Master Queue registers */
	CAM_DBG(CAM_CCI, " **** CCI MASTER%d QUEUE%d Registers ****",
		master, queue);
	for (i = 0; i < DEBUG_MASTER_QUEUE_REG_COUNT; i++) {
		reg_offset = DEBUG_MASTER_QUEUE_REG_START +  master*0x200 +
			queue*0x100 + i * 4;
		read_val = cam_io_r_mb(cci_dev->base + reg_offset);
		CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
			reg_offset, read_val);
	}

	/* CCI Interrupt registers */
	CAM_DBG(CAM_CCI, " ****CCI Interrupt Registers ****");
	for (i = 0; i < DEBUG_INTR_REG_COUNT; i++) {
		reg_offset = DEBUG_INTR_REG_START + i * 4;
		read_val = cam_io_r_mb(cci_dev->base + reg_offset);
		CAM_DBG(CAM_CCI, "offset = 0x%X value = 0x%X",
			reg_offset, read_val);
	}
}
#endif

static uint32_t cam_cci_wait(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;

	if (!cci_dev) {
		CAM_ERR(CAM_CCI, "failed");
		return -EINVAL;
	}

	rc = wait_for_completion_timeout(&cci_dev->
		cci_master_info[master].report_q[queue], CCI_TIMEOUT);
	CAM_DBG(CAM_CCI, "wait DONE_for_completion_timeout");

	if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
		cam_cci_dump_registers(cci_dev, master, queue);
#endif
		CAM_ERR(CAM_CCI, "wait for queue: %d", queue);
		if (rc == 0)
			rc = -ETIMEDOUT;
		cam_cci_flush_queue(cci_dev, master);
		return rc;
	}
	rc = cci_dev->cci_master_info[master].status;
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "failed rc %d", rc);
		return rc;
	}

	return 0;
}

static void cam_cci_load_report_cmd(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	uint32_t reg_offset = master * 0x200 + queue * 0x100;
	uint32_t read_val = cam_io_r_mb(base +
		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
	uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);

	CAM_DBG(CAM_CCI, "CCI_I2C_REPORT_CMD curr_w_cnt: %d", read_val);
	cam_io_w_mb(report_val,
		base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
		reg_offset);
	read_val++;

	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d", read_val);
	cam_io_w_mb(read_val, base +
		CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
}

static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	uint32_t reg_val = 1 << ((master * 2) + queue);

	cam_cci_load_report_cmd(cci_dev, master, queue);
	atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
	atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1);
	cam_io_w_mb(reg_val, base +
		CCI_QUEUE_START_ADDR);

	return cam_cci_wait(cci_dev, master, queue);
}

static int32_t cam_cci_transfer_end(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;

	if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) {
		rc = cam_cci_lock_queue(cci_dev, master, queue, 0);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed line %d");
			return rc;
		}
		rc = cam_cci_wait_report_cmd(cci_dev, master, queue);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			return rc;
		}
	} else {
		atomic_set(&cci_dev->cci_master_info[master].
						done_pending[queue], 1);
		rc = cam_cci_wait(cci_dev, master, queue);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			return rc;
		}
		rc = cam_cci_lock_queue(cci_dev, master, queue, 0);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			return rc;
		}
		rc = cam_cci_wait_report_cmd(cci_dev, master, queue);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "Failed rc %d", rc);
			return rc;
		}
	}

	return rc;
}

static int32_t cam_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;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	read_val = cam_io_r_mb(base +
		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d", 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 void cam_cci_process_half_q(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;
	uint32_t reg_val = 1 << ((master * 2) + queue);

	if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) {
		cam_cci_load_report_cmd(cci_dev, master, queue);
		atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
		cam_io_w_mb(reg_val, base +
			CCI_QUEUE_START_ADDR);
	}
}

static int32_t cam_cci_process_full_q(struct cci_device *cci_dev,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;

	if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 1) {
		atomic_set(&cci_dev->cci_master_info[master].
						done_pending[queue], 1);
		rc = cam_cci_wait(cci_dev, master, queue);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			return rc;
		}
	} else {
		rc = cam_cci_wait_report_cmd(cci_dev, master, queue);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			return rc;
		}
	}

	return rc;
}

static int32_t cam_cci_calc_cmd_len(struct cci_device *cci_dev,
	struct cam_cci_ctrl *c_ctrl, uint32_t cmd_size,
	 struct cam_sensor_i2c_reg_array *i2c_cmd, uint32_t *pack)
{
	uint8_t i;
	uint32_t len = 0;
	uint8_t data_len = 0, addr_len = 0;
	uint8_t pack_max_len;
	struct cam_sensor_i2c_reg_setting *msg;
	struct cam_sensor_i2c_reg_array *cmd = i2c_cmd;
	uint32_t size = cmd_size;

	if (!cci_dev || !c_ctrl) {
		CAM_ERR(CAM_CCI, "failed");
		return -EINVAL;
	}

	msg = &c_ctrl->cfg.cci_i2c_write_cfg;
	*pack = 0;

	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;
	} else {
		addr_len = cam_cci_convert_type_to_num_bytes(msg->addr_type);
		data_len = cam_cci_convert_type_to_num_bytes(msg->data_type);
		len = data_len + addr_len;
		pack_max_len = size < (cci_dev->payload_size-len) ?
			size : (cci_dev->payload_size-len);
		for (i = 0; i < pack_max_len;) {
			if (cmd->delay || ((cmd - i2c_cmd) >= (cmd_size - 1)))
				break;
			if (cmd->reg_addr + 1 ==
				(cmd+1)->reg_addr) {
				len += data_len;
				(*pack)++;
			} else {
				break;
			}
			i += data_len;
			cmd++;
		}
	}

	if (len > cci_dev->payload_size) {
		CAM_ERR(CAM_CCI, "Len error: %d", len);
		return -EINVAL;
	}

	len += 1; /*add i2c WR command*/
	len = len/4 + 1;

	return len;
}

static uint32_t cam_cci_cycles_per_ms(unsigned long clk)
{
	uint32_t cycles_per_us;

	if (clk) {
		cycles_per_us = ((clk/1000)*256)/1000;
	} else {
		CAM_ERR(CAM_CCI, "failed: Can use default: %d",
			CYCLES_PER_MICRO_SEC_DEFAULT);
		cycles_per_us = CYCLES_PER_MICRO_SEC_DEFAULT;
	}

	return cycles_per_us;
}

void cam_cci_get_clk_rates(struct cci_device *cci_dev,
	struct cam_cci_ctrl *c_ctrl)

{
	int32_t src_clk_idx, j;
	uint32_t cci_clk_src;
	unsigned long clk;
	struct cam_cci_clk_params_t *clk_params = NULL;

	enum i2c_freq_mode i2c_freq_mode = c_ctrl->cci_info->i2c_freq_mode;
	struct cam_hw_soc_info *soc_info = &cci_dev->soc_info;

	if (i2c_freq_mode >= I2C_MAX_MODES ||
		i2c_freq_mode < I2C_STANDARD_MODE) {
		CAM_ERR(CAM_CCI, "Invalid frequency mode: %d",
			(int32_t)i2c_freq_mode);
		cci_dev->clk_level_index = -1;
		return;
	}

	clk_params = &cci_dev->cci_clk_params[i2c_freq_mode];
	cci_clk_src = clk_params->cci_clk_src;

	src_clk_idx = soc_info->src_clk_idx;

	if (src_clk_idx < 0) {
		cci_dev->cycles_per_us = CYCLES_PER_MICRO_SEC_DEFAULT;
		cci_dev->clk_level_index = 0;
		return;
	}

	if (cci_clk_src == 0) {
		clk = soc_info->clk_rate[0][src_clk_idx];
		cci_dev->cycles_per_us = cam_cci_cycles_per_ms(clk);
		cci_dev->clk_level_index = 0;
		return;
	}

	for (j = 0; j < CAM_MAX_VOTE; j++) {
		clk = soc_info->clk_rate[j][src_clk_idx];
		if (clk == cci_clk_src) {
			cci_dev->cycles_per_us = cam_cci_cycles_per_ms(clk);
			cci_dev->clk_level_index = j;
			return;
		}
	}
	return;
}

static int32_t cam_cci_set_clk_param(struct cci_device *cci_dev,
	struct cam_cci_ctrl *c_ctrl)
{
	struct cam_cci_clk_params_t *clk_params = NULL;
	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
	enum i2c_freq_mode i2c_freq_mode = c_ctrl->cci_info->i2c_freq_mode;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	if ((i2c_freq_mode >= I2C_MAX_MODES) || (i2c_freq_mode < 0)) {
		CAM_ERR(CAM_CCI, "invalid i2c_freq_mode = %d", i2c_freq_mode);
		return -EINVAL;
	}

	clk_params = &cci_dev->cci_clk_params[i2c_freq_mode];

	if (cci_dev->i2c_freq_mode[master] == i2c_freq_mode)
		return 0;
	if (master == MASTER_0) {
		cam_io_w_mb(clk_params->hw_thigh << 16 |
			clk_params->hw_tlow,
			base + CCI_I2C_M0_SCL_CTL_ADDR);
		cam_io_w_mb(clk_params->hw_tsu_sto << 16 |
			clk_params->hw_tsu_sta,
			base + CCI_I2C_M0_SDA_CTL_0_ADDR);
		cam_io_w_mb(clk_params->hw_thd_dat << 16 |
			clk_params->hw_thd_sta,
			base + CCI_I2C_M0_SDA_CTL_1_ADDR);
		cam_io_w_mb(clk_params->hw_tbuf,
			base + CCI_I2C_M0_SDA_CTL_2_ADDR);
		cam_io_w_mb(clk_params->hw_scl_stretch_en << 8 |
			clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
			base + CCI_I2C_M0_MISC_CTL_ADDR);
	} else if (master == MASTER_1) {
		cam_io_w_mb(clk_params->hw_thigh << 16 |
			clk_params->hw_tlow,
			base + CCI_I2C_M1_SCL_CTL_ADDR);
		cam_io_w_mb(clk_params->hw_tsu_sto << 16 |
			clk_params->hw_tsu_sta,
			base + CCI_I2C_M1_SDA_CTL_0_ADDR);
		cam_io_w_mb(clk_params->hw_thd_dat << 16 |
			clk_params->hw_thd_sta,
			base + CCI_I2C_M1_SDA_CTL_1_ADDR);
		cam_io_w_mb(clk_params->hw_tbuf,
			base + CCI_I2C_M1_SDA_CTL_2_ADDR);
		cam_io_w_mb(clk_params->hw_scl_stretch_en << 8 |
			clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
			base + CCI_I2C_M1_MISC_CTL_ADDR);
	}
	cci_dev->i2c_freq_mode[master] = i2c_freq_mode;

	return 0;
}

static int32_t cam_cci_data_queue(struct cci_device *cci_dev,
	struct cam_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue,
	enum cci_i2c_sync sync_en)
{
	uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
	int32_t rc = 0, free_size = 0, en_seq_write = 0;
	uint8_t data[12];
	struct cam_sensor_i2c_reg_setting *i2c_msg =
		&c_ctrl->cfg.cci_i2c_write_cfg;
	struct cam_sensor_i2c_reg_array *i2c_cmd = i2c_msg->reg_setting;
	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
	uint16_t reg_addr = 0, cmd_size = i2c_msg->size;
	uint32_t read_val = 0, reg_offset, val, delay = 0;
	uint32_t max_queue_size, queue_size = 0, cmd = 0;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;
	void __iomem *base = soc_info->reg_map[0].mem_base;

	if (i2c_cmd == NULL) {
		CAM_ERR(CAM_CCI, "Failed: i2c cmd is NULL");
		return -EINVAL;
	}

	if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) {
		CAM_ERR(CAM_CCI, "failed: invalid cmd_size %d",
			cmd_size);
		return -EINVAL;
	}

	CAM_DBG(CAM_CCI, "addr type %d data type %d cmd_size %d",
		i2c_msg->addr_type, i2c_msg->data_type, cmd_size);

	if (i2c_msg->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) {
		CAM_ERR(CAM_CCI, "failed: invalid addr_type 0x%X",
			i2c_msg->addr_type);
		return -EINVAL;
	}
	if (i2c_msg->data_type >= CAMERA_SENSOR_I2C_TYPE_MAX) {
		CAM_ERR(CAM_CCI, "failed: invalid data_type 0x%X",
			i2c_msg->data_type);
		return -EINVAL;
	}
	reg_offset = master * 0x200 + queue * 0x100;

	cam_io_w_mb(cci_dev->cci_wait_sync_cfg.cid,
		base + CCI_SET_CID_SYNC_TIMER_ADDR +
		cci_dev->cci_wait_sync_cfg.csid *
		CCI_SET_CID_SYNC_TIMER_OFFSET);

	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
		c_ctrl->cci_info->retries << 16 |
		c_ctrl->cci_info->id_map << 18;

	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x",
		CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
		reg_offset, val);
	cam_io_w_mb(val, base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
		reg_offset);

	atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0);

	max_queue_size = cci_dev->cci_i2c_queue_info[master][queue].
			max_queue_size;

	if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ)
		queue_size = max_queue_size;
	else
		queue_size = max_queue_size/2;
	reg_addr = i2c_cmd->reg_addr;

	if (sync_en == MSM_SYNC_ENABLE && cci_dev->valid_sync &&
		cmd_size < max_queue_size) {
		val = CCI_I2C_WAIT_SYNC_CMD |
			((cci_dev->cci_wait_sync_cfg.line) << 4);
		cam_io_w_mb(val,
			base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
			reg_offset);
	}

	rc = cam_cci_lock_queue(cci_dev, master, queue, 1);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "failed line %d", rc);
		return rc;
	}

	while (cmd_size) {
		uint32_t pack = 0;

		len = cam_cci_calc_cmd_len(cci_dev, c_ctrl, cmd_size,
			i2c_cmd, &pack);
		if (len <= 0) {
			CAM_ERR(CAM_CCI, "failed");
			return -EINVAL;
		}

		read_val = cam_io_r_mb(base +
			CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
		CAM_DBG(CAM_CCI, "CUR_WORD_CNT_ADDR %d len %d max %d",
			read_val, len, max_queue_size);
		/* + 1 - space alocation for Report CMD */
		if ((read_val + len + 1) > queue_size) {
			if ((read_val + len + 1) > max_queue_size) {
				rc = cam_cci_process_full_q(cci_dev,
					master, queue);
				if (rc < 0) {
					CAM_ERR(CAM_CCI, "failed rc: %d", rc);
					return rc;
				}
				continue;
			}
			cam_cci_process_half_q(cci_dev, master, queue);
		}

		CAM_DBG(CAM_CCI, "cmd_size %d addr 0x%x data 0x%x",
			cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
		delay = i2c_cmd->delay;
		i = 0;
		data[i++] = CCI_I2C_WRITE_CMD;

		/*
		 * in case of multiple command
		 * MSM_CCI_I2C_WRITE : address is not continuous, so update
		 *	address for a new packet.
		 * MSM_CCI_I2C_WRITE_SEQ : address is continuous, need to keep
		 *	the incremented address for a
		 *	new packet
		 */
		if (c_ctrl->cmd == MSM_CCI_I2C_WRITE ||
			c_ctrl->cmd == MSM_CCI_I2C_WRITE_ASYNC ||
			c_ctrl->cmd == MSM_CCI_I2C_WRITE_SYNC ||
			c_ctrl->cmd == MSM_CCI_I2C_WRITE_SYNC_BLOCK)
			reg_addr = i2c_cmd->reg_addr;

		if (en_seq_write == 0) {
			/* either byte or word addr */
			if (i2c_msg->addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE)
				data[i++] = reg_addr;
			else {
				data[i++] = (reg_addr & 0xFF00) >> 8;
				data[i++] = reg_addr & 0x00FF;
			}
		}
		/* max of 10 data bytes */
		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) {
					switch (i2c_msg->data_type) {
					case CAMERA_SENSOR_I2C_TYPE_DWORD:
						data[i++] = (i2c_cmd->reg_data &
							0xFF000000) >> 24;
						/* fallthrough */
					case CAMERA_SENSOR_I2C_TYPE_3B:
						data[i++] = (i2c_cmd->reg_data &
							0x00FF0000) >> 16;
						/* fallthrough */
					case CAMERA_SENSOR_I2C_TYPE_WORD:
						data[i++] = (i2c_cmd->reg_data &
							0x0000FF00) >> 8;
						/* fallthrough */
					case CAMERA_SENSOR_I2C_TYPE_BYTE:
						data[i++] = i2c_cmd->reg_data &
							0x000000FF;
						break;
					default:
						CAM_ERR(CAM_CCI,
							"invalid data type: %d",
							i2c_msg->data_type);
						return -EINVAL;
					}

					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 ||
			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 ||
			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) {
			data[0] |= 0xF0;
			en_seq_write = 1;
		} else {
			data[0] |= ((i-1) << 4);
			en_seq_write = 0;
		}
		len = ((i-1)/4) + 1;

		read_val = cam_io_r_mb(base +
			CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
		for (h = 0, k = 0; h < len; h++) {
			cmd = 0;
			for (j = 0; (j < 4 && k < i); j++)
				cmd |= (data[k++] << (j * 8));
			CAM_DBG(CAM_CCI,
				"LOAD_DATA_ADDR 0x%x, q: %d, len:%d, cnt: %d",
				cmd, queue, len, read_val);
			cam_io_w_mb(cmd, base +
				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
				master * 0x200 + queue * 0x100);

			read_val += 1;
			cam_io_w_mb(read_val, base +
				CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
		}

		if ((delay > 0) && (delay < CCI_MAX_DELAY) &&
			en_seq_write == 0) {
			cmd = (uint32_t)((delay * cci_dev->cycles_per_us) /
				0x100);
			cmd <<= 4;
			cmd |= CCI_I2C_WAIT_CMD;
			CAM_DBG(CAM_CCI,
				"CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x", cmd);
			cam_io_w_mb(cmd, base +
				CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
				master * 0x200 + queue * 0x100);
			read_val += 1;
			cam_io_w_mb(read_val, base +
				CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
		}
	}

	rc = cam_cci_transfer_end(cci_dev, master, queue);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "failed rc %d", rc);
		return rc;
	}

	return rc;
}

static int32_t cam_cci_read(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	int32_t rc = 0;
	uint32_t val = 0;
	int32_t read_words = 0, exp_words = 0;
	int32_t index = 0, first_byte = 0;
	uint32_t i = 0;
	enum cci_i2c_master_t master;
	enum cci_i2c_queue_t queue = QUEUE_1;
	struct cci_device *cci_dev = NULL;
	struct cam_cci_read_cfg *read_cfg = NULL;
	struct cam_hw_soc_info *soc_info = NULL;
	void __iomem *base = NULL;

	cci_dev = v4l2_get_subdevdata(sd);
	master = c_ctrl->cci_info->cci_i2c_master;
	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;

	if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX
		|| c_ctrl->cci_info->cci_i2c_master < 0) {
		CAM_ERR(CAM_CCI, "Invalid I2C master addr");
		return -EINVAL;
	}

	soc_info = &cci_dev->soc_info;
	base = soc_info->reg_map[0].mem_base;

	mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]);

	/*
	 * Todo: If there is a change in frequency of operation
	 * Wait for previos transaction to complete
	 */

	/* Set the I2C Frequency */
	rc = cam_cci_set_clk_param(cci_dev, c_ctrl);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc);
		goto rel_mutex;
	}

	/*
	 * Call validate queue to make sure queue is empty before starting.
	 * If this call fails, don't proceed with i2c_read call. This is to
	 * avoid overflow / underflow of queue
	 */
	rc = cam_cci_validate_queue(cci_dev,
		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size - 1,
		master, queue);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc);
		goto rel_mutex;
	}

	if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
		CAM_ERR(CAM_CCI, "More than max retries");
		goto rel_mutex;
	}

	if (read_cfg->data == NULL) {
		CAM_ERR(CAM_CCI, "Data ptr is NULL");
		goto rel_mutex;
	}

	CAM_DBG(CAM_CCI, "master %d, queue %d", master, queue);
	CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d",
		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
		c_ctrl->cci_info->id_map);
	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
		c_ctrl->cci_info->retries << 16 |
		c_ctrl->cci_info->id_map << 18;
	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "failed rc: %d", rc);
		goto rel_mutex;
	}

	val = CCI_I2C_LOCK_CMD;
	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "failed rc: %d", rc);
		goto rel_mutex;
	}

	if (read_cfg->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) {
		CAM_ERR(CAM_CCI, "failed : Invalid addr type: %u",
			read_cfg->addr_type);
		rc = -EINVAL;
		goto rel_mutex;
	}

	val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4);
	for (i = 0; i < read_cfg->addr_type; i++) {
		val |= ((read_cfg->addr >> (i << 3)) & 0xFF)  <<
		((read_cfg->addr_type - i) << 3);
	}

	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "failed rc: %d", rc);
		goto rel_mutex;
	}

	val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4);
	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "failed rc: %d", rc);
		goto rel_mutex;
	}

	val = CCI_I2C_UNLOCK_CMD;
	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "failed rc: %d", rc);
		goto rel_mutex;
	}

	val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR
			+ master * 0x200 + queue * 0x100);
	CAM_DBG(CAM_CCI, "cur word cnt 0x%x", val);
	cam_io_w_mb(val, base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR
			+ master * 0x200 + queue * 0x100);

	val = 1 << ((master * 2) + queue);
	cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR);
	CAM_DBG(CAM_CCI, "wait_for_completion_timeout");

	rc = wait_for_completion_timeout(&cci_dev->
		cci_master_info[master].reset_complete, CCI_TIMEOUT);
	if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
		cam_cci_dump_registers(cci_dev, master, queue);
#endif
		if (rc == 0)
			rc = -ETIMEDOUT;
		CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d", rc);
		cam_cci_flush_queue(cci_dev, master);
		goto rel_mutex;
	} else {
		rc = 0;
	}

	read_words = cam_io_r_mb(base +
		CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100);
	exp_words = ((read_cfg->num_byte / 4) + 1);
	if (read_words != exp_words) {
		CAM_ERR(CAM_CCI, "read_words = %d, exp words = %d",
			read_words, exp_words);
		memset(read_cfg->data, 0, read_cfg->num_byte);
		rc = -EINVAL;
		goto rel_mutex;
	}
	index = 0;
	CAM_DBG(CAM_CCI, "index %d num_type %d", index, read_cfg->num_byte);
	first_byte = 0;
	do {
		val = cam_io_r_mb(base +
			CCI_I2C_M0_READ_DATA_ADDR + master * 0x100);
		CAM_DBG(CAM_CCI, "read val 0x%x", val);
		for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) {
			CAM_DBG(CAM_CCI, "i:%d index:%d", i, index);
			if (!first_byte) {
				CAM_DBG(CAM_CCI, "sid 0x%x", val & 0xFF);
				first_byte++;
			} else {
				read_cfg->data[index] =
					(val  >> (i * 8)) & 0xFF;
				CAM_DBG(CAM_CCI, "data[%d] 0x%x", index,
					read_cfg->data[index]);
				index++;
			}
		}
	} while (--read_words > 0);
rel_mutex:
	mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]);

	return rc;
}

static int32_t cam_cci_i2c_write(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue,
	enum cci_i2c_sync sync_en)
{
	int32_t rc = 0;
	struct cci_device *cci_dev;
	enum cci_i2c_master_t master;

	cci_dev = v4l2_get_subdevdata(sd);

	if (cci_dev->cci_state != CCI_STATE_ENABLED) {
		CAM_ERR(CAM_CCI, "invalid cci state %d",
			cci_dev->cci_state);
		return -EINVAL;
	}
	master = c_ctrl->cci_info->cci_i2c_master;
	CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d",
		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
		c_ctrl->cci_info->id_map);

	/* Set the I2C Frequency */
	rc = cam_cci_set_clk_param(cci_dev, c_ctrl);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc);
		return rc;
	}
	/*
	 * Call validate queue to make sure queue is empty before starting.
	 * If this call fails, don't proceed with i2c_write call. This is to
	 * avoid overflow / underflow of queue
	 */
	rc = cam_cci_validate_queue(cci_dev,
		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size-1,
		master, queue);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "Initial validataion failed rc %d",
			rc);
		return rc;
	}
	if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
		CAM_ERR(CAM_CCI, "More than max retries");
		return rc;
	}
	rc = cam_cci_data_queue(cci_dev, c_ctrl, queue, sync_en);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "failed rc: %d", rc);
		return rc;
	}

	return rc;
}

static void cam_cci_write_async_helper(struct work_struct *work)
{
	int rc;
	struct cci_device *cci_dev;
	struct cci_write_async *write_async =
		container_of(work, struct cci_write_async, work);
	struct cam_sensor_i2c_reg_setting *i2c_msg;
	enum cci_i2c_master_t master;
	struct cam_cci_master_info *cci_master_info;

	cci_dev = write_async->cci_dev;
	i2c_msg = &write_async->c_ctrl.cfg.cci_i2c_write_cfg;
	master = write_async->c_ctrl.cci_info->cci_i2c_master;
	cci_master_info = &cci_dev->cci_master_info[master];

	mutex_lock(&cci_master_info->mutex_q[write_async->queue]);
	rc = cam_cci_i2c_write(&(cci_dev->v4l2_dev_str.sd),
		&write_async->c_ctrl, write_async->queue, write_async->sync_en);
	mutex_unlock(&cci_master_info->mutex_q[write_async->queue]);
	if (rc < 0)
		CAM_ERR(CAM_CCI, "failed rc: %d", rc);

	kfree(write_async->c_ctrl.cfg.cci_i2c_write_cfg.reg_setting);
	kfree(write_async);
}

static int32_t cam_cci_i2c_write_async(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue,
	enum cci_i2c_sync sync_en)
{
	int32_t rc = 0;
	struct cci_write_async *write_async;
	struct cci_device *cci_dev;
	struct cam_sensor_i2c_reg_setting *cci_i2c_write_cfg;
	struct cam_sensor_i2c_reg_setting *cci_i2c_write_cfg_w;

	cci_dev = v4l2_get_subdevdata(sd);

	write_async = kzalloc(sizeof(*write_async), GFP_KERNEL);
	if (!write_async)
		return -ENOMEM;


	INIT_WORK(&write_async->work, cam_cci_write_async_helper);
	write_async->cci_dev = cci_dev;
	write_async->c_ctrl = *c_ctrl;
	write_async->queue = queue;
	write_async->sync_en = sync_en;

	cci_i2c_write_cfg = &c_ctrl->cfg.cci_i2c_write_cfg;
	cci_i2c_write_cfg_w = &write_async->c_ctrl.cfg.cci_i2c_write_cfg;

	if (cci_i2c_write_cfg->size == 0) {
		kfree(write_async);
		return -EINVAL;
	}

	cci_i2c_write_cfg_w->reg_setting =
		kzalloc(sizeof(struct cam_sensor_i2c_reg_array)*
		cci_i2c_write_cfg->size, GFP_KERNEL);
	if (!cci_i2c_write_cfg_w->reg_setting) {
		CAM_ERR(CAM_CCI, "Couldn't allocate memory");
		kfree(write_async);
		return -ENOMEM;
	}
	memcpy(cci_i2c_write_cfg_w->reg_setting,
		cci_i2c_write_cfg->reg_setting,
		(sizeof(struct cam_sensor_i2c_reg_array)*
						cci_i2c_write_cfg->size));

	cci_i2c_write_cfg_w->addr_type = cci_i2c_write_cfg->addr_type;
	cci_i2c_write_cfg_w->addr_type = cci_i2c_write_cfg->addr_type;
	cci_i2c_write_cfg_w->data_type = cci_i2c_write_cfg->data_type;
	cci_i2c_write_cfg_w->size = cci_i2c_write_cfg->size;
	cci_i2c_write_cfg_w->delay = cci_i2c_write_cfg->delay;

	queue_work(cci_dev->write_wq[write_async->queue], &write_async->work);

	return rc;
}

static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	int32_t rc = 0;
	struct cci_device *cci_dev = NULL;
	enum cci_i2c_master_t master;
	struct cam_cci_read_cfg *read_cfg = NULL;
	uint16_t read_bytes = 0;

	if (!sd || !c_ctrl) {
		CAM_ERR(CAM_CCI, "sd %pK c_ctrl %pK", sd, c_ctrl);
		return -EINVAL;
	}
	if (!c_ctrl->cci_info) {
		CAM_ERR(CAM_CCI, "cci_info NULL");
		return -EINVAL;
	}
	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev) {
		CAM_ERR(CAM_CCI, "cci_dev NULL");
		return -EINVAL;
	}
	if (cci_dev->cci_state != CCI_STATE_ENABLED) {
		CAM_ERR(CAM_CCI, "invalid cci state %d", cci_dev->cci_state);
		return -EINVAL;
	}

	if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX
			|| c_ctrl->cci_info->cci_i2c_master < 0) {
		CAM_ERR(CAM_CCI, "Invalid I2C master addr");
		return -EINVAL;
	}

	master = c_ctrl->cci_info->cci_i2c_master;
	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
	if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
		CAM_ERR(CAM_CCI, "read num bytes 0");
		rc = -EINVAL;
		goto ERROR;
	}

	read_bytes = read_cfg->num_byte;
	do {
		if (read_bytes > CCI_READ_MAX)
			read_cfg->num_byte = CCI_READ_MAX;
		else
			read_cfg->num_byte = read_bytes;
		rc = cam_cci_read(sd, c_ctrl);
		if (rc < 0) {
			CAM_ERR(CAM_CCI, "failed rc %d", rc);
			goto ERROR;
		}
		if (read_bytes > CCI_READ_MAX) {
			read_cfg->addr += CCI_READ_MAX;
			read_cfg->data += CCI_READ_MAX;
			read_bytes -= CCI_READ_MAX;
		} else {
			read_bytes = 0;
		}
	} while (read_bytes);

ERROR:
	return rc;
}

static int32_t cam_cci_i2c_set_sync_prms(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	int32_t rc = 0;
	struct cci_device *cci_dev;

	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev || !c_ctrl) {
		CAM_ERR(CAM_CCI, "failed: invalid params %pK %pK",
			cci_dev, c_ctrl);
		rc = -EINVAL;
		return rc;
	}
	cci_dev->cci_wait_sync_cfg = c_ctrl->cfg.cci_wait_sync_cfg;
	cci_dev->valid_sync = cci_dev->cci_wait_sync_cfg.csid < 0 ? 0 : 1;

	return rc;
}

static int32_t cam_cci_release(struct v4l2_subdev *sd)
{
	uint8_t rc = 0;
	struct cci_device *cci_dev;

	cci_dev = v4l2_get_subdevdata(sd);

	rc = cam_cci_soc_release(cci_dev);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "Failed in releasing the cci: %d", rc);
		return rc;
	}

	return rc;
}

static int32_t cam_cci_write(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	int32_t rc = 0;
	struct cci_device *cci_dev;
	enum cci_i2c_master_t master;
	struct cam_cci_master_info *cci_master_info;
	uint32_t i;

	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev || !c_ctrl) {
		CAM_ERR(CAM_CCI, "failed: invalid params %pK %pK",
			cci_dev, c_ctrl);
		rc = -EINVAL;
		return rc;
	}

	master = c_ctrl->cci_info->cci_i2c_master;

	if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX
		|| c_ctrl->cci_info->cci_i2c_master < 0) {
		CAM_ERR(CAM_CCI, "Invalid I2C master addr");
		return -EINVAL;
	}

	cci_master_info = &cci_dev->cci_master_info[master];

	switch (c_ctrl->cmd) {
	case MSM_CCI_I2C_WRITE_SYNC_BLOCK:
		mutex_lock(&cci_master_info->mutex_q[SYNC_QUEUE]);
		rc = cam_cci_i2c_write(sd, c_ctrl,
			SYNC_QUEUE, MSM_SYNC_ENABLE);
		mutex_unlock(&cci_master_info->mutex_q[SYNC_QUEUE]);
		break;
	case MSM_CCI_I2C_WRITE_SYNC:
		rc = cam_cci_i2c_write_async(sd, c_ctrl,
			SYNC_QUEUE, MSM_SYNC_ENABLE);
		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,
					MSM_SYNC_DISABLE);
				mutex_unlock(&cci_master_info->mutex_q[i]);
				return rc;
			}
		}
		mutex_lock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
		rc = cam_cci_i2c_write(sd, c_ctrl,
			PRIORITY_QUEUE, MSM_SYNC_DISABLE);
		mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
		break;
	case MSM_CCI_I2C_WRITE_ASYNC:
		rc = cam_cci_i2c_write_async(sd, c_ctrl,
			PRIORITY_QUEUE, MSM_SYNC_DISABLE);
		break;
	default:
		rc = -ENOIOCTLCMD;
	}

	return rc;
}

int32_t cam_cci_core_cfg(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *cci_ctrl)
{
	int32_t rc = 0;

	CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd);
	switch (cci_ctrl->cmd) {
	case MSM_CCI_INIT:
		rc = cam_cci_init(sd, cci_ctrl);
		break;
	case MSM_CCI_RELEASE:
		rc = cam_cci_release(sd);
		break;
	case MSM_CCI_I2C_READ:
		rc = cam_cci_read_bytes(sd, cci_ctrl);
		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:
		rc = cam_cci_write(sd, cci_ctrl);
		break;
	case MSM_CCI_GPIO_WRITE:
		break;
	case MSM_CCI_SET_SYNC_CID:
		rc = cam_cci_i2c_set_sync_prms(sd, cci_ctrl);
		break;

	default:
		rc = -ENOIOCTLCMD;
	}

	cci_ctrl->status = rc;

	return rc;
}
