static int32_t msm_camera_cci_i2c_set_mask(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t mask, enum msm_camera_i2c_data_type data_type, uint16_t set_mask) { int32_t rc; uint16_t reg_data; rc = msm_camera_cci_i2c_read(client, addr, ®_data, data_type); if (rc < 0) { S_I2C_DBG("%s read fail\n", __func__); return rc; } S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n", __func__, addr, reg_data, mask); if (set_mask) reg_data |= mask; else reg_data &= ~mask; S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data); rc = msm_camera_cci_i2c_write(client, addr, reg_data, data_type); if (rc < 0) S_I2C_DBG("%s write fail\n", __func__); return rc; }
int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t *data, enum msm_camera_i2c_data_type data_type) { int32_t rc = -EFAULT; unsigned char buf[client->addr_type+data_type]; struct msm_camera_cci_ctrl cci_ctrl; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) || (data_type != MSM_CAMERA_I2C_BYTE_DATA && data_type != MSM_CAMERA_I2C_WORD_DATA)) return rc; cci_ctrl.cmd = MSM_CCI_I2C_READ; cci_ctrl.cci_info = client->cci_client; cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr; cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type; cci_ctrl.cfg.cci_i2c_read_cfg.data = buf; cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = data_type; rc = v4l2_subdev_call(client->cci_client->cci_subdev, core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); if (rc < 0) { pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); return rc; } rc = cci_ctrl.status; if (data_type == MSM_CAMERA_I2C_BYTE_DATA) *data = buf[0]; else *data = buf[0] << 8 | buf[1]; S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data); return rc; }
int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client, uint32_t addr, uint8_t *data, uint32_t num_byte) { int32_t rc = -EFAULT; uint8_t i = 0; struct msm_camera_cci_ctrl cci_ctrl; struct msm_camera_i2c_reg_conf reg_conf_tbl[num_byte]; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) || num_byte == 0) return rc; S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n", __func__, addr, num_byte); memset(reg_conf_tbl, 0, num_byte * sizeof(struct msm_camera_i2c_reg_conf)); reg_conf_tbl[0].reg_addr = addr; for (i = 0; i < num_byte; i++) reg_conf_tbl[i].reg_data = data[i]; cci_ctrl.cmd = MSM_CCI_I2C_WRITE; cci_ctrl.cci_info = client->cci_client; cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl; cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA; cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type; cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte; rc = v4l2_subdev_call(client->cci_client->cci_subdev, core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc); rc = cci_ctrl.status; return rc; }
static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data, enum msm_camera_i2c_data_type data_type) { int32_t rc; uint16_t reg_data = 0; int data_len = 0; switch (data_type) { case MSM_CAMERA_I2C_BYTE_DATA: case MSM_CAMERA_I2C_WORD_DATA: data_len = data_type; break; case MSM_CAMERA_I2C_SET_BYTE_MASK: case MSM_CAMERA_I2C_UNSET_BYTE_MASK: data_len = MSM_CAMERA_I2C_BYTE_DATA; break; case MSM_CAMERA_I2C_SET_WORD_MASK: case MSM_CAMERA_I2C_UNSET_WORD_MASK: data_len = MSM_CAMERA_I2C_WORD_DATA; break; default: pr_err("%s: Unsupport data type: %d\n", __func__, data_type); break; } rc = msm_camera_cci_i2c_read(client, addr, ®_data, data_len); if (rc < 0) return rc; rc = I2C_COMPARE_MISMATCH; switch (data_type) { case MSM_CAMERA_I2C_BYTE_DATA: case MSM_CAMERA_I2C_WORD_DATA: if (data == reg_data) rc = I2C_COMPARE_MATCH; break; case MSM_CAMERA_I2C_SET_BYTE_MASK: case MSM_CAMERA_I2C_SET_WORD_MASK: if ((reg_data & data) == data) rc = I2C_COMPARE_MATCH; break; case MSM_CAMERA_I2C_UNSET_BYTE_MASK: case MSM_CAMERA_I2C_UNSET_WORD_MASK: if (!(reg_data & data)) rc = I2C_COMPARE_MATCH; break; default: pr_err("%s: Unsupport data type: %d\n", __func__, data_type); break; } S_I2C_DBG("%s: Register and data match result %d\n", __func__, rc); return rc; }
int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client, uint32_t addr, uint8_t *data, uint32_t num_byte) { int32_t rc = -EFAULT; unsigned char *buf = NULL; int i; struct msm_camera_cci_ctrl cci_ctrl; /* HTC_START , add to fix Klocwork issue */ cci_ctrl.status = 0; /* HTC_END */ if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) || num_byte == 0) return rc; buf = kzalloc(num_byte, GFP_KERNEL); if (!buf) { pr_err("%s:%d no memory\n", __func__, __LINE__); return -ENOMEM; } cci_ctrl.cmd = MSM_CCI_I2C_READ; cci_ctrl.cci_info = client->cci_client; cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr; cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = client->addr_type; cci_ctrl.cfg.cci_i2c_read_cfg.data = buf; cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte; rc = v4l2_subdev_call(client->cci_client->cci_subdev, core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc); rc = cci_ctrl.status; S_I2C_DBG("%s addr = 0x%x", __func__, addr); for (i = 0; i < num_byte; i++) { data[i] = buf[i]; S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]); S_I2C_DBG("Data: 0x%x\n", data[i]); } kfree(buf); return rc; }
int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data, enum msm_camera_i2c_data_type data_type) { int32_t rc; S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n", __func__, addr, data, data_type); rc = msm_camera_cci_i2c_compare(client, addr, data, data_type); return rc; }
int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data, enum msm_camera_i2c_data_type data_type) { int32_t rc = -EFAULT; int i; S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n", __func__, addr, data, data_type); for (i = 0; i < I2C_POLL_MAX_ITERATION; i++) { rc = msm_camera_cci_i2c_compare(client, addr, data, data_type); if (rc == 0 || rc < 0) break; usleep_range(10000, 11000); } return rc; }
int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client, uint32_t addr, uint8_t *data, uint32_t num_byte) { int32_t rc = -EFAULT; uint8_t i = 0; struct msm_camera_cci_ctrl cci_ctrl; struct msm_camera_i2c_reg_array *reg_conf_tbl = NULL; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) || num_byte == 0) return rc; if (num_byte > I2C_SEQ_REG_DATA_MAX) { pr_err("%s: num_byte=%d clamped to max supported %d\n", __func__, num_byte, I2C_SEQ_REG_DATA_MAX); return rc; } S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n", __func__, addr, num_byte); reg_conf_tbl = kzalloc(num_byte * (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); if (!reg_conf_tbl) { pr_err("%s:%d no memory\n", __func__, __LINE__); return -ENOMEM; } reg_conf_tbl[0].reg_addr = addr; for (i = 0; i < num_byte; i++) { reg_conf_tbl[i].reg_data = data[i]; reg_conf_tbl[i].delay = 0; } cci_ctrl.cmd = MSM_CCI_I2C_WRITE_SEQ; cci_ctrl.cci_info = client->cci_client; cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = reg_conf_tbl; cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA; cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type; cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte; rc = v4l2_subdev_call(client->cci_client->cci_subdev, core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); CDBG("%s line %d rc = %d\n", __func__, __LINE__, rc); rc = cci_ctrl.status; kfree(reg_conf_tbl); reg_conf_tbl = NULL; return rc; }