From 9fb3bd88bd6e45d381d24676288c621d7f3462b3 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 6 Jan 2022 16:56:28 +0800 Subject: [PATCH] camera: ois: add dw9781c Q-timer active ois add dw9781c Q-timer active ois. for dubai project. Change-Id: Id6c9dd48d928364ca39f0b8e19fb5d34b5081c43 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2163522 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 211 ++++++++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.h | 6 + .../cam_sensor_utils/cam_sensor_cmn_header.h | 3 +- 3 files changed, 219 insertions(+), 1 deletion(-) 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 cb148f775d02..37fb8ddc1b01 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -115,6 +115,8 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->prev_timestamp = 0; o_ctrl->curr_timestamp = 0; o_ctrl->is_first_vsync = 1; + o_ctrl->q_timer_cnt = QTIMER_SAMPLE_TIME*10*2; + o_ctrl->q_timer_timestamp = 0; soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; @@ -574,6 +576,42 @@ release_firmware: return rc; } +static int cam_ois_write_q_timer(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 = {QTIMER_ADDR,0x0000,0,0}; + int32_t rc = 0; + uint32_t data = 0; + uint64_t qtime_ns = 0; + + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "Invalid Args"); + return -EINVAL; + } + + if (o_ctrl->q_timer_cnt > 60000) + o_ctrl->q_timer_cnt = QTIMER_SAMPLE_TIME*10*2; + + data = ++o_ctrl->q_timer_cnt; + + i2c_write_settings.reg_data = data; + 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 Q-timer settings"); + } else { + rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); + if (rc < 0) + CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d"); + else + o_ctrl->q_timer_timestamp = qtime_ns; + } + + CAM_DBG(CAM_OIS,"Write Q-timer %d, timestamp %lld", data, qtime_ns); + return rc; +} + /** * cam_ois_pkt_parse - Parse csl packet * @o_ctrl: ctrl structure @@ -1282,6 +1320,179 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } break; } + case CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON_QTIMER: { + 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; + uint8_t *timestampBuf; + uint32_t timestampBufLen; + struct i2c_settings_list *i2c_list; + uint8_t *read_buff = NULL; + uint32_t buff_length = 0, read_length = 0; + uint16_t sample_cnt = 0, flag = 0, latest_data_ts = 0; + uint64_t delta_timestamp_ns = 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) { + read_buff = i2c_list->i2c_settings.read_buff; + buff_length = i2c_list->i2c_settings.read_buff_len; + read_length = i2c_list->i2c_settings.size; + + CAM_DBG(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); + + if (buff_length < read_length) { + CAM_ERR(CAM_SENSOR, "Invalid buffer size, readLen: %d, bufLen: %d", read_length, buff_length); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + 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"); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + rc = cam_ois_write_q_timer(o_ctrl); + udelay(300); + + if (rc < 0) { + CAM_ERR(CAM_OIS,"Write Q-timer failed rc: %d", rc); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + // SM7325 support burst read + rc = camera_io_dev_read_seq( + &o_ctrl->io_master_info, + i2c_list->i2c_settings.reg_setting[0].reg_addr, + read_buff, + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type, + i2c_list->i2c_settings.size); + if (rc < 0) { + CAM_ERR(CAM_OIS, "Failed: seq read I2C settings: %d", rc); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + flag = (read_buff[0] >> 4) & 0xF; + sample_cnt = ((read_buff[0] & 0xF) << 8) | read_buff[1]; + latest_data_ts = (read_buff[2] << 8) | read_buff[3]; + + CAM_DBG(CAM_OIS, "flag = %d, sample_cnt = %d, latest_data_ts = %d", + flag, sample_cnt, latest_data_ts); + + if (flag != 0x2 && flag != 0x3) { + CAM_ERR(CAM_OIS, "flag %d is not in correct status", flag); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + if (sample_cnt == 0 || sample_cnt > QTIMER_MAX_SAMPLE) { + CAM_ERR(CAM_OIS, "sample_cnt %d is out of range", sample_cnt); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + if (latest_data_ts == 0 || + latest_data_ts > o_ctrl->q_timer_cnt || + ((QTIMER_SAMPLE_TIME*10+3) + latest_data_ts) <= o_ctrl->q_timer_cnt) { + CAM_ERR(CAM_OIS, "latest_data_ts %d is out of range, q_timer_cnt %d", + latest_data_ts, o_ctrl->q_timer_cnt); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + delta_timestamp_ns = (o_ctrl->q_timer_cnt - latest_data_ts)*100000; + o_ctrl->q_timer_timestamp -= delta_timestamp_ns; // latest ois data timestamp + + if (o_ctrl->q_timer_timestamp == 0) { + CAM_ERR(CAM_OIS, "q_timer_timestamp is zero."); + delete_request(&i2c_read_settings); + return -EINVAL; + } + + CAM_DBG(CAM_OIS,"latest ois data timestamp %lld", o_ctrl->q_timer_timestamp); + + memcpy((void *)timestampBuf, (void *)&o_ctrl->q_timer_timestamp, sizeof(uint64_t)); + } + } + 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 bb3a8df636f7..b7cadb5e5367 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -31,6 +31,10 @@ #define MAX_SAMPLE 30 #define READ_BYTE 0xC +#define QTIMER_ADDR 0x70DB +#define QTIMER_SAMPLE_TIME 2 +#define QTIMER_MAX_SAMPLE 20 + enum cam_ois_state { CAM_OIS_INIT, CAM_OIS_ACQUIRE, @@ -158,6 +162,8 @@ struct cam_ois_ctrl_t { bool is_first_vsync; uint8_t *ois_data; int ois_data_size; + uint16_t q_timer_cnt; + uint64_t q_timer_timestamp; }; /** 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 45b3dc27e441..863991792102 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 @@ -176,7 +176,8 @@ enum cam_ois_packet_opcodes { CAM_OIS_PACKET_OPCODE_READ, CAM_OIS_PACKET_OPCODE_WRITE_TIME, CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_ROHM, - CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON, + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON_QTIMER }; enum msm_bus_perf_setting {