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

Commit b869e62f authored by Hariram Purushothaman's avatar Hariram Purushothaman Committed by Stephen Boyd
Browse files

msm: camera: Fix various small issues in cci driver



Remove some unused ioctl exposed, Also add
some bound checks for ioctl user params.

Change-Id: Ifdd441fdb25fd20b005c4e4e1ebe4e203f1216ac
CRs-Fixed: 511382
Signed-off-by: default avatarHariram Purushothaman <hpurus@codeaurora.org>
parent a4db2dab
Loading
Loading
Loading
Loading
+61 −40
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@

/* Max bytes that can be read per CCI read transaction */
#define CCI_READ_MAX 12
#define CCI_I2C_READ_MAX_RETRIES 3
#define CCI_I2C_MAX_READ 8192
#define CCI_I2C_MAX_WRITE 8192

static struct v4l2_subdev *g_cci_subdev;

@@ -87,36 +90,6 @@ static void msm_cci_set_clk_param(struct cci_device *cci_dev)
	return;
}

static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
	struct msm_camera_cci_ctrl *c_ctrl)
{
	struct cci_device *cci_dev;
	cci_dev = v4l2_get_subdevdata(sd);
	msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
		CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
	return 0;
}

static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
	struct msm_camera_cci_ctrl *c_ctrl)
{
	struct cci_device *cci_dev;
	uint32_t val;
	cci_dev = v4l2_get_subdevdata(sd);
	val = c_ctrl->cci_info->freq;
	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
		c_ctrl->cci_info->cci_i2c_master*0x100);
	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
		c_ctrl->cci_info->cci_i2c_master*0x100);
	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
		c_ctrl->cci_info->cci_i2c_master*0x100);
	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
		c_ctrl->cci_info->cci_i2c_master*0x100);
	msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
		c_ctrl->cci_info->cci_i2c_master*0x100);
	return 0;
}

static void msm_cci_flush_queue(struct cci_device *cci_dev,
	enum cci_i2c_master_t master)
{
@@ -213,8 +186,29 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
	uint16_t cmd_size = i2c_msg->size;
	struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;

	if (i2c_cmd == NULL) {
		pr_err("%s:%d Failed line\n", __func__,
			__LINE__);
		return -EINVAL;
	}

	if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) {
		pr_err("%s:%d Failed line\n", __func__, __LINE__);
		return -EINVAL;
	}

	CDBG("%s addr type %d data type %d\n", __func__,
		i2c_msg->addr_type, i2c_msg->data_type);

	if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
		pr_err("%s failed line %d\n", __func__, __LINE__);
		return -EINVAL;
	}
	if (i2c_msg->data_type >= MSM_CAMERA_I2C_DATA_TYPE_MAX) {
		pr_err("%s failed line %d\n", __func__, __LINE__);
		return -EINVAL;
	}
	/* assume total size within the max queue */
	while (cmd_size) {
		CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
@@ -321,6 +315,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
		goto ERROR;
	}

	if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
		pr_err("%s:%d More than max retries\n", __func__,
			__LINE__);
		goto ERROR;
	}

	if (read_cfg->data == NULL) {
		pr_err("%s:%d Data ptr is NULL\n", __func__,
			__LINE__);
		goto ERROR;
	}

	CDBG("%s master %d, queue %d\n", __func__, master, queue);
	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
		c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
@@ -341,6 +347,11 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
		goto ERROR;
	}

	if (read_cfg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
		CDBG("%s failed line %d\n", __func__, __LINE__);
		goto ERROR;
	}

	if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
		val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) |
			((read_cfg->addr & 0xFF) << 8);
@@ -454,9 +465,14 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
		return -EINVAL;
	}

	if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
		pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
		return -EINVAL;
	}

	master = c_ctrl->cci_info->cci_i2c_master;
	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
	if (!read_cfg->num_byte) {
	if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
		pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
		rc = -EINVAL;
		goto ERROR;
@@ -494,6 +510,10 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
	enum cci_i2c_master_t master;
	enum cci_i2c_queue_t queue = QUEUE_0;
	cci_dev = v4l2_get_subdevdata(sd);
	if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
		pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
		return -EINVAL;
	}
	master = c_ctrl->cci_info->cci_i2c_master;
	CDBG("%s master %d, queue %d\n", __func__, master, queue);
	CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
@@ -514,6 +534,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
			__LINE__, rc);
		goto ERROR;
	}
	if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
		pr_err("%s:%d More than max retries\n", __func__,
			__LINE__);
		goto ERROR;
	}

	val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
		c_ctrl->cci_info->retries << 16 |
@@ -533,7 +558,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
		goto ERROR;
	}

	msm_cci_data_queue(cci_dev, c_ctrl, queue);
	rc = msm_cci_data_queue(cci_dev, c_ctrl, queue);
	if (rc < 0) {
		CDBG("%s failed line %d\n", __func__, __LINE__);
		goto ERROR;
	}
	val = CCI_I2C_UNLOCK_CMD;
	CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
	rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
@@ -710,14 +739,6 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd,
	case MSM_CCI_RELEASE:
		rc = msm_cci_release(sd);
		break;
	case MSM_CCI_SET_SID:
		break;
	case MSM_CCI_SET_FREQ:
		rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
		break;
	case MSM_CCI_SET_SYNC_CID:
		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
		break;
	case MSM_CCI_I2C_READ:
		rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
		break;
+2 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum msm_camera_i2c_reg_addr_type {
	MSM_CAMERA_I2C_BYTE_ADDR = 1,
	MSM_CAMERA_I2C_WORD_ADDR,
	MSM_CAMERA_I2C_3B_ADDR,
	MSM_CAMERA_I2C_ADDR_TYPE_MAX,
};

enum msm_camera_i2c_data_type {
@@ -62,6 +63,7 @@ enum msm_camera_i2c_data_type {
	MSM_CAMERA_I2C_SET_WORD_MASK,
	MSM_CAMERA_I2C_UNSET_WORD_MASK,
	MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
	MSM_CAMERA_I2C_DATA_TYPE_MAX,
};

enum msm_sensor_power_seq_type_t {