|
@@ -239,16 +239,34 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set)
|
|
|
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
|
|
|
size = i2c_list->i2c_settings.size;
|
|
|
/* qtimer is 8 bytes so validate here*/
|
|
|
- if (size < 8) {
|
|
|
+ if (size * (uint32_t)(i2c_list->i2c_settings.data_type) != 8) {
|
|
|
CAM_ERR(CAM_OIS, "Invalid write time settings");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- for (i = 0; i < size; i++) {
|
|
|
- CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
|
|
- i, (qtime_ns & 0xFF));
|
|
|
- i2c_list->i2c_settings.reg_setting[i].reg_data =
|
|
|
- (qtime_ns & 0xFF);
|
|
|
- qtime_ns >>= 8;
|
|
|
+ switch (i2c_list->i2c_settings.data_type) {
|
|
|
+ case CAMERA_SENSOR_I2C_TYPE_BYTE:
|
|
|
+ for (i = 0; i < size; i++) {
|
|
|
+ CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
|
|
+ i, (qtime_ns & 0xFF));
|
|
|
+ i2c_list->i2c_settings.reg_setting[i].reg_data =
|
|
|
+ (qtime_ns & 0xFF);
|
|
|
+ qtime_ns >>= 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ case CAMERA_SENSOR_I2C_TYPE_WORD:
|
|
|
+ for (i = 0; i < size; i++) {
|
|
|
+ CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
|
|
+ i, (qtime_ns & 0xFFFF));
|
|
|
+ i2c_list->i2c_settings.reg_setting[i].reg_data =
|
|
|
+ (qtime_ns & 0xFFFF);
|
|
|
+ qtime_ns >>= 16;
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ CAM_ERR(CAM_OIS, "Unsupported reg data type!");
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -356,6 +374,244 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int cam_ois_parse_fw_setting(uint8_t *cmd_buf, uint32_t size,
|
|
|
+ struct i2c_settings_array *reg_settings)
|
|
|
+{
|
|
|
+ int32_t rc = 0;
|
|
|
+ uint32_t byte_cnt = 0;
|
|
|
+ struct common_header *cmm_hdr;
|
|
|
+ uint16_t op_code;
|
|
|
+ uint32_t j = 0;
|
|
|
+ struct list_head *list = NULL;
|
|
|
+
|
|
|
+ while (byte_cnt < size) {
|
|
|
+ if ((size - byte_cnt) < sizeof(struct common_header)) {
|
|
|
+ CAM_ERR(CAM_SENSOR, "Not enough buffer");
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ cmm_hdr = (struct common_header *)cmd_buf;
|
|
|
+ op_code = cmm_hdr->fifth_byte;
|
|
|
+ CAM_DBG(CAM_SENSOR, "Command Type:%d, Op code:%d",
|
|
|
+ cmm_hdr->cmd_type, op_code);
|
|
|
+
|
|
|
+ switch (cmm_hdr->cmd_type) {
|
|
|
+ case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: {
|
|
|
+ uint32_t cmd_length_in_bytes = 0;
|
|
|
+ struct cam_cmd_i2c_random_wr
|
|
|
+ *cam_cmd_i2c_random_wr =
|
|
|
+ (struct cam_cmd_i2c_random_wr *)cmd_buf;
|
|
|
+
|
|
|
+ if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_random_wr)) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Not enough buffer provided,size %d,byte_cnt %d",
|
|
|
+ size, byte_cnt);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_sensor_handle_random_write(
|
|
|
+ cam_cmd_i2c_random_wr,
|
|
|
+ reg_settings,
|
|
|
+ &cmd_length_in_bytes, &j, &list);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Failed in random write %d", rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte_cnt += sizeof(struct cam_cmd_i2c_random_wr);
|
|
|
+ cmd_buf += sizeof(struct cam_cmd_i2c_random_wr);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_WR: {
|
|
|
+ uint32_t cmd_length_in_bytes = 0;
|
|
|
+ struct cam_cmd_i2c_continuous_wr
|
|
|
+ *cam_cmd_i2c_continuous_wr =
|
|
|
+ (struct cam_cmd_i2c_continuous_wr *)cmd_buf;
|
|
|
+
|
|
|
+ if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_continuous_wr)) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Not enough buffer provided,size %d,byte_cnt %d",
|
|
|
+ size, byte_cnt);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_sensor_handle_continuous_write(
|
|
|
+ cam_cmd_i2c_continuous_wr,
|
|
|
+ reg_settings,
|
|
|
+ &cmd_length_in_bytes, &j, &list);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Failed in continuous write %d", rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte_cnt += sizeof(struct cam_cmd_i2c_continuous_wr);
|
|
|
+ cmd_buf += sizeof(struct cam_cmd_i2c_continuous_wr);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CAMERA_SENSOR_CMD_TYPE_WAIT: {
|
|
|
+ if (op_code == CAMERA_SENSOR_WAIT_OP_HW_UCND ||
|
|
|
+ op_code == CAMERA_SENSOR_WAIT_OP_SW_UCND) {
|
|
|
+ if ((size - byte_cnt) <
|
|
|
+ sizeof(struct cam_cmd_unconditional_wait)) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Not enough buffer provided,size %d,byte_cnt %d",
|
|
|
+ size, byte_cnt);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_sensor_handle_delay(
|
|
|
+ (uint32_t **)(&cmd_buf), op_code,
|
|
|
+ reg_settings, j, &byte_cnt,
|
|
|
+ list);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "delay hdl failed: %d",
|
|
|
+ rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: {
|
|
|
+ uint16_t cmd_length_in_bytes = 0;
|
|
|
+ struct cam_cmd_i2c_random_rd *i2c_random_rd =
|
|
|
+ (struct cam_cmd_i2c_random_rd *)cmd_buf;
|
|
|
+
|
|
|
+ if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_random_rd)) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Not enough buffer provided,size %d,byte_cnt %d",
|
|
|
+ size, byte_cnt);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_sensor_handle_random_read(
|
|
|
+ i2c_random_rd,
|
|
|
+ reg_settings,
|
|
|
+ &cmd_length_in_bytes, &j, &list,
|
|
|
+ NULL);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Failed in random read %d", rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte_cnt += sizeof(struct cam_cmd_i2c_random_rd);
|
|
|
+ cmd_buf += sizeof(struct cam_cmd_i2c_random_rd);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: {
|
|
|
+ uint16_t cmd_length_in_bytes = 0;
|
|
|
+ struct cam_cmd_i2c_continuous_rd
|
|
|
+ *i2c_continuous_rd =
|
|
|
+ (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
|
|
|
+
|
|
|
+ if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_continuous_rd)) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Not enough buffer provided,size %d,byte_cnt %d",
|
|
|
+ size, byte_cnt);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_sensor_handle_continuous_read(
|
|
|
+ i2c_continuous_rd,
|
|
|
+ reg_settings,
|
|
|
+ &cmd_length_in_bytes, &j, &list,
|
|
|
+ NULL);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Failed in continuous read %d", rc);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte_cnt += sizeof(struct cam_cmd_i2c_continuous_rd);
|
|
|
+ cmd_buf += sizeof(struct cam_cmd_i2c_continuous_rd);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
|
|
|
+ cmm_hdr->cmd_type);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+end:
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+static int cam_ois_fw_info_pkt_parser(struct cam_ois_ctrl_t *o_ctrl,
|
|
|
+ uint32_t *cmd_buf, size_t len)
|
|
|
+{
|
|
|
+ int32_t rc = 0;
|
|
|
+ struct cam_cmd_ois_fw_info *ois_fw_info;
|
|
|
+ uint8_t *pSettingData = NULL;
|
|
|
+ uint32_t size;
|
|
|
+ struct i2c_settings_array *reg_settings = NULL;
|
|
|
+ uint8_t count = 0;
|
|
|
+ uint32_t idx;
|
|
|
+
|
|
|
+ if (!o_ctrl || !cmd_buf || len < sizeof(struct cam_cmd_ois_fw_info)) {
|
|
|
+ CAM_ERR(CAM_OIS, "Invalid Args,o_ctrl %p,cmd_buf %p,len %d",
|
|
|
+ o_ctrl, cmd_buf, len);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ois_fw_info = (struct cam_cmd_ois_fw_info *)cmd_buf;
|
|
|
+ CAM_DBG(CAM_SENSOR, "fw_count %d, endianness %d",
|
|
|
+ ois_fw_info->fw_count, ois_fw_info->endianness);
|
|
|
+
|
|
|
+ if (ois_fw_info->fw_count <= MAX_OIS_FW_COUNT) {
|
|
|
+ memcpy(&o_ctrl->fw_info, ois_fw_info, sizeof(struct cam_cmd_ois_fw_info));
|
|
|
+ pSettingData = (uint8_t *)cmd_buf + sizeof(struct cam_cmd_ois_fw_info);
|
|
|
+
|
|
|
+ for (count = 0; count < ois_fw_info->fw_count*2; count++) {
|
|
|
+ idx = count / 2;
|
|
|
+ /* init settings */
|
|
|
+ if ((count & 0x1) == 0) {
|
|
|
+ size = ois_fw_info->fw_param[idx].fw_init_size;
|
|
|
+ reg_settings = &o_ctrl->i2c_fw_init_data[idx];
|
|
|
+ CAM_DBG(CAM_SENSOR, "init size %d", size);
|
|
|
+ /* finalize settings */
|
|
|
+ } else if ((count & 0x1) == 1) {
|
|
|
+ size = ois_fw_info->fw_param[idx].fw_finalize_size;
|
|
|
+ reg_settings = &o_ctrl->i2c_fw_finalize_data[idx];
|
|
|
+ CAM_DBG(CAM_SENSOR, "finalize size %d", size);
|
|
|
+ } else {
|
|
|
+ size = 0;
|
|
|
+ CAM_DBG(CAM_SENSOR, "Unsupported case!");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size != 0) {
|
|
|
+ reg_settings->is_settings_valid = 1;
|
|
|
+ rc = cam_ois_parse_fw_setting(pSettingData, size, reg_settings);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS, "Failed to parse fw setting!");
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ pSettingData += size;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ CAM_ERR(CAM_OIS, "Exceed max fw count!");
|
|
|
+ }
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl)
|
|
|
{
|
|
|
uint16_t total_bytes = 0;
|
|
@@ -480,6 +736,207 @@ release_firmware:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static inline uint32_t swap_high_byte_and_low_byte(uint8_t *src,
|
|
|
+ uint8_t data_type)
|
|
|
+{
|
|
|
+ uint32_t ret_value = 0x00;
|
|
|
+ uint8_t cycle = 0;
|
|
|
+
|
|
|
+ for (cycle = 0; cycle < data_type; cycle++)
|
|
|
+ ret_value = ((ret_value<<8) | ((*(src+cycle))&0xff));
|
|
|
+
|
|
|
+ return ret_value;
|
|
|
+}
|
|
|
+
|
|
|
+static int write_ois_fw(uint8_t *fw_data, enum cam_endianness_type endianness,
|
|
|
+ struct cam_cmd_ois_fw_param *fw_param, struct camera_io_master io_master_info,
|
|
|
+ uint8_t i2c_operation)
|
|
|
+{
|
|
|
+ int32_t rc = 0;
|
|
|
+ struct cam_sensor_i2c_reg_setting setting;
|
|
|
+ uint8_t *ptr = fw_data;
|
|
|
+ int32_t cnt = 0, wcnt = 0;
|
|
|
+ void *vaddr = NULL;
|
|
|
+ uint16_t data_type = fw_param->fw_data_type;
|
|
|
+ uint16_t len_per_write = fw_param->fw_len_per_write /
|
|
|
+ fw_param->fw_data_type;
|
|
|
+
|
|
|
+ vaddr = vmalloc((sizeof(struct cam_sensor_i2c_reg_array) * len_per_write));
|
|
|
+ if (!vaddr) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Failed in allocating i2c_array: size: %u",
|
|
|
+ (sizeof(struct cam_sensor_i2c_reg_array) * len_per_write));
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ setting.reg_setting = (struct cam_sensor_i2c_reg_array *) (vaddr);
|
|
|
+ setting.addr_type = fw_param->fw_addr_type;
|
|
|
+ setting.data_type = fw_param->fw_data_type;
|
|
|
+ setting.size = len_per_write;
|
|
|
+ setting.delay = fw_param->fw_delayUs;
|
|
|
+
|
|
|
+ for (wcnt = 0; wcnt < (fw_param->fw_size/data_type); wcnt += len_per_write) {
|
|
|
+ for (cnt = 0; cnt < len_per_write; cnt++, ptr += data_type) {
|
|
|
+ setting.reg_setting[cnt].reg_addr =
|
|
|
+ fw_param->fw_reg_addr + wcnt + cnt;
|
|
|
+ /* Big */
|
|
|
+ if (endianness == CAM_ENDIANNESS_BIG) {
|
|
|
+ setting.reg_setting[cnt].reg_data =
|
|
|
+ swap_high_byte_and_low_byte(ptr, data_type);
|
|
|
+ /* Little */
|
|
|
+ } else if (endianness == CAM_ENDIANNESS_LITTLE) {
|
|
|
+ switch (data_type) {
|
|
|
+ case CAMERA_SENSOR_I2C_TYPE_BYTE:
|
|
|
+ setting.reg_setting[cnt].reg_data = *((uint8_t *)ptr);
|
|
|
+ break;
|
|
|
+ case CAMERA_SENSOR_I2C_TYPE_WORD:
|
|
|
+ setting.reg_setting[cnt].reg_data = *((uint16_t *)ptr);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Unsupported data type");
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto End;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ setting.reg_setting[cnt].delay = fw_param->fw_delayUs;
|
|
|
+ setting.reg_setting[cnt].data_mask = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i2c_operation == CAM_SENSOR_I2C_WRITE_RANDOM) {
|
|
|
+ rc = camera_io_dev_write(&(io_master_info),
|
|
|
+ &setting);
|
|
|
+ } else if (i2c_operation == CAM_SENSOR_I2C_WRITE_BURST ||
|
|
|
+ i2c_operation == CAM_SENSOR_I2C_WRITE_SEQ) {
|
|
|
+ rc = camera_io_dev_write_continuous(&io_master_info,
|
|
|
+ &setting, i2c_operation);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Failed in Applying i2c wrt settings");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+End:
|
|
|
+ vfree(vaddr);
|
|
|
+ vaddr = NULL;
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+static int cam_ois_fw_download_v2(struct cam_ois_ctrl_t *o_ctrl)
|
|
|
+{
|
|
|
+ int32_t rc = 0;
|
|
|
+ struct cam_cmd_ois_fw_param *fw_param = NULL;
|
|
|
+ uint32_t fw_size;
|
|
|
+ uint16_t len_per_write = 0;
|
|
|
+ uint8_t *ptr = NULL;
|
|
|
+ const struct firmware *fw = NULL;
|
|
|
+ struct device *dev = &(o_ctrl->pdev->dev);
|
|
|
+ uint8_t count = 0;
|
|
|
+ uint8_t cont_wr_flag = 0;
|
|
|
+
|
|
|
+ if (!o_ctrl) {
|
|
|
+ CAM_ERR(CAM_OIS, "Invalid Args");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (count = 0; count < o_ctrl->fw_info.fw_count; count++) {
|
|
|
+ fw_param = &o_ctrl->fw_info.fw_param[count];
|
|
|
+ fw_size = fw_param->fw_size;
|
|
|
+ len_per_write = fw_param->fw_len_per_write / fw_param->fw_data_type;
|
|
|
+
|
|
|
+ CAM_DBG(CAM_OIS, "count: %d, fw_size: %d, data_type: %d, len_per_write: %d",
|
|
|
+ count, fw_size, fw_param->fw_data_type, len_per_write);
|
|
|
+
|
|
|
+ /* Load FW */
|
|
|
+ rc = request_firmware(&fw, fw_param->fw_name, dev);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS, "Failed to locate %s", fw_param->fw_name);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (0 == rc && NULL != fw &&
|
|
|
+ (fw_size <= fw->size - fw_param->fw_start_pos)) {
|
|
|
+ /* fw init */
|
|
|
+ CAM_DBG(CAM_OIS, "fw init");
|
|
|
+ if (o_ctrl->i2c_fw_init_data[count].is_settings_valid == 1) {
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fw_init_data[count]);
|
|
|
+ if ((rc == -EAGAIN) &&
|
|
|
+ (o_ctrl->io_master_info.master_type == CCI_MASTER)) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "CCI HW is resetting: Reapplying FW init settings");
|
|
|
+ usleep_range(1000, 1010);
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fw_init_data[count]);
|
|
|
+ }
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Cannot apply FW init settings %d",
|
|
|
+ rc);
|
|
|
+ goto release_firmware;
|
|
|
+ } else {
|
|
|
+ CAM_DBG(CAM_OIS, "OIS FW init settings success");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* send fw */
|
|
|
+ CAM_DBG(CAM_OIS, "send fw, operation %d", fw_param->fw_operation);
|
|
|
+
|
|
|
+ ptr = (uint8_t *)(fw->data + fw_param->fw_start_pos);
|
|
|
+ if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_RNDM_WR)
|
|
|
+ cont_wr_flag = CAM_SENSOR_I2C_WRITE_RANDOM;
|
|
|
+ else if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
|
|
|
+ cont_wr_flag = CAM_SENSOR_I2C_WRITE_BURST;
|
|
|
+ else if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN)
|
|
|
+ cont_wr_flag = CAM_SENSOR_I2C_WRITE_SEQ;
|
|
|
+
|
|
|
+ write_ois_fw(ptr, o_ctrl->fw_info.endianness, fw_param,
|
|
|
+ o_ctrl->io_master_info, cont_wr_flag);
|
|
|
+
|
|
|
+ /* fw finalize */
|
|
|
+ CAM_DBG(CAM_OIS, "fw finalize");
|
|
|
+ if (o_ctrl->i2c_fw_finalize_data[count].is_settings_valid == 1) {
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fw_finalize_data[count]);
|
|
|
+ if ((rc == -EAGAIN) &&
|
|
|
+ (o_ctrl->io_master_info.master_type == CCI_MASTER)) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "CCI HW is resetting: Reapplying FW finalize settings");
|
|
|
+ usleep_range(1000, 1010);
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fw_finalize_data[count]);
|
|
|
+ }
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Cannot apply FW finalize settings %d",
|
|
|
+ rc);
|
|
|
+ goto release_firmware;
|
|
|
+ } else {
|
|
|
+ CAM_DBG(CAM_OIS, "OIS FW finalize settings success");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fw != NULL) {
|
|
|
+ release_firmware(fw);
|
|
|
+ fw = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+release_firmware:
|
|
|
+ if (fw != NULL) {
|
|
|
+ release_firmware(fw);
|
|
|
+ fw = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* cam_ois_pkt_parse - Parse csl packet
|
|
|
* @o_ctrl: ctrl structure
|
|
@@ -543,13 +1000,13 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
|
|
|
switch (csl_packet->header.op_code & 0xFFFFFF) {
|
|
|
case CAM_OIS_PACKET_OPCODE_INIT:
|
|
|
+ CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_INIT,num_cmd_buf %d",
|
|
|
+ csl_packet->num_cmd_buf);
|
|
|
+
|
|
|
offset = (uint32_t *)&csl_packet->payload;
|
|
|
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
|
|
|
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
|
|
|
|
|
|
- CAM_DBG(CAM_OIS, "num_cmd_buf %d",
|
|
|
- csl_packet->num_cmd_buf);
|
|
|
-
|
|
|
/* Loop through multiple command buffers */
|
|
|
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
|
|
|
total_cmd_buf_in_bytes = cmd_desc[i].length;
|
|
@@ -580,6 +1037,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
|
|
|
cmm_hdr = (struct common_header *)cmd_buf;
|
|
|
|
|
|
+ CAM_DBG(CAM_OIS,
|
|
|
+ "cmm_hdr->cmd_type: %d", cmm_hdr->cmd_type);
|
|
|
switch (cmm_hdr->cmd_type) {
|
|
|
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
|
|
|
rc = cam_ois_slaveInfo_pkt_parser(
|
|
@@ -604,6 +1063,18 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
return rc;
|
|
|
}
|
|
|
break;
|
|
|
+ case CAMERA_SENSOR_OIS_CMD_TYPE_FW_INFO:
|
|
|
+ CAM_DBG(CAM_OIS,
|
|
|
+ "Received fwInfo buffer,total_cmd_buf_in_bytes: %d",
|
|
|
+ total_cmd_buf_in_bytes);
|
|
|
+ rc = cam_ois_fw_info_pkt_parser(
|
|
|
+ o_ctrl, cmd_buf, total_cmd_buf_in_bytes);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Failed: parse fw info settings");
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ break;
|
|
|
default:
|
|
|
if (o_ctrl->i2c_init_data.is_settings_valid == 0) {
|
|
|
CAM_DBG(CAM_OIS,
|
|
@@ -649,9 +1120,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
i2c_reg_settings,
|
|
|
&cmd_desc[i], 1, NULL);
|
|
|
if (rc < 0) {
|
|
|
- CAM_ERR(CAM_OIS,
|
|
|
+ CAM_DBG(CAM_OIS,
|
|
|
"fw init parsing failed: %d", rc);
|
|
|
- return rc;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
@@ -667,32 +1137,43 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
o_ctrl->cam_ois_state = CAM_OIS_CONFIG;
|
|
|
}
|
|
|
|
|
|
- if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1) {
|
|
|
- rc = cam_ois_apply_settings(o_ctrl,
|
|
|
- &o_ctrl->i2c_fwinit_data);
|
|
|
- if ((rc == -EAGAIN) &&
|
|
|
- (o_ctrl->io_master_info.master_type == CCI_MASTER)) {
|
|
|
- CAM_WARN(CAM_OIS,
|
|
|
- "CCI HW is restting: Reapplying fwinit settings");
|
|
|
- usleep_range(1000, 1010);
|
|
|
- rc = cam_ois_apply_settings(o_ctrl,
|
|
|
- &o_ctrl->i2c_fwinit_data);
|
|
|
- }
|
|
|
- if (rc) {
|
|
|
- CAM_ERR(CAM_OIS,
|
|
|
- "Cannot apply fwinit data %d",
|
|
|
- rc);
|
|
|
- goto pwr_dwn;
|
|
|
- } else {
|
|
|
- CAM_DBG(CAM_OIS, "OIS fwinit settings success");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ CAM_DBG(CAM_OIS, "ois_fw_flag: %d", o_ctrl->ois_fw_flag);
|
|
|
if (o_ctrl->ois_fw_flag) {
|
|
|
- rc = cam_ois_fw_download(o_ctrl);
|
|
|
- if (rc) {
|
|
|
- CAM_ERR(CAM_OIS, "Failed OIS FW Download");
|
|
|
- goto pwr_dwn;
|
|
|
+ CAM_DBG(CAM_OIS, "fw_count: %d", o_ctrl->fw_info.fw_count);
|
|
|
+ if (o_ctrl->fw_info.fw_count != 0) {
|
|
|
+ rc = cam_ois_fw_download_v2(o_ctrl);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS, "Failed OIS FW Download v2");
|
|
|
+ goto pwr_dwn;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1) {
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fwinit_data);
|
|
|
+ if ((rc == -EAGAIN) &&
|
|
|
+ (o_ctrl->io_master_info.master_type ==
|
|
|
+ CCI_MASTER)) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Reapplying fwinit settings");
|
|
|
+ usleep_range(1000, 1010);
|
|
|
+ rc = cam_ois_apply_settings(o_ctrl,
|
|
|
+ &o_ctrl->i2c_fwinit_data);
|
|
|
+ }
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS,
|
|
|
+ "Cannot apply fwinit data %d",
|
|
|
+ rc);
|
|
|
+ goto pwr_dwn;
|
|
|
+ } else {
|
|
|
+ CAM_DBG(CAM_OIS, "OIS fwinit settings success");
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = cam_ois_fw_download(o_ctrl);
|
|
|
+ if (rc) {
|
|
|
+ CAM_ERR(CAM_OIS, "Failed OIS FW Download");
|
|
|
+ goto pwr_dwn;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -705,6 +1186,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
rc = cam_ois_apply_settings(o_ctrl,
|
|
|
&o_ctrl->i2c_init_data);
|
|
|
}
|
|
|
+
|
|
|
if (rc < 0) {
|
|
|
CAM_ERR(CAM_OIS,
|
|
|
"Cannot apply Init settings: rc = %d",
|
|
@@ -740,6 +1222,25 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
rc = 0;
|
|
|
}
|
|
|
|
|
|
+ for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
|
|
|
+ if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_init_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_finalize_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
rc = delete_request(&o_ctrl->i2c_init_data);
|
|
|
if (rc < 0) {
|
|
|
CAM_WARN(CAM_OIS,
|
|
@@ -754,6 +1255,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
}
|
|
|
break;
|
|
|
case CAM_OIS_PACKET_OPCODE_OIS_CONTROL:
|
|
|
+ CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_OIS_CONTROL");
|
|
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
|
|
rc = -EINVAL;
|
|
|
CAM_WARN(CAM_OIS,
|
|
@@ -793,6 +1295,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
struct cam_buf_io_cfg *io_cfg;
|
|
|
struct i2c_settings_array i2c_read_settings;
|
|
|
|
|
|
+ CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_READ");
|
|
|
+
|
|
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
|
|
rc = -EINVAL;
|
|
|
CAM_WARN(CAM_OIS,
|
|
@@ -869,6 +1373,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
break;
|
|
|
}
|
|
|
case CAM_OIS_PACKET_OPCODE_WRITE_TIME: {
|
|
|
+ CAM_DBG(CAM_OIS,
|
|
|
+ "CAM_OIS_PACKET_OPCODE_WRITE_TIME");
|
|
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
|
|
rc = -EINVAL;
|
|
|
CAM_ERR(CAM_OIS,
|
|
@@ -925,7 +1431,7 @@ pwr_dwn:
|
|
|
|
|
|
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
+ int rc = 0, i = 0;
|
|
|
struct cam_ois_soc_private *soc_private =
|
|
|
(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
|
|
|
struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
|
|
@@ -952,6 +1458,25 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
|
|
|
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
|
|
|
delete_request(&o_ctrl->i2c_fwinit_data);
|
|
|
|
|
|
+ for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
|
|
|
+ if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_init_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_finalize_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (o_ctrl->i2c_mode_data.is_settings_valid == 1)
|
|
|
delete_request(&o_ctrl->i2c_mode_data);
|
|
|
|
|
@@ -980,7 +1505,7 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
|
|
|
*/
|
|
|
int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
+ int rc = 0, i = 0;
|
|
|
struct cam_ois_query_cap_t ois_cap = {0};
|
|
|
struct cam_control *cmd = (struct cam_control *)arg;
|
|
|
struct cam_ois_soc_private *soc_private = NULL;
|
|
@@ -1091,6 +1616,25 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|
|
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
|
|
|
delete_request(&o_ctrl->i2c_fwinit_data);
|
|
|
|
|
|
+ for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
|
|
|
+ if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_init_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
|
|
|
+ rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
|
|
|
+ if (rc < 0) {
|
|
|
+ CAM_WARN(CAM_OIS,
|
|
|
+ "Fail deleting i2c_fw_finalize_data: rc: %d", rc);
|
|
|
+ rc = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
break;
|
|
|
case CAM_STOP_DEV:
|
|
|
if (o_ctrl->cam_ois_state != CAM_OIS_START) {
|