From fdd05557080413e7f10acaf24825bea40cd1ce45 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 24 Nov 2021 17:41:50 +0800 Subject: [PATCH] ois: enable active ois [detail] enable active ois for milan5G dw9781c Change-Id: I48087bbcc20ad23d91469e40bbe3054714a12f08 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2126132 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Ji Zhao Reviewed-by: Zhuoran Xu Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 214 +++++++++++++++++- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 1 + .../cam_sensor_utils/cam_sensor_cmn_header.h | 3 +- 3 files changed, 216 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c index 165376ff152f..d2663140d005 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -112,6 +112,7 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl) &o_ctrl->soc_info; struct cam_ois_soc_private *soc_private; struct cam_sensor_power_ctrl_t *power_info; + o_ctrl->prevTimeStamp = 0; soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; @@ -571,6 +572,28 @@ release_firmware: return rc; } +static int cam_ois_write_dw(struct cam_ois_ctrl_t *o_ctrl) +{ + struct cam_sensor_i2c_reg_setting i2c_reg_setting = {NULL,1,CAMERA_SENSOR_I2C_TYPE_WORD,CAMERA_SENSOR_I2C_TYPE_WORD,0}; + struct cam_sensor_i2c_reg_array i2c_write_settings = {0x70DA,0x0000,0,0}; + int32_t rc = 0; + + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "Invalid Args"); + return -EINVAL; + } + + i2c_reg_setting.reg_setting = &(i2c_write_settings); + + rc = camera_io_dev_write(&(o_ctrl->io_master_info), + &(i2c_reg_setting)); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "Failed in Applying i2c wrt settings"); + } + return rc; +} + /** * cam_ois_pkt_parse - Parse csl packet * @o_ctrl: ctrl structure @@ -1033,7 +1056,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } break; } - case CAM_OIS_PACKET_OPCODE_ACTIVE_EIS: { + case CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_ROHM: { struct cam_buf_io_cfg *io_cfg; struct cam_buf_io_cfg *timestamp_io_cfg; struct i2c_settings_array i2c_read_settings; @@ -1128,6 +1151,195 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } break; } + case CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON: { + struct cam_buf_io_cfg *io_cfg; + struct cam_buf_io_cfg *timestamp_io_cfg; + struct i2c_settings_array i2c_read_settings; + uintptr_t buf_addr = 0x0; + size_t buf_size = 0; + uint64_t timestamp, qtime_ns; + uint8_t *timestampBuf; + uint32_t timestampBufLen; + struct i2c_settings_list *i2c_list; + uint8_t *read_buff = NULL; + uint32_t buff_length = 0; + uint32_t read_length = 0; + uint32_t i, size; + uint8_t packetCounter = 0; + uint32_t k = 0, remain_len = 0, read_len = 0; + + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + rc = -EINVAL; + CAM_WARN(CAM_OIS, + "Not in right state to read OIS: %d", + o_ctrl->cam_ois_state); + return rc; + } + CAM_DBG(CAM_OIS, "number of I/O configs: %d:", + csl_packet->num_io_configs); + if (csl_packet->num_io_configs < 2) { + CAM_ERR(CAM_OIS, "Not enough I/O Configs"); + rc = -EINVAL; + return rc; + } + + INIT_LIST_HEAD(&(i2c_read_settings.list_head)); + + io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) + &csl_packet->payload + + csl_packet->io_configs_offset); + + if (io_cfg == NULL) { + CAM_ERR(CAM_OIS, "I/O config is invalid(NULL)"); + rc = -EINVAL; + return rc; + } + + timestamp_io_cfg = &io_cfg[1]; + + if (timestamp_io_cfg == NULL) { + CAM_ERR(CAM_OIS, "timestamp I/O config is invalid(NULL)"); + rc = -EINVAL; + return rc; + } + + offset = (uint32_t *)&csl_packet->payload; + offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t)); + cmd_desc = (struct cam_cmd_buf_desc *)(offset); + if (cmd_desc == NULL) { + CAM_ERR(CAM_OIS, "cmd desc is invalid(NULL)"); + rc = -EINVAL; + return rc; + } + + i2c_read_settings.is_settings_valid = 1; + i2c_read_settings.request_id = 0; + rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info, + &i2c_read_settings, + cmd_desc, 1, io_cfg); + if (rc < 0) { + CAM_ERR(CAM_OIS, "OIS read pkt parsing failed: %d", rc); + return rc; + } + + list_for_each_entry(i2c_list, + &(i2c_read_settings.list_head), list) { + if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) { + rc = camera_io_dev_write(&(o_ctrl->io_master_info), + &(i2c_list->i2c_settings)); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "Failed in Applying i2c wrt settings"); + delete_request(&i2c_read_settings); + return rc; + } + } else if (i2c_list->op_code == CAM_SENSOR_I2C_READ_SEQ) { + #define READ_BTYE 0xE + read_buff = i2c_list->i2c_settings.read_buff; + buff_length = i2c_list->i2c_settings.read_buff_len; + read_length = i2c_list->i2c_settings.size; + remain_len = read_length; + read_len = READ_BTYE; + packetCounter = 0; + + if (read_length > buff_length) { + CAM_ERR(CAM_SENSOR, + "Invalid buffer size, readLen: %d, bufLen: %d", + read_length, buff_length); + return -EINVAL; + } + do { + // SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time. + // Each loop read max supported bytes(0xE), to save read time. + for (k = 0; k < read_length/READ_BTYE + 1; k++) { + rc = camera_io_dev_read_seq( + &o_ctrl->io_master_info, + i2c_list->i2c_settings.reg_setting[0].reg_addr + k*READ_BTYE/2, + read_buff + k*READ_BTYE, + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type, + read_len); + remain_len -= read_len; + read_len = remain_len > READ_BTYE ? READ_BTYE:remain_len; + } + + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "failed: seq read I2C settings: %d", + rc); + delete_request(&i2c_read_settings); + return rc; + } + if (!rc){ + if (read_buff[1] == 0){ + CAM_ERR(CAM_OIS,"Header is zero, break the read"); + rc = -EINVAL; + break; + } else if ((read_buff[1] != 0) && (packetCounter == 0)) { + + //TODO: change to use interrupt + timestamp = o_ctrl->prevTimeStamp; + + rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "failed to get qtimer rc:%d"); + return rc; + } + + o_ctrl->prevTimeStamp = qtime_ns; + + rc = cam_mem_get_cpu_buf(timestamp_io_cfg->mem_handle[0], + &buf_addr, &buf_size); + timestampBuf = (uint8_t *)buf_addr + timestamp_io_cfg->offsets[0]; + timestampBufLen = buf_size - timestamp_io_cfg->offsets[0]; + + if(timestampBufLen < sizeof(uint64_t)) { + CAM_ERR(CAM_OIS, "Buffer not large enough for timestamp"); + return -EINVAL; + } + memcpy((void *)timestampBuf, (void *)×tamp, sizeof(uint64_t)); + + packetCounter = (read_buff[1] + 9)/10; + } + } + rc = cam_ois_write_dw(o_ctrl); + usleep_range(1000, 1010); + if (!rc){ + read_buff += i2c_list->i2c_settings.size; + packetCounter--; + } else { + CAM_ERR(CAM_OIS,"Write failed rc: %d", rc); + break; + } + } while(packetCounter); + } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) { + size = i2c_list->i2c_settings.size; + for (i = 0; i < size; i++) { + rc = camera_io_dev_poll( + &(o_ctrl->io_master_info), + i2c_list->i2c_settings.reg_setting[i].reg_addr, + i2c_list->i2c_settings.reg_setting[i].reg_data, + 0xFFFE, + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type, + i2c_list->i2c_settings.reg_setting[i].delay); + } + if ((rc == 1) || (rc < 0)) { + CAM_ERR(CAM_OIS, + "i2c poll fails rc: %d",rc); + rc = -EINVAL; + break; + } + } + } + rc = delete_request(&i2c_read_settings); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "Failed in deleting the read settings"); + return rc; + } + break; + } default: CAM_ERR(CAM_OIS, "Invalid Opcode: %d", (csl_packet->header.op_code & 0xFFFFFF)); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h index af7473d413e9..3097f36c2763 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -142,6 +142,7 @@ struct cam_ois_ctrl_t { uint8_t ois_fw_inc_addr; uint8_t ois_fw_addr_type; uint8_t ois_fw_data_type; + uint64_t prevTimeStamp; struct cam_ois_opcode opcode; }; diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h index 707d913a3ae1..45b3dc27e441 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h @@ -175,7 +175,8 @@ enum cam_ois_packet_opcodes { CAM_OIS_PACKET_OPCODE_OIS_CONTROL, CAM_OIS_PACKET_OPCODE_READ, CAM_OIS_PACKET_OPCODE_WRITE_TIME, - CAM_OIS_PACKET_OPCODE_ACTIVE_EIS + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_ROHM, + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON }; enum msm_bus_perf_setting {