Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +123 −41 Original line number Diff line number Diff line Loading @@ -885,20 +885,39 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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 */ mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* 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; mutex_unlock(&cci_dev->cci_master_info[master].mutex); goto rel_master; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * 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 Loading @@ -909,24 +928,24 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; goto rel_mutex_q; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; goto rel_mutex_q; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; goto rel_mutex_q; } 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; goto rel_mutex_q; } CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d", Loading @@ -938,14 +957,14 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); Loading @@ -957,21 +976,21 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR Loading Loading @@ -1002,7 +1021,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, cam_cci_dump_registers(cci_dev, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } read_words = cam_io_r_mb(base + Loading Loading @@ -1083,7 +1102,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } break; } Loading @@ -1092,8 +1111,15 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, CAM_DBG(CAM_CCI, "Burst read successful words_read %d", total_read_words); rel_mutex: rel_mutex_q: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); rel_master: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading Loading @@ -1125,20 +1151,38 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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 */ mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* Set the I2C Frequency */ rc = cam_cci_set_clk_param(cci_dev, c_ctrl); if (rc < 0) { mutex_unlock(&cci_dev->cci_master_info[master].mutex); CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc); goto rel_mutex; goto rel_master; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * 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 Loading @@ -1149,17 +1193,17 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; goto rel_mutex_q; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; goto rel_mutex_q; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; goto rel_mutex_q; } CAM_DBG(CAM_CCI, "master %d, queue %d", master, queue); Loading @@ -1172,21 +1216,21 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); Loading @@ -1198,21 +1242,21 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR Loading Loading @@ -1240,7 +1284,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, "wait_for_completion_timeout rc = %d FIFO buf_lvl: 0x%x", rc, val); cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } else { rc = 0; } Loading @@ -1253,7 +1297,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, read_words, exp_words); memset(read_cfg->data, 0, read_cfg->num_byte); rc = -EINVAL; goto rel_mutex; goto rel_mutex_q; } index = 0; CAM_DBG(CAM_CCI, "index %d num_type %d", index, read_cfg->num_byte); Loading @@ -1277,8 +1321,15 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, } read_words--; } rel_mutex: rel_mutex_q: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); rel_master: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading @@ -1302,12 +1353,36 @@ static int32_t cam_cci_i2c_write(struct v4l2_subdev *sd, c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, c_ctrl->cci_info->id_map); mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* 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; mutex_unlock(&cci_dev->cci_master_info[master].mutex); goto ERROR; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); /* * 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 Loading @@ -1319,18 +1394,25 @@ static int32_t cam_cci_i2c_write(struct v4l2_subdev *sd, if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); return rc; goto ERROR; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); return rc; goto ERROR; } 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; goto ERROR; } ERROR: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/timer.h> #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/semaphore.h> #include <media/cam_sensor.h> #include <media/v4l2-event.h> #include <media/v4l2-ioctl.h> Loading Loading @@ -137,6 +138,10 @@ struct cam_cci_master_info { struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; spinlock_t freq_cnt; struct semaphore master_sem; bool is_first_req; uint16_t freq_ref_cnt; }; struct cam_cci_clk_params_t { Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -189,7 +189,10 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) for (i = 0; i < NUM_MASTERS; i++) { new_cci_dev->cci_master_info[i].status = 0; new_cci_dev->cci_master_info[i].is_first_req = true; mutex_init(&new_cci_dev->cci_master_info[i].mutex); sema_init(&new_cci_dev->cci_master_info[i].master_sem, 1); spin_lock_init(&new_cci_dev->cci_master_info[i].freq_cnt); init_completion( &new_cci_dev->cci_master_info[i].reset_complete); init_completion( Loading Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +123 −41 Original line number Diff line number Diff line Loading @@ -885,20 +885,39 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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 */ mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* 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; mutex_unlock(&cci_dev->cci_master_info[master].mutex); goto rel_master; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * 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 Loading @@ -909,24 +928,24 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; goto rel_mutex_q; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; goto rel_mutex_q; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; goto rel_mutex_q; } 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; goto rel_mutex_q; } CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d", Loading @@ -938,14 +957,14 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); Loading @@ -957,21 +976,21 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR Loading Loading @@ -1002,7 +1021,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, cam_cci_dump_registers(cci_dev, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } read_words = cam_io_r_mb(base + Loading Loading @@ -1083,7 +1102,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } break; } Loading @@ -1092,8 +1111,15 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, CAM_DBG(CAM_CCI, "Burst read successful words_read %d", total_read_words); rel_mutex: rel_mutex_q: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); rel_master: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading Loading @@ -1125,20 +1151,38 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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 */ mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* Set the I2C Frequency */ rc = cam_cci_set_clk_param(cci_dev, c_ctrl); if (rc < 0) { mutex_unlock(&cci_dev->cci_master_info[master].mutex); CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc); goto rel_mutex; goto rel_master; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * 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 Loading @@ -1149,17 +1193,17 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; goto rel_mutex_q; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; goto rel_mutex_q; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; goto rel_mutex_q; } CAM_DBG(CAM_CCI, "master %d, queue %d", master, queue); Loading @@ -1172,21 +1216,21 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); Loading @@ -1198,21 +1242,21 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } 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; goto rel_mutex_q; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR Loading Loading @@ -1240,7 +1284,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, "wait_for_completion_timeout rc = %d FIFO buf_lvl: 0x%x", rc, val); cam_cci_flush_queue(cci_dev, master); goto rel_mutex; goto rel_mutex_q; } else { rc = 0; } Loading @@ -1253,7 +1297,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, read_words, exp_words); memset(read_cfg->data, 0, read_cfg->num_byte); rc = -EINVAL; goto rel_mutex; goto rel_mutex_q; } index = 0; CAM_DBG(CAM_CCI, "index %d num_type %d", index, read_cfg->num_byte); Loading @@ -1277,8 +1321,15 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, } read_words--; } rel_mutex: rel_mutex_q: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); rel_master: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading @@ -1302,12 +1353,36 @@ static int32_t cam_cci_i2c_write(struct v4l2_subdev *sd, c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, c_ctrl->cci_info->id_map); mutex_lock(&cci_dev->cci_master_info[master].mutex); if (cci_dev->cci_master_info[master].is_first_req) { cci_dev->cci_master_info[master].is_first_req = false; CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else if (c_ctrl->cci_info->i2c_freq_mode != cci_dev->i2c_freq_mode[master]) { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); down(&cci_dev->cci_master_info[master].master_sem); } else { CAM_DBG(CAM_CCI, "Master: %d, curr_freq: %d, req_freq: %d", master, cci_dev->i2c_freq_mode[master], c_ctrl->cci_info->i2c_freq_mode); spin_lock(&cci_dev->cci_master_info[master].freq_cnt); cci_dev->cci_master_info[master].freq_ref_cnt++; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); } /* 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; mutex_unlock(&cci_dev->cci_master_info[master].mutex); goto ERROR; } mutex_unlock(&cci_dev->cci_master_info[master].mutex); /* * 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 Loading @@ -1319,18 +1394,25 @@ static int32_t cam_cci_i2c_write(struct v4l2_subdev *sd, if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); return rc; goto ERROR; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); return rc; goto ERROR; } 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; goto ERROR; } ERROR: spin_lock(&cci_dev->cci_master_info[master].freq_cnt); if (cci_dev->cci_master_info[master].freq_ref_cnt == 0) up(&cci_dev->cci_master_info[master].master_sem); else cci_dev->cci_master_info[master].freq_ref_cnt--; spin_unlock(&cci_dev->cci_master_info[master].freq_cnt); return rc; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/timer.h> #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/semaphore.h> #include <media/cam_sensor.h> #include <media/v4l2-event.h> #include <media/v4l2-ioctl.h> Loading Loading @@ -137,6 +138,10 @@ struct cam_cci_master_info { struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; spinlock_t lock_q[NUM_QUEUES]; spinlock_t freq_cnt; struct semaphore master_sem; bool is_first_req; uint16_t freq_ref_cnt; }; struct cam_cci_clk_params_t { Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -189,7 +189,10 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) for (i = 0; i < NUM_MASTERS; i++) { new_cci_dev->cci_master_info[i].status = 0; new_cci_dev->cci_master_info[i].is_first_req = true; mutex_init(&new_cci_dev->cci_master_info[i].mutex); sema_init(&new_cci_dev->cci_master_info[i].master_sem, 1); spin_lock_init(&new_cci_dev->cci_master_info[i].freq_cnt); init_completion( &new_cci_dev->cci_master_info[i].reset_complete); init_completion( Loading