From 2ce39159e6cd01a2f006ea9fc87e73611c138cfe Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Mon, 13 Jul 2020 16:14:12 +0800 Subject: [PATCH 01/86] camera: EXPORT_SYMBOL cam_cci_get_subdev function In kernel 5.4, camera driver would compile to camera.ko as GKI requirements, and cci_intf driver need to call cam_cci_get_subdev function, so export symbol cam_cci_get_subdev to it. Change-Id: Ic299d9135f147d703d082604d02b43d88b7eb5ef Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/1679152 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Dawei Wang Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_cci/cam_cci_dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c index 28b76aef1c12..3508ba9402ef 100644 --- a/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c +++ b/drivers/cam_sensor_module/cam_cci/cam_cci_dev.c @@ -28,6 +28,8 @@ struct v4l2_subdev *cam_cci_get_subdev(int cci_dev_index) return sub_device; } +EXPORT_SYMBOL(cam_cci_get_subdev); + static long cam_cci_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { From 23cf72040d316290b4f372c01c8e7e3d86c2a4f9 Mon Sep 17 00:00:00 2001 From: timwang Date: Thu, 16 Jul 2020 09:37:16 -0500 Subject: [PATCH 02/86] V(CR): Port OIS Kernel Changes -Add new fields to OIS data structures -Add capability to program OIS more flexibly Change-Id: I97988cc3a6d7fa2241016bd4a269618c8ff10ad0 Reviewed-on: https://gerrit.mot.com/1736525 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Dawei Wang Reviewed-by: Rav(CR) Vembu Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 298 +++++++++++++----- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 18 ++ include/uapi/camera/media/cam_sensor.h | 6 + 3 files changed, 247 insertions(+), 75 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 b8cc002edb91..8d1770d307c1 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -332,7 +332,13 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->io_master_info.cci_client->sid = ois_info->slave_addr >> 1; o_ctrl->ois_fw_flag = ois_info->ois_fw_flag; + o_ctrl->ois_preprog_flag = ois_info->ois_preprog_flag; + o_ctrl->ois_precoeff_flag = ois_info->ois_precoeff_flag; o_ctrl->is_ois_calib = ois_info->is_ois_calib; + o_ctrl->ois_postcalib_flag = ois_info->ois_postcalib_flag; + o_ctrl->ois_fw_txn_data_sz = ois_info->ois_fw_txn_data_sz; + o_ctrl->ois_fw_inc_addr = ois_info->ois_fw_inc_addr; + o_ctrl->ois_fw_addr_type = ois_info->ois_fw_addr_type; memcpy(o_ctrl->ois_name, ois_info->ois_name, OIS_NAME_LEN); o_ctrl->ois_name[OIS_NAME_LEN - 1] = '\0'; o_ctrl->io_master_info.cci_client->retries = 3; @@ -353,16 +359,97 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, return rc; } -static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) +static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) { uint16_t total_bytes = 0; uint8_t *ptr = NULL; - int32_t rc = 0, cnt; - uint32_t fw_size; + int32_t rc = 0, total_idx, packet_idx; + uint32_t txn_data_size, txn_regsetting_size; const struct firmware *fw = NULL; const char *fw_name_prog = NULL; - const char *fw_name_coeff = NULL; char name_prog[32] = {0}; + struct device *dev = &(o_ctrl->pdev->dev); + struct cam_sensor_i2c_reg_setting i2c_reg_setting; + void *vaddr = NULL; + + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "Invalid Args"); + return -EINVAL; + } + + snprintf(name_prog, 32, "%s.prog", o_ctrl->ois_name); + + /* cast pointer as const pointer*/ + fw_name_prog = name_prog; + + /* Load FW */ + rc = request_firmware(&fw, fw_name_prog, dev); + if (rc) { + CAM_ERR(CAM_OIS, "Failed to locate %s", fw_name_prog); + return rc; + } + + total_bytes = fw->size; + if(o_ctrl->ois_fw_txn_data_sz == 0) + txn_data_size = total_bytes; + else + txn_data_size = o_ctrl->ois_fw_txn_data_sz; + + i2c_reg_setting.addr_type = o_ctrl->ois_fw_addr_type; + i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_reg_setting.delay = 0; + txn_regsetting_size = sizeof(struct cam_sensor_i2c_reg_array) * txn_data_size; + vaddr = vmalloc(txn_regsetting_size); + if (!vaddr) { + CAM_ERR(CAM_OIS, "Failed in allocating i2c_array"); + release_firmware(fw); + return -ENOMEM; + } + + i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) (vaddr); + + for (total_idx = 0, ptr = (uint8_t *)fw->data; total_idx < total_bytes;) { + for(packet_idx = 0; + (packet_idx < txn_data_size) && (total_idx + packet_idx < total_bytes); + packet_idx++, ptr++) + { + int regAddrOffset = 0; + if(o_ctrl->ois_fw_inc_addr == 1) + regAddrOffset = total_idx + packet_idx; + + i2c_reg_setting.reg_setting[packet_idx].reg_addr = + o_ctrl->opcode.prog + regAddrOffset; + i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + i2c_reg_setting.reg_setting[packet_idx].delay = 0; + i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; + } + i2c_reg_setting.size = packet_idx; + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 1); + if (rc < 0) { + CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); + goto release_firmware; + } + total_idx += packet_idx; + } + +release_firmware: + vfree(vaddr); + vaddr = NULL; + txn_regsetting_size = 0; + release_firmware(fw); + + return rc; +} + +static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) +{ + uint16_t total_bytes = 0; + uint8_t *ptr = NULL; + int32_t rc = 0, total_idx, packet_idx; + uint32_t txn_data_size, txn_regsetting_size; + const struct firmware *fw = NULL; + const char *fw_name_coeff = NULL; char name_coeff[32] = {0}; struct device *dev = &(o_ctrl->pdev->dev); struct cam_sensor_i2c_reg_setting i2c_reg_setting; @@ -374,57 +461,8 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) } snprintf(name_coeff, 32, "%s.coeff", o_ctrl->ois_name); - - snprintf(name_prog, 32, "%s.prog", o_ctrl->ois_name); - - /* cast pointer as const pointer*/ - fw_name_prog = name_prog; fw_name_coeff = name_coeff; - /* Load FW */ - rc = request_firmware(&fw, fw_name_prog, dev); - if (rc) { - CAM_ERR(CAM_OIS, "Failed to locate %s", fw_name_prog); - return rc; - } - - total_bytes = fw->size; - i2c_reg_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE; - i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; - i2c_reg_setting.size = total_bytes; - i2c_reg_setting.delay = 0; - fw_size = (sizeof(struct cam_sensor_i2c_reg_array) * total_bytes); - vaddr = vmalloc(fw_size); - if (!vaddr) { - CAM_ERR(CAM_OIS, - "Failed in allocating i2c_array: fw_size: %u", fw_size); - release_firmware(fw); - return -ENOMEM; - } - - i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) ( - vaddr); - - for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes; - cnt++, ptr++) { - i2c_reg_setting.reg_setting[cnt].reg_addr = - o_ctrl->opcode.prog; - i2c_reg_setting.reg_setting[cnt].reg_data = *ptr; - i2c_reg_setting.reg_setting[cnt].delay = 0; - i2c_reg_setting.reg_setting[cnt].data_mask = 0; - } - - rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), - &i2c_reg_setting, 1); - if (rc < 0) { - CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); - goto release_firmware; - } - vfree(vaddr); - vaddr = NULL; - fw_size = 0; - release_firmware(fw); - rc = request_firmware(&fw, fw_name_coeff, dev); if (rc) { CAM_ERR(CAM_OIS, "Failed to locate %s", fw_name_coeff); @@ -432,41 +470,55 @@ static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl) } total_bytes = fw->size; - i2c_reg_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + if(o_ctrl->ois_fw_txn_data_sz == 0) + txn_data_size = total_bytes; + else + txn_data_size = o_ctrl->ois_fw_txn_data_sz; + + i2c_reg_setting.addr_type = o_ctrl->ois_fw_addr_type; i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; - i2c_reg_setting.size = total_bytes; i2c_reg_setting.delay = 0; - fw_size = (sizeof(struct cam_sensor_i2c_reg_array) * total_bytes); - vaddr = vmalloc(fw_size); + txn_regsetting_size = sizeof(struct cam_sensor_i2c_reg_array) * txn_data_size; + vaddr = vmalloc(txn_regsetting_size); if (!vaddr) { - CAM_ERR(CAM_OIS, - "Failed in allocating i2c_array: fw_size: %u", fw_size); + CAM_ERR(CAM_OIS, "Failed in allocating i2c_array"); release_firmware(fw); return -ENOMEM; } - i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) ( - vaddr); + i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) (vaddr); - for (cnt = 0, ptr = (uint8_t *)fw->data; cnt < total_bytes; - cnt++, ptr++) { - i2c_reg_setting.reg_setting[cnt].reg_addr = - o_ctrl->opcode.coeff; - i2c_reg_setting.reg_setting[cnt].reg_data = *ptr; - i2c_reg_setting.reg_setting[cnt].delay = 0; - i2c_reg_setting.reg_setting[cnt].data_mask = 0; + for (total_idx = 0, ptr = (uint8_t *)fw->data; total_idx < total_bytes;) { + for(packet_idx = 0; + (packet_idx < txn_data_size) && (total_idx + packet_idx < total_bytes); + packet_idx++, ptr++) + { + int regAddrOffset = 0; + if(o_ctrl->ois_fw_inc_addr == 1) + regAddrOffset = total_idx + packet_idx; + + i2c_reg_setting.reg_setting[packet_idx].reg_addr = + o_ctrl->opcode.coeff + regAddrOffset; + i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + i2c_reg_setting.reg_setting[packet_idx].delay = 0; + i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; + } + i2c_reg_setting.size = packet_idx; + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 1); + if (rc < 0) { + CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); + goto release_firmware; + } + total_idx += packet_idx; } - rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), - &i2c_reg_setting, 1); - if (rc < 0) - CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); - release_firmware: vfree(vaddr); vaddr = NULL; - fw_size = 0; + txn_regsetting_size = 0; release_firmware(fw); + return rc; } @@ -609,6 +661,34 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) "init parsing failed: %d", rc); return rc; } + } else if (((o_ctrl->ois_preprog_flag) != 0) && + o_ctrl->i2c_preprog_data.is_settings_valid == 0) { + CAM_DBG(CAM_OIS, "Received PreProg Settings"); + i2c_reg_settings = &(o_ctrl->i2c_preprog_data); + i2c_reg_settings->request_id = 0; + rc = cam_sensor_i2c_command_parser( + &o_ctrl->io_master_info, + i2c_reg_settings, + &cmd_desc[i], 1, NULL); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "preprog parsing failed: %d", rc); + return rc; + } + } else if (((o_ctrl->ois_precoeff_flag) != 0) && + o_ctrl->i2c_precoeff_data.is_settings_valid == 0) { + CAM_DBG(CAM_OIS, "Received PreCoeff Settings"); + i2c_reg_settings = &(o_ctrl->i2c_precoeff_data); + i2c_reg_settings->request_id = 0; + rc = cam_sensor_i2c_command_parser( + &o_ctrl->io_master_info, + i2c_reg_settings, + &cmd_desc[i], 1, NULL); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "precoeff parsing failed: %d", rc); + return rc; + } } else if ((o_ctrl->is_ois_calib != 0) && (o_ctrl->i2c_calib_data.is_settings_valid == 0)) { @@ -626,6 +706,20 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) "Calib parsing failed: %d", rc); return rc; } + } else if (((o_ctrl->ois_postcalib_flag) != 0) && + o_ctrl->i2c_postcalib_data.is_settings_valid == 0) { + CAM_DBG(CAM_OIS, "Received PostCalib Settings"); + i2c_reg_settings = &(o_ctrl->i2c_postcalib_data); + i2c_reg_settings->request_id = 0; + rc = cam_sensor_i2c_command_parser( + &o_ctrl->io_master_info, + i2c_reg_settings, + &cmd_desc[i], 1, NULL); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "postcalib parsing failed: %d", rc); + return rc; + } } break; } @@ -640,14 +734,40 @@ 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->ois_preprog_flag) { + rc = cam_ois_apply_settings(o_ctrl, + &o_ctrl->i2c_preprog_data); + if (rc) { + CAM_ERR(CAM_OIS, "Cannot apply preprog settings"); + goto pwr_dwn; + } + } + if (o_ctrl->ois_fw_flag) { - rc = cam_ois_fw_download(o_ctrl); + rc = cam_ois_fw_prog_download(o_ctrl); if (rc) { CAM_ERR(CAM_OIS, "Failed OIS FW Download"); goto pwr_dwn; } } + if (o_ctrl->ois_precoeff_flag) { + rc = cam_ois_apply_settings(o_ctrl, + &o_ctrl->i2c_precoeff_data); + if (rc) { + CAM_ERR(CAM_OIS, "Cannot apply precoeff settings"); + goto pwr_dwn; + } + } + + if (o_ctrl->ois_fw_flag) { + rc = cam_ois_fw_coeff_download(o_ctrl); + if (rc) { + CAM_ERR(CAM_OIS, "Failed OIS COEFF FW Download"); + goto pwr_dwn; + } + } + rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data); if ((rc == -EAGAIN) && (o_ctrl->io_master_info.master_type == CCI_MASTER)) { @@ -673,18 +793,46 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } + if (o_ctrl->ois_postcalib_flag) { + CAM_DBG(CAM_OIS, "starting post calib data"); + rc = cam_ois_apply_settings(o_ctrl, + &o_ctrl->i2c_postcalib_data); + if (rc) { + CAM_ERR(CAM_OIS, "Cannot apply post calib data"); + goto pwr_dwn; + } + } + rc = delete_request(&o_ctrl->i2c_init_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Init data: rc: %d", rc); rc = 0; } + rc = delete_request(&o_ctrl->i2c_preprog_data); + if (rc < 0) { + CAM_WARN(CAM_OIS, + "Fail deleting PreProg data: rc: %d", rc); + rc = 0; + } + rc = delete_request(&o_ctrl->i2c_precoeff_data); + if (rc < 0) { + CAM_WARN(CAM_OIS, + "Fail deleting PreCoeff data: rc: %d", rc); + rc = 0; + } rc = delete_request(&o_ctrl->i2c_calib_data); if (rc < 0) { CAM_WARN(CAM_OIS, "Fail deleting Calibration data: rc: %d", rc); rc = 0; } + rc = delete_request(&o_ctrl->i2c_postcalib_data); + if (rc < 0) { + CAM_WARN(CAM_OIS, + "Fail deleting PostCalib data: rc: %d", rc); + rc = 0; + } break; case CAM_OIS_PACKET_OPCODE_OIS_CONTROL: if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { 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 ddb585bc4f2b..27eb1af573cc 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -95,12 +95,21 @@ struct cam_ois_intf_params { * @i2c_init_data : ois i2c init settings * @i2c_mode_data : ois i2c mode settings * @i2c_time_data : ois i2c time write settings + * @i2c_preprog_data : ois i2c preprog settings + * @i2c_precoeff_data : ois i2c precoeff settings + * @i2c_postcalib_data : ois i2c postcalib settings * @i2c_calib_data : ois i2c calib settings * @ois_device_type : ois device type * @cam_ois_state : ois_device_state * @ois_fw_flag : flag for firmware download + * @ois_preprog_flag : flag for preprog reg settings + * @ois_precoeff_flag : flag for precoeff reg settings * @is_ois_calib : flag for Calibration data + * @ois_postcalib_flag : flag for postcalib reg settings * @opcode : ois opcode + * @ois_fw_inc_addr : flag to increment address when sending fw + * @ois_fw_addr_type : address type of fw + * @ois_fw_txn_data_sz : num data bytes per i2c txn when sending fw * @device_name : Device name * */ @@ -115,14 +124,23 @@ struct cam_ois_ctrl_t { struct cam_subdev v4l2_dev_str; struct cam_ois_intf_params bridge_intf; struct i2c_settings_array i2c_init_data; + struct i2c_settings_array i2c_preprog_data; + struct i2c_settings_array i2c_precoeff_data; struct i2c_settings_array i2c_calib_data; + struct i2c_settings_array i2c_postcalib_data; struct i2c_settings_array i2c_mode_data; struct i2c_settings_array i2c_time_data; enum msm_camera_device_type_t ois_device_type; enum cam_ois_state cam_ois_state; char ois_name[32]; uint8_t ois_fw_flag; + uint8_t ois_preprog_flag; + uint8_t ois_precoeff_flag; uint8_t is_ois_calib; + uint8_t ois_postcalib_flag; + uint8_t ois_fw_txn_data_sz; + uint8_t ois_fw_inc_addr; + uint8_t ois_fw_addr_type; struct cam_ois_opcode opcode; }; diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index f935a7a702b3..9552d118387a 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -137,6 +137,12 @@ struct cam_cmd_ois_info { __u8 cmd_type; __u8 ois_fw_flag; __u8 is_ois_calib; + __u8 ois_preprog_flag; + __u8 ois_precoeff_flag; + __u8 ois_postcalib_flag; + __u8 ois_fw_txn_data_sz; + __u8 ois_fw_inc_addr; + __u8 ois_fw_addr_type; char ois_name[MAX_OIS_NAME_SIZE]; struct cam_ois_opcode opcode; } __attribute__((packed)); From ae871fa71ddf2fb208572660e9be9bf056141818 Mon Sep 17 00:00:00 2001 From: timwang Date: Tue, 1 Sep 2020 20:13:10 -0500 Subject: [PATCH 03/86] V(CR): Port Active OIS Kernel Changes -Adds Active OIS packet decoding logic -Adds logic to read Active OIS data out of the OIS chip Change-Id: I428e912d401fd18d555df62fe4cdea1d8a3ca18d Reviewed-on: https://gerrit.mot.com/1738888 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Jian Luan Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 95 +++++++++++++++++++ .../cam_sensor_utils/cam_sensor_cmn_header.h | 3 +- 2 files changed, 97 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 8d1770d307c1..c40c8ee47cc4 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -984,6 +984,101 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } break; } + case CAM_OIS_PACKET_OPCODE_ACTIVE_EIS: { + struct cam_buf_io_cfg *io_cfg; + struct cam_buf_io_cfg *timestamp_io_cfg; + struct i2c_settings_array i2c_read_settings; + struct timespec64 ts; + uintptr_t buf_addr = 0x0; + size_t buf_size = 0; + uint64_t timestamp; + uint8_t *timestampBuf; + uint32_t timestampBufLen; + + 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; + } + + rc = cam_sensor_i2c_read_data( + &i2c_read_settings, + &o_ctrl->io_master_info); + if (rc < 0) { + CAM_ERR(CAM_OIS, "cannot read data rc: %d", rc); + delete_request(&i2c_read_settings); + return rc; + } + + ktime_get_boottime_ts64(&ts); + timestamp = + (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); + 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)); + 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_sensor_utils/cam_sensor_cmn_header.h b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h index 58a248f4c882..707d913a3ae1 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 @@ -174,7 +174,8 @@ enum cam_ois_packet_opcodes { CAM_OIS_PACKET_OPCODE_INIT, CAM_OIS_PACKET_OPCODE_OIS_CONTROL, CAM_OIS_PACKET_OPCODE_READ, - CAM_OIS_PACKET_OPCODE_WRITE_TIME + CAM_OIS_PACKET_OPCODE_WRITE_TIME, + CAM_OIS_PACKET_OPCODE_ACTIVE_EIS }; enum msm_bus_perf_setting { From e57ff4ba23820588c48a9d94a4f5ea7e5982e46b Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 7 May 2020 17:00:07 +0530 Subject: [PATCH 04/86] msm: camera: sensor: Read using addr and data type [detail] Read using address and data type provided in xml CRs-Fixed: 2675042 Change-Id: Ice85f2ce4a6fa38a7de4b1bf4233449c52cd39e2 Signed-off-by: Vishal Verma Reviewed-on: https://gerrit.mot.com/1761431 Submit-Approved: Jira Key Tested-by: Jira Key SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Reviewed-by: Wang Liu (cherry picked from commit cab465769a5a610d37bccb99e8fb722ab2ffe188) Reviewed-on: https://gerrit.mot.com/1763255 Reviewed-by: Dawei Wang (cherry picked from commit f1f2e1f642f7d1526d9ceb51e9947ceb98292862) Reviewed-on: https://gerrit.mot.com/1893806 Reviewed-by: Shuo Wang Reviewed-by: Long Cheng Reviewed-by: Jian Zhang Reviewed-by: Zhenxin Xi Reviewed-by: Zhuoran Xu --- drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 8298f9f81bc6..d8db350e033d 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -154,7 +154,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, csl_packet = (struct cam_packet *)(generic_ptr + (uint32_t)config.offset); - if (cam_packet_util_validate_packet(csl_packet, + if ((csl_packet == NULL) || cam_packet_util_validate_packet(csl_packet, remain_len)) { CAM_ERR(CAM_SENSOR, "Invalid packet params"); rc = -EINVAL; From 09fc6955503e5a9d9d71759e5b4f08e170300686 Mon Sep 17 00:00:00 2001 From: wangdw10 Date: Thu, 11 Mar 2021 20:53:07 +0800 Subject: [PATCH 05/86] msm: ois: support new OIS i2c settings Add new fields to OIS data structures, support to apply ois preprog data, precoeff data and postcalibration data Change-Id: Ic8546882e053c10981698bc5ef5182571e6afc0b Signed-off-by: wangdw10 Reviewed-on: https://gerrit.mot.com/1898786 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Dawei Wang Reviewed-by: Long Cheng Reviewed-by: Zhuoran Xu Reviewed-by: Xu Ji Reviewed-by: Shuo Wang Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key Reviewed-by: Zhichao Chen --- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index a7616d4d19b1..aa771b3bd14d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -306,7 +306,10 @@ static int cam_ois_component_bind(struct device *dev, soc_private->power_info.dev = &pdev->dev; INIT_LIST_HEAD(&(o_ctrl->i2c_init_data.list_head)); + INIT_LIST_HEAD(&(o_ctrl->i2c_preprog_data.list_head)); + INIT_LIST_HEAD(&(o_ctrl->i2c_precoeff_data.list_head)); INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head)); + INIT_LIST_HEAD(&(o_ctrl->i2c_postcalib_data.list_head)); INIT_LIST_HEAD(&(o_ctrl->i2c_mode_data.list_head)); mutex_init(&(o_ctrl->ois_mutex)); rc = cam_ois_driver_soc_init(o_ctrl); From 68f7e5cb865d1fb56441d644ec3bb0d325b7944e Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Mon, 22 Mar 2021 20:32:52 +0800 Subject: [PATCH 06/86] cam: Add actuator standalone diver for vibrator. -To eliminate the resonance noise during system vibrator vibrating, set actuator to specified DAC position(480 on DW9714), then the resonance noise can be obviously improved. To achieve the conbination between vibrator and camera AF actuator,we implemnte: - Actuator separately control during camera power off. - Actuator policy to avoid vibrating disturb normal camera AF. port from (CR),fix berlna wide camera resonance noise issue. -Port from (CR): cam/actuator: Add CCI access lock to avoid conflicts. Usually actuator initial setting will execute power down reset(PD), actuator can't respond CCI access for a while after PD. Add lock to avoid access actuator while PD operation. -Port from (CR): cam/actuator: Create separate work queue for park lens. Park lens may cost more than 100ms for different camera modules, create seperate work queue for actuator to avoid park lens operation block system_wq too long. -Port from (CR): cam/actautor: Optimizing park lens for vibrating. Move lens to noise reduction postion after camera exited. -Port from (CR): cam/actuator: Avoid error releasing CCI/regulator. Avoid unbalanced aquire/release of CCI/regulator when actuator init failed. Due to when CCI init for vibrator failed, regulators had been released. -For new baseline sm8350,compile this standalone actuator diver into camera.ko Change-Id: If77d10badfb4147c467ebae238f4e6af317d466f Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1906964 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Dawei Wang Reviewed-by: Darong Huang Reviewed-by: Long Cheng Reviewed-by: Xu Ji Reviewed-by: Jian Zhang Reviewed-by: Zhuoran Xu Reviewed-by: Bolei Shang Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- drivers/Makefile | 6 + .../cam_actuator/cam_actuator_core.c | 32 +- .../cam_actuator/cam_actuator_dev.h | 3 + .../cam_actuator/cam_actuator_soc.c | 9 + .../cam_actuator/mot_actuator.c | 1032 +++++++++++++++++ .../cam_actuator/mot_actuator.h | 35 + .../cam_actuator/mot_actuator_policy.c | 113 ++ .../cam_actuator/mot_actuator_policy.h | 20 + drivers/camera_main.c | 2 + include/uapi/camera/media/cam_req_mgr.h | 1 + 10 files changed, 1252 insertions(+), 1 deletion(-) create mode 100644 drivers/cam_sensor_module/cam_actuator/mot_actuator.c create mode 100644 drivers/cam_sensor_module/cam_actuator/mot_actuator.h create mode 100644 drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.c create mode 100644 drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.h diff --git a/drivers/Makefile b/drivers/Makefile index 7a7b0250f03f..c2349c1f090e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -172,6 +172,12 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \ cam_sensor_module/cam_sensor_utils/cam_sensor_util.o \ cam_sensor_module/cam_res_mgr/cam_res_mgr.o +ifneq (,$(filter $(CONFIG_AF_NOISE_ELIMINATION), y m)) +camera-$(CONFIG_SPECTRA_SENSOR) += \ + cam_sensor_module/cam_actuator/mot_actuator.o \ + cam_sensor_module/cam_actuator/mot_actuator_policy.o +endif + camera-$(CONFIG_LEDS_QPNP_FLASH_V2) += \ cam_sensor_module/cam_flash/cam_flash_dev.o \ cam_sensor_module/cam_flash/cam_flash_core.o \ diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index 722f91e334b3..cfa2f8e0d6a7 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -10,6 +10,9 @@ #include "cam_trace.h" #include "cam_common_util.h" #include "cam_packet_util.h" +#ifdef CONFIG_AF_NOISE_ELIMINATION +#include "mot_actuator_policy.h" +#endif int32_t cam_actuator_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -259,7 +262,13 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl, CAM_ERR(CAM_ACTUATOR, " Invalid settings"); return -EINVAL; } - +#ifdef CONFIG_AF_NOISE_ELIMINATION + /*Usually actuator initial setting will execute power down reset(PD), actuator can't respond + CCI access for a while after PD. Add lock to avoid access actuator while PD operation.*/ + if (a_ctrl->is_multi_user_supported) { + mot_actuator_lock(); + } +#endif list_for_each_entry(i2c_list, &(i2c_set->list_head), list) { rc = cam_actuator_i2c_modes_util( @@ -276,6 +285,14 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl, } } +#ifdef CONFIG_AF_NOISE_ELIMINATION + /*Usually actuator initial setting will execute power down reset(PD), actuator can't respond + CCI access for a while after PD. Add lock to avoid access actuator while PD operation.*/ + if (a_ctrl->is_multi_user_supported) { + mot_actuator_unlock(); + } +#endif + return rc; } @@ -582,6 +599,13 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, } } +#ifdef CONFIG_AF_NOISE_ELIMINATION + if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE && + a_ctrl->is_multi_user_supported == true) { + mot_actuator_get(ACTUATOR_CLIENT_CAMERA); + } +#endif + if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE) { rc = cam_actuator_power_up(a_ctrl); if (rc < 0) { @@ -595,6 +619,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc = cam_actuator_apply_settings(a_ctrl, &a_ctrl->i2c_data.init_settings); if (rc < 0) { + delete_request(&a_ctrl->i2c_data.init_settings); CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings"); goto end; } @@ -890,6 +915,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, } if (a_ctrl->cam_act_state == CAM_ACTUATOR_CONFIG) { +#ifdef CONFIG_AF_NOISE_ELIMINATION + if (a_ctrl->is_multi_user_supported == true) { + mot_actuator_put(ACTUATOR_CLIENT_CAMERA); + } +#endif rc = cam_actuator_power_down(a_ctrl); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h b/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h index 1ec575301cfc..5406e2c96e55 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h @@ -115,6 +115,9 @@ struct cam_actuator_ctrl_t { struct cam_actuator_query_cap act_info; struct actuator_intf_params bridge_intf; uint32_t last_flush_req; +#ifdef CONFIG_AF_NOISE_ELIMINATION + bool is_multi_user_supported; +#endif }; /** diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c index cb852423a228..7ef6b95595d2 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c @@ -34,6 +34,15 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl, of_node = soc_info->dev->of_node; +#ifdef CONFIG_AF_NOISE_ELIMINATION + if (!of_property_read_bool(of_node, "multi-user-support")) { + a_ctrl->is_multi_user_supported = false; + } else { + a_ctrl->is_multi_user_supported = true; + } + CAM_DBG(CAM_ACTUATOR, "multi-user-support %d", a_ctrl->is_multi_user_supported); +#endif + if (a_ctrl->io_master_info.master_type == CCI_MASTER) { rc = of_property_read_u32(of_node, "cci-master", &(a_ctrl->cci_i2c_master)); diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c new file mode 100644 index 000000000000..e8fe296ca82d --- /dev/null +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -0,0 +1,1032 @@ +/* + * Copyright (C) 2020 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cam_debug_util.h" +#include "cam_cci_dev.h" +#include "mot_actuator.h" +#include "mot_actuator_policy.h" +#include "cam_sensor_io.h" +#include "cam_req_mgr_dev.h" +/*=================ACTUATOR HW INFO====================*/ +#define DEVICE_NAME_LEN 32 +#define MAX_ACTUATOR_NUM 3 +#define REGULATOR_NAME_MAX_LEN 32 +#define ANDROIDBOOT_DEVICE_MAX_LEN 32 + +typedef enum { + MOT_ACTUATOR_INVALID, + MOT_ACTUATOR_FIRST, + MOT_ACTUATOR_GT9767 = MOT_ACTUATOR_FIRST, + MOT_ACTUATOR_GT9772, + MOT_ACTUATOR_DW9714, + MOT_ACTUATOR_NUM, +} mot_actuator_type; + +typedef enum { + REGULATOR_IOVDD, + REGULATOR_AFVDD, + REGULATOR_NUM, +} mot_regulator_type; + +typedef enum { + MOT_DEVICE_NIO, + MOT_DEVICE_BERLNA, + MOT_DEVICE_NUM, +} mot_dev_type; + +typedef struct { + uint16_t kneePoint; + uint16_t step; +} mot_park_lens_step; + +typedef struct { + struct cam_sensor_i2c_reg_setting *init_setting; + struct cam_sensor_i2c_reg_setting *dac_setting; +} mot_actuator_settings; + +typedef struct { + mot_actuator_type actuator_type; + uint16_t dac_pos; + uint16_t cci_addr; + uint16_t cci_dev; + uint16_t cci_master; + char *regulator_list[REGULATOR_NUM]; + uint32_t regulator_volt_uv[REGULATOR_NUM]; + bool park_lens_needed; +} mot_actuator_hw_info; + +typedef struct { + mot_dev_type dev_type; + uint16_t actuator_num; + char dev_name[DEVICE_NAME_LEN]; + mot_actuator_hw_info actuator_info[MAX_ACTUATOR_NUM]; +} mot_dev_info; + +/*Register settings of GT9767*/ //todo +static struct cam_sensor_i2c_reg_array mot_gt9767_init_setting[] ={ + {0x02, 0x00, 300}, + {0x06, 0x0A, 0}, + {0x07, 0x01, 0}, + {0x08, 0x43, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_gt9767_dac_setting[] ={ + {0x03, 0x3ff, 0} +}; + +static struct cam_sensor_i2c_reg_setting mot_gt9767_init_settings = { + .reg_setting = mot_gt9767_init_setting, + .size = ARRAY_SIZE(mot_gt9767_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_gt9767_dac_settings = { + .reg_setting = mot_gt9767_dac_setting, + .size = ARRAY_SIZE(mot_gt9767_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + +/*Register settings of GT9772*/ +static struct cam_sensor_i2c_reg_array mot_gt9772_init_setting[] ={ + {0xED, 0xAB, 0}, + {0x02, 0x01, 0}, + {0x02, 0x00, 300}, + {0x06, 0x84, 0}, + {0x07, 0x01, 0}, + {0x08, 0x62, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_gt9772_dac_setting[] ={ + {0x03, 0x3ff, 0} +}; + +static struct cam_sensor_i2c_reg_setting mot_gt9772_init_settings = { + .reg_setting = mot_gt9772_init_setting, + .size = ARRAY_SIZE(mot_gt9772_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_gt9772_dac_settings = { + .reg_setting = mot_gt9772_dac_setting, + .size = ARRAY_SIZE(mot_gt9772_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + +/*Register settings of DW9714*/ //todo +static struct cam_sensor_i2c_reg_array mot_dw9714_init_setting[] ={ + {0xED, 0xAB, 0}, + {0x02, 0x01, 0}, + {0x02, 0x00, 1000}, + {0x06, 0x84, 0}, + {0x07, 0x01, 0}, + {0x08, 0x78, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_dw9714_dac_setting[] ={ //todo + {0x03, 0x3ff, 0} +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9714_init_settings = { + .reg_setting = mot_dw9714_init_setting, + .size = ARRAY_SIZE(mot_dw9714_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9714_dac_settings = { + .reg_setting = mot_dw9714_dac_setting, + .size = ARRAY_SIZE(mot_dw9714_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + +/*Register settings of all supported actuator types*/ +static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { + //MUST be sorted as definition order in above structure: mot_actuator_type + {&mot_gt9767_init_settings, &mot_gt9767_dac_settings}, + {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, + {&mot_dw9714_init_settings, &mot_dw9714_dac_settings}, +}; + +static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { + { + .dev_type = MOT_DEVICE_NIO, + .actuator_num = 1, + .dev_name = "nio", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_GT9772, + .dac_pos = 400, + .cci_addr = 0x0c, + .cci_dev = 0x01, + .cci_master = 0x0, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .park_lens_needed = true, + }, + }, + }, + { + .dev_type = MOT_DEVICE_BERLNA, + .actuator_num = 1, + .dev_name = "berlna", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9714, + .dac_pos = 400, + .cci_addr = 0x0c, + .cci_dev = 0x01, + .cci_master = 0x01, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .park_lens_needed = true, + }, + }, + }, +}; + +static uint32_t mot_device_index = MOT_DEVICE_NUM; + +static char *bootargs_str; +static char androidboot_device[ANDROIDBOOT_DEVICE_MAX_LEN]; +int mot_actuator_get_bootarg(char *key, char **value) +{ + const char *bootargs_tmp = NULL; + char *idx = NULL; + char *kvpair = NULL; + int err = 1; + struct device_node *n = of_find_node_by_path("/chosen"); + size_t bootargs_tmp_len = 0; + + if (n == NULL) + goto err; + + if (of_property_read_string(n, "bootargs", &bootargs_tmp) != 0) + goto putnode; + + bootargs_tmp_len = strlen(bootargs_tmp); + if (!bootargs_str) { + /* The following operations need a non-const + * version of bootargs + */ + bootargs_str = kzalloc(bootargs_tmp_len + 1, GFP_KERNEL); + if (!bootargs_str) + goto putnode; + } + strlcpy(bootargs_str, bootargs_tmp, bootargs_tmp_len + 1); + + idx = strnstr(bootargs_str, key, strlen(bootargs_str)); + if (idx) { + kvpair = strsep(&idx, " "); + if (kvpair) + if (strsep(&kvpair, "=")) { + *value = strsep(&kvpair, " "); + if (*value) + err = 0; + } + } + +putnode: + of_node_put(n); +err: + return err; +} + +static int cam_select_actuator_by_device_name(void) +{ + char *str; + uint32_t i; + if (mot_actuator_get_bootarg("androidboot.device=", &str) == 0) + strlcpy(androidboot_device, str, ANDROIDBOOT_DEVICE_MAX_LEN); + + for (i=0; i= MOT_DEVICE_NUM) { + CAM_ERR(CAM_ACTUATOR, "UNKNOWN DEVICE:%s", str); + } + return 1; +} + +/*=================ACTUATOR RUNTIME====================*/ +#define VIBRATING_MAX_INTERVAL 2000//ms +#define PARK_LENS_MAX_STAGES 10 + +struct mot_actuator_ctrl_t { + struct cam_subdev v4l2_dev_str; + struct platform_device *pdev; + char device_name[20]; + struct workqueue_struct *mot_actuator_wq; + struct delayed_work delay_work; + struct mutex actuator_lock; +}; + +enum mot_actuator_state_e { + MOT_ACTUATOR_IDLE, + MOT_ACTUATOR_INITED, + MOT_ACTUATOR_STARTED, + MOT_ACTUATOR_RELEASED +}; + +typedef struct { + struct cam_sensor_cci_client client; + struct camera_io_master io_master; + struct regulator * regulators[REGULATOR_NUM]; + uint32_t safe_dac_pos; +} mot_actuator_runtime_type; + +static struct mot_actuator_ctrl_t mot_actuator_fctrl; +static enum mot_actuator_state_e mot_actuator_state = MOT_ACTUATOR_IDLE; +static mot_actuator_runtime_type mot_actuator_runtime[MAX_ACTUATOR_NUM]; +static uint32_t lens_safe_pos_dac = 0; +static uint32_t lens_park_pos = 100; +static mot_park_lens_step lens_park_table[PARK_LENS_MAX_STAGES] = { + {300, 60}, + {200, 40}, +}; +static bool runtime_inited = 0; + +static int mot_actuator_init_runtime(void) +{ + int i; + int regIdx; + + if (runtime_inited == true) { + CAM_DBG(CAM_ACTUATOR, "Runtime has been inited!!!"); + return 0; + } + + if (mot_device_index >= MOT_DEVICE_NUM) { + CAM_ERR(CAM_ACTUATOR, "INVALID DEVICE!!!"); + return -1; + } + + for (i = 0; i < mot_dev_list[mot_device_index].actuator_num; i++) { + if (mot_dev_list[mot_device_index].actuator_info[i].actuator_type == MOT_ACTUATOR_INVALID) { + CAM_DBG(CAM_ACTUATOR, "NO. %d actuator type is %d", + i, mot_dev_list[mot_device_index].actuator_info[i].actuator_type); + continue; + } + + /*Init actuators' CCI data*/ + mot_actuator_runtime[i].io_master.master_type = CCI_MASTER; + mot_actuator_runtime[i].io_master.cci_client = &mot_actuator_runtime[i].client; + mot_actuator_runtime[i].client.sid = mot_dev_list[mot_device_index].actuator_info[i].cci_addr; + mot_actuator_runtime[i].client.cci_device = mot_dev_list[mot_device_index].actuator_info[i].cci_dev; + mot_actuator_runtime[i].client.cci_i2c_master = mot_dev_list[mot_device_index].actuator_info[i].cci_master; + CAM_DBG(CAM_ACTUATOR, "NO. %d ACTUATOR sid:%x, cci_device:%d, cci_i2c_master:%d", + i, mot_actuator_runtime[i].client.sid, mot_actuator_runtime[i].client.cci_device, + mot_actuator_runtime[i].client.cci_i2c_master); + + /*Init actuators' DAC pos*/ + if (lens_safe_pos_dac != 0) { + mot_actuator_runtime[i].safe_dac_pos = lens_safe_pos_dac; + } else { + mot_actuator_runtime[i].safe_dac_pos = mot_dev_list[mot_device_index].actuator_info[i].dac_pos; + } + CAM_DBG(CAM_ACTUATOR, "ACTUATOR NO. %d, DAC pos: %d", i, mot_actuator_runtime[i].safe_dac_pos); + + /*Init actuators' regulators*/ + for (regIdx = 0; regIdx < REGULATOR_NUM; regIdx++) { + char *reg_name = mot_dev_list[mot_device_index].actuator_info[i].regulator_list[regIdx]; + if (reg_name[0] != '\0' && mot_actuator_runtime[i].regulators[regIdx] == NULL) { + mot_actuator_runtime[i].regulators[regIdx] = regulator_get(&mot_actuator_fctrl.v4l2_dev_str.pdev->dev, reg_name); + if (mot_actuator_runtime[i].regulators[regIdx] == NULL) { + CAM_DBG(CAM_ACTUATOR, "REGULATOR NO. %d of actuator %d IS NULL!", regIdx, i); + } else { + CAM_DBG(CAM_ACTUATOR, "REGULATOR GET SUCCESS:%p", mot_actuator_runtime[i].regulators[regIdx]); + regulator_set_voltage(mot_actuator_runtime[i].regulators[regIdx], + mot_dev_list[mot_device_index].actuator_info[i].regulator_volt_uv[regIdx], + mot_dev_list[mot_device_index].actuator_info[i].regulator_volt_uv[regIdx]); + } + } + } + } + + runtime_inited = true; + + return 0; +} + +static int32_t mot_actuator_apply_settings(struct camera_io_master *io_master_info, + struct cam_sensor_i2c_reg_setting *write_setting) +{ + /*Usually actuator initial setting will execute power down reset(PD), actuator can't respond + CCI access for a while after PD. Add lock to avoid access actuator while PD operation.*/ + int32_t ret = 0; + mot_actuator_lock(); + ret = camera_io_dev_write(io_master_info, write_setting); + mot_actuator_unlock(); + return ret; +} + +static struct cam_sensor_i2c_reg_setting *mot_actuator_get_init_settings(uint32_t index) +{ + uint32_t actuator_index = mot_dev_list[mot_device_index].actuator_info[index].actuator_type - MOT_ACTUATOR_FIRST; + return mot_actuator_list[actuator_index].init_setting; +} + +static struct cam_sensor_i2c_reg_setting *mot_actuator_get_dac_settings(uint32_t index) +{ + uint32_t actuator_index = mot_dev_list[mot_device_index].actuator_info[index].actuator_type - MOT_ACTUATOR_FIRST; + return mot_actuator_list[actuator_index].dac_setting; +} + +static int32_t mot_actuator_move_lens_by_dac(uint32_t index, uint32_t dac_value) +{ + struct cam_sensor_i2c_reg_setting *dac_setting = mot_actuator_get_dac_settings(index); + /*Fill the DAC value*/ + dac_setting->reg_setting[0].reg_data = dac_value; + CAM_DBG(CAM_ACTUATOR, "move lens to DAC pos: %d", dac_value); + return mot_actuator_apply_settings(&mot_actuator_runtime[index].io_master, dac_setting); +} + +static int32_t mot_actuator_power_on(uint32_t index) +{ + int i; + int ret = 0; + + for (i = 0; i < REGULATOR_NUM; i++) { + if (mot_actuator_runtime[index].regulators[i] != NULL) { + ret = regulator_enable(mot_actuator_runtime[index].regulators[i]); + CAM_DBG(CAM_ACTUATOR, "power on ret %d", ret); + } + } + + return ret; +} + +static int32_t mot_actuator_power_off(uint32_t index) +{ + int i; + int ret = 0; + + for (i = 0; i < REGULATOR_NUM; i++) { + if (mot_actuator_runtime[index].regulators[i] != NULL) { + ret = regulator_disable(mot_actuator_runtime[index].regulators[i]); + CAM_DBG(CAM_ACTUATOR, "power off ret %d", ret); + } + } + + return ret; +} + +int32_t mot_actuator_init_cci(uint32_t index) +{ + int32_t ret = 0; + + CAM_DBG(CAM_ACTUATOR, "init cci."); + ret = camera_io_init(&mot_actuator_runtime[index].io_master); + if (ret != 0) { + CAM_ERR(CAM_ACTUATOR, "init cci failed, ret=%d!!!", ret); + } + return ret; +} + +int32_t mot_actuator_release_cci(uint32_t index) +{ + int32_t ret = 0; + + CAM_DBG(CAM_ACTUATOR, "release cci."); + ret = camera_io_release(&mot_actuator_runtime[index].io_master); + if (ret != 0) { + CAM_ERR(CAM_ACTUATOR, "release cci failed, ret=%d!!!", ret); + } + return ret; +} + +static int32_t mot_actuator_vib_move_lens(uint32_t index) +{ + int32_t ret = 0; + + if (mot_device_index >= MOT_DEVICE_NUM || index > mot_dev_list[mot_device_index].actuator_num) { + CAM_ERR(CAM_ACTUATOR, "INVALID device!!!"); + return -1; + } + + if (mot_actuator_state <= MOT_ACTUATOR_IDLE || mot_actuator_state >= MOT_ACTUATOR_RELEASED) { + mot_actuator_init_runtime(); + mot_actuator_power_on(index); + ret = mot_actuator_init_cci(index); + if (ret == 0) { + ret = mot_actuator_apply_settings(&mot_actuator_runtime[index].io_master, mot_actuator_get_init_settings(index)); + if (ret == 0) { + CAM_DBG(CAM_ACTUATOR, "init acutator sucess", ret); + mot_actuator_state = MOT_ACTUATOR_INITED; + } else { + mot_actuator_release_cci(index); + CAM_ERR(CAM_ACTUATOR, "init acutator failed, ret=%d!!!", ret); + } + } else { + CAM_ERR(CAM_ACTUATOR, "init cci device failed, ret=%d!!!", ret); + } + + if (ret != 0) { + CAM_ERR(CAM_ACTUATOR, "init actuator encountered error, power off now. ret=%d", ret); + mot_actuator_power_off(index); + } + } + + if (ret == 0 && mot_actuator_state == MOT_ACTUATOR_INITED) { + /*Move lens to the specified position.*/ + unsigned int consumers = mot_actuator_get_consumers(); + + CAM_DBG(CAM_ACTUATOR, "actuator consumers: %d", consumers); + + if ((consumers & CLINET_VIBRATOR_MASK) == 0) { + mot_actuator_get(ACTUATOR_CLIENT_VIBRATOR); + } + + if (consumers == 0) { + /*Just move lens when camera off and before first vibrating*/ + ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + if (ret == 0) { + CAM_DBG(CAM_ACTUATOR, "actuator:%d is safe now, please start vibrating"); + } else { + CAM_ERR(CAM_ACTUATOR, "write dac failed, ret=%d!!!", ret); + } + } else { + CAM_DBG(CAM_ACTUATOR, "actuator is already in position."); + } + + mot_actuator_state = MOT_ACTUATOR_STARTED; + } else { + CAM_DBG(CAM_ACTUATOR, "May be already in position. state: %d ret=%d.", mot_actuator_state, ret); + } + + return ret; +} + +static int32_t mot_actuator_park_lens(uint32_t index) +{ + uint32_t cur_len_pos = mot_actuator_runtime[index].safe_dac_pos; + int stageIndex; + unsigned int consumers = 0; + int32_t ret = 0; + + if (mot_dev_list[mot_device_index].actuator_info[index].park_lens_needed == false) { + CAM_DBG(CAM_ACTUATOR, "Park lens is not needed."); + return 0; + } + + while (cur_len_pos > lens_park_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "Park lens was broken by other actuator requests."); + break; + } + + for (stageIndex=0; stageIndex= lens_park_table[stageIndex].kneePoint && lens_park_table[stageIndex].step > 0) { + cur_len_pos -= lens_park_table[stageIndex].step; + break; + } + } + + if (lens_park_table[stageIndex].step <= 0 && cur_len_pos > lens_park_pos) { + cur_len_pos -= 10; + } + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "Park Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos <= lens_park_pos) { + /*For skipping the last delay*/ + CAM_DBG(CAM_ACTUATOR, "Park lens done."); + break; + } + + usleep_range(10000, 12000); + } + + return 0; +} + +int mot_actuator_on_vibrate_start(void) +{ + bool is_exiting = false; + ktime_t start,end,duration; + start = ktime_get(); + cancel_delayed_work(&mot_actuator_fctrl.delay_work); + if (mutex_is_locked(&mot_actuator_fctrl.actuator_lock)) { + is_exiting = true; + } + mutex_lock(&mot_actuator_fctrl.actuator_lock); + if (is_exiting) { + CAM_WARN(CAM_ACTUATOR, "Wait 2~3ms to let CCI release done."); + usleep_range(2, 3); + } + mot_actuator_vib_move_lens(0); + mutex_unlock(&mot_actuator_fctrl.actuator_lock); + end = ktime_get(); + duration = ktime_sub(end, start); + duration /= 1000; + CAM_DBG(CAM_ACTUATOR, "Move lens delay: %dus", duration); + return 0; +} +EXPORT_SYMBOL(mot_actuator_on_vibrate_start); + +int mot_actuator_on_vibrate_stop(void) +{ + if (mot_actuator_fctrl.mot_actuator_wq != NULL) { + queue_delayed_work(mot_actuator_fctrl.mot_actuator_wq, + &mot_actuator_fctrl.delay_work, msecs_to_jiffies(VIBRATING_MAX_INTERVAL)); + } else { + //Dedicated work queue may create failed, use default one. + schedule_delayed_work(&mot_actuator_fctrl.delay_work, msecs_to_jiffies(VIBRATING_MAX_INTERVAL)); + } + return 0; +} +EXPORT_SYMBOL(mot_actuator_on_vibrate_stop); + +static int32_t mot_actuator_handle_exit(uint32_t arg) +{ + int rc = 0; + + return rc; +} + +static int32_t mot_actuator_handle_write(uint32_t arg) +{ + int rc = 0; + + if (mot_actuator_state != MOT_ACTUATOR_INITED) { + pr_err("%s: mot actuator is not initiated!!", __func__); + return -EINVAL; + } + + return rc; +} + +static void mot_actuator_handle_release(void) +{ + if (mot_actuator_state == MOT_ACTUATOR_RELEASED) { + pr_err("%s: Already released.", __func__); + return; + } + + if (mot_actuator_state == MOT_ACTUATOR_INITED) { + pr_debug("Disable AF power!"); + //regulator_disable(afVdd); + //regulator_disable(ioVdd); + } + pr_debug("%s: Vsync released.", __func__); + mot_actuator_state = MOT_ACTUATOR_RELEASED; + return; +} + +static int32_t mot_actuator_handle_cmd( + struct v4l2_subdev *sd, + uint32_t arg, + unsigned int cmd) +{ + int32_t rc=0; + + switch (cmd) { + case MOT_ACTUATOR_INIT: + /* init */ + mot_actuator_init_runtime(); + pr_debug("%s: MOT_ACTUATOR_INIT ret:%d", __func__, rc); + break; + case MOT_ACTUATOR_READ: + /* read */ + pr_debug("%s: MOT_ACTUATOR_READ ret:%d", __func__, rc); + break; + case MOT_ACTUATOR_WRITE: + /* write */ + mot_actuator_handle_write(arg); + pr_debug("%s: MOT_ACTUATOR_WRITE ret:%d", __func__, rc); + break; + case MOT_ACTUATOR_EXIT: + /* exit */ + mot_actuator_handle_exit(arg); + pr_debug("%s: MOT_ACTUATOR_EXIT ret:%d", __func__, rc); + break; + case MOT_ACTUATOR_RELEASE: + /* release */ + mot_actuator_handle_release(); + pr_debug("%s: MOT_ACTUATOR_RELEASE ret:%d", __func__, rc); + break; + default: + pr_err("%s: Unknown command (%d)\n", __func__, cmd); + rc = -EINVAL; + break; + } + + return rc; +} + +static long mot_actuator_ioctl(struct v4l2_subdev *sd, + unsigned int cmd, void *arg) +{ + pr_debug("%s cmd=%x, arg=%x\n", __func__, cmd, *(int *)arg); + + switch (cmd) { + case MOT_ACTUATOR_READ: + case MOT_ACTUATOR_WRITE: + case MOT_ACTUATOR_INIT: + case MOT_ACTUATOR_EXIT: + case MOT_ACTUATOR_RELEASE: + return mot_actuator_handle_cmd(sd, *(int *)arg, cmd); + default: + pr_err("%s Unsupported cmd=%x, arg=%x\n", __func__, cmd, arg); + pr_debug("%s supported cmd: %x, %x, %x, %x, %x\n", __func__, + MOT_ACTUATOR_READ, + MOT_ACTUATOR_WRITE, + MOT_ACTUATOR_INIT, + MOT_ACTUATOR_EXIT, + MOT_ACTUATOR_RELEASE); + return -ENOIOCTLCMD; + } +} + +#ifdef CONFIG_COMPAT +static long mot_actuator_ioctl32(struct v4l2_subdev *sd, + unsigned int cmd, unsigned long arg) +{ + int cmd_data; + int32_t rc = 0; + + if (copy_from_user(&cmd_data, (void __user *)arg, + sizeof(cmd_data))) { + pr_err("Failed to copy from user_ptr=%pK size=%zu", (void __user *)arg, sizeof(cmd_data)); + return -EFAULT; + } + + pr_debug("%s cmd=%x, arg=%x\n", __func__, cmd, arg); + + switch (cmd) { + case MOT_ACTUATOR_READ32: + cmd = MOT_ACTUATOR_READ; + break; + case MOT_ACTUATOR_WRITE32: + cmd = MOT_ACTUATOR_WRITE; + break; + case MOT_ACTUATOR_INIT32: + cmd = MOT_ACTUATOR_INIT; + break; + case MOT_ACTUATOR_EXIT32: + cmd = MOT_ACTUATOR_EXIT; + break; + case MOT_ACTUATOR_RELEASE32: + cmd = MOT_ACTUATOR_RELEASE; + break; + default: + pr_err("%s Unsupported cmd=%x, arg=%x\n", __func__, cmd, arg); + pr_debug("%s supported cmd: %x, %x, %x, %x, %x\n", __func__, + MOT_ACTUATOR_READ32, + MOT_ACTUATOR_WRITE32, + MOT_ACTUATOR_INIT32, + MOT_ACTUATOR_EXIT32, + MOT_ACTUATOR_RELEASE32); + return -ENOIOCTLCMD; + } + + rc = mot_actuator_ioctl(sd, cmd, (void *)&cmd_data); + + return rc; +} +#endif + +static struct v4l2_subdev_core_ops mot_actuator_subdev_core_ops = { + .ioctl = mot_actuator_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl32 = mot_actuator_ioctl32, +#endif +}; + +static struct v4l2_subdev_ops mot_actuator_subdev_ops = { + .core = &mot_actuator_subdev_core_ops, +}; + +static const struct v4l2_subdev_internal_ops mot_actuator_internal_ops; + +static struct platform_device mot_actuator_device = { + .name = "mot_actuator", + .id = -1, +}; + +static void mot_actuator_delayed_process(struct work_struct *work) +{ + struct mot_actuator_ctrl_t *actuator_fctrl = container_of(work, + struct mot_actuator_ctrl_t, delay_work.work); + unsigned int consumers = 0; + int actuatorUsers = 0; + + mutex_lock(&actuator_fctrl->actuator_lock); + consumers = mot_actuator_get_consumers(); + if ((consumers & CLINET_VIBRATOR_MASK) != 0) { + actuatorUsers = mot_actuator_put(ACTUATOR_CLIENT_VIBRATOR); + } + if (mot_actuator_state >= MOT_ACTUATOR_INITED && mot_actuator_state < MOT_ACTUATOR_RELEASED) { + if ((consumers & (~CLINET_VIBRATOR_MASK)) == 0) { + //Only park lens when there's no other user holding actuator. + mot_actuator_park_lens(0); + } + mot_actuator_power_off(0); + mot_actuator_release_cci(0); + } + mot_actuator_state = MOT_ACTUATOR_RELEASED; + mutex_unlock(&actuator_fctrl->actuator_lock); +} + +static inline ssize_t msm_actuator_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t count = 0; + count = sprintf(buf, "\nmot_actuator_state: %d, device index: %d\n", mot_actuator_state, mot_device_index); + return count; +} + +static ssize_t msm_actuator_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + + if (kstrtouint(buf, 10, &input) != 0) { + retval = -EINVAL; + goto exit; + } + + if (input) { + CAM_DBG(CAM_ACTUATOR, "start actuator"); + mot_actuator_on_vibrate_start(); + } else { + CAM_DBG(CAM_ACTUATOR, "stop actuator"); + mot_actuator_on_vibrate_stop(); + } + retval = count; +exit: + return retval; +} + +//Tuning interface +static inline ssize_t mot_actuator_lens_park_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t count = 0; + count = sprintf(buf, "\n lens park pos: %d\n", lens_park_pos); + return count; +} + +static ssize_t mot_actuator_lens_park_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + + if (kstrtouint(buf, 10, &input) != 0) { + retval = -EINVAL; + goto exit; + } + + lens_park_pos = input; + + retval = count; +exit: + return retval; +} + +static inline ssize_t mot_actuator_safe_pos_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t count = 0; + count = sprintf(buf, "\n safe dac value steps: %d\n", lens_safe_pos_dac); + return count; +} + +static ssize_t mot_actuator_safe_pos_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + + if (kstrtouint(buf, 10, &input) != 0) { + retval = -EINVAL; + goto exit; + } + + lens_safe_pos_dac = input; + + retval = count; +exit: + return retval; +} + +static inline ssize_t mot_actuator_dump_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t count = 0; + count = mot_actuator_dump(buf); + return count; +} + +static ssize_t mot_actuator_dump_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return count; +} + + +static inline ssize_t mot_actuator_park_lens_table_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t count = 0; + int i; + count += sprintf(buf, "\n knee point step\n"); + for (i=0; i 0) { + for (index=0; indexv4l2_dev_str.internal_ops = &mot_actuator_internal_ops; + f_ctrl->v4l2_dev_str.ops = &mot_actuator_subdev_ops; + strlcpy(f_ctrl->device_name, MOT_ACTUATOR_NAME, sizeof(f_ctrl->device_name)); + f_ctrl->v4l2_dev_str.name = f_ctrl->device_name; + f_ctrl->v4l2_dev_str.sd_flags = + (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); + f_ctrl->v4l2_dev_str.ent_function = CAM_MOT_ACTUATOR_TYPE; + f_ctrl->v4l2_dev_str.token = f_ctrl; + + platform_device_register(&mot_actuator_device); + f_ctrl->v4l2_dev_str.pdev = &mot_actuator_device; + + f_ctrl->mot_actuator_wq = NULL; + f_ctrl->mot_actuator_wq = create_singlethread_workqueue("mot_actuator_wq"); + if (f_ctrl->mot_actuator_wq == NULL) { + pr_err("%s: create work queue failed!!!", __func__); + } + + INIT_DELAYED_WORK(&f_ctrl->delay_work, mot_actuator_delayed_process); + mutex_init(&f_ctrl->actuator_lock); + + {//Debug/tuning interfaces + int i; + for (i=0; iv4l2_dev_str.pdev->dev.kobj, + &mot_actuator_attrs[i].attr); + } + } + + rc = cam_register_subdev(&(f_ctrl->v4l2_dev_str)); + if (rc) + pr_err("%s: Fail with cam_register_subdev rc: %d", __func__, rc); + + return rc; +} + +int mot_actuator_driver_init(void) +{ + pr_debug("%s\n", __func__); + + mot_actuator_init_subdev(&mot_actuator_fctrl); + cam_select_actuator_by_device_name(); + return 0; +} + +void mot_actuator_driver_exit(void) +{ + pr_debug("%s\n", __func__); + + cancel_delayed_work_sync(&mot_actuator_fctrl.delay_work); + if (mot_actuator_fctrl.mot_actuator_wq != NULL) { + flush_workqueue(mot_actuator_fctrl.mot_actuator_wq); + destroy_workqueue(mot_actuator_fctrl.mot_actuator_wq); + mot_actuator_fctrl.mot_actuator_wq = NULL; + } + cam_unregister_subdev(&mot_actuator_fctrl.v4l2_dev_str); +} + +MODULE_DESCRIPTION("MOT ACTUATOR"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.h b/drivers/cam_sensor_module/cam_actuator/mot_actuator.h new file mode 100644 index 000000000000..1a70aead7e67 --- /dev/null +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.h @@ -0,0 +1,35 @@ +#ifndef __MOT_ACTUATOR_H__ +#define __MOT_ACTUATOR_H__ + +#include +#include +#define MOT_ACTUATOR_NAME "mot_actuator" + +#define MOT_ACTUATOR_READ \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 50, int) +#define MOT_ACTUATOR_READ32 \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 50, int) + +#define MOT_ACTUATOR_WRITE \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 51, int) +#define MOT_ACTUATOR_WRITE32 \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 51, int) + +#define MOT_ACTUATOR_INIT \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 52, int) +#define MOT_ACTUATOR_INIT32 \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 52, int) + +#define MOT_ACTUATOR_RELEASE \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 53, int) +#define MOT_ACTUATOR_RELEASE32 \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 53, int) + +#define MOT_ACTUATOR_EXIT \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 54, int) +#define MOT_ACTUATOR_EXIT32 \ + _IOWR('X', BASE_VIDIOC_PRIVATE + 54, int) + +int mot_actuator_driver_init(void); +void mot_actuator_driver_exit(void); +#endif /*__MOT_ACTUATOR_H__*/ diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.c new file mode 100644 index 000000000000..b979927c1c9b --- /dev/null +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "cam_debug_util.h" +#include "mot_actuator_policy.h" + +extern int mot_actuator_on_vibrate_start(void); +extern int mot_actuator_on_vibrate_stop(void); + +static atomic_t mot_actuator_ref_count = ATOMIC_INIT(0); +static unsigned long mot_actuator_consumers = ATOMIC_INIT(0); +static struct mutex actuator_res_lock = __MUTEX_INITIALIZER(actuator_res_lock); + +int mot_actuator_get(mot_actuator_client user) +{ + if (user <= ACTUATOR_CLIENT_INVALID || user >= ACTUATOR_CLIENT_MAX) { + CAM_ERR(CAM_ACTUATOR, "INVALID CLIENT!!!"); + return 0; + } + + CAM_DBG(CAM_ACTUATOR, "Obtain actuator from: %d", user); + + test_and_set_bit(user, &mot_actuator_consumers); + + return atomic_add_return(1, &mot_actuator_ref_count); +} +EXPORT_SYMBOL(mot_actuator_get); + +int mot_actuator_put(mot_actuator_client user) +{ + unsigned long consumers = 0; + if (user <= ACTUATOR_CLIENT_INVALID || user >= ACTUATOR_CLIENT_MAX) { + CAM_ERR(CAM_ACTUATOR, "INVALID CLIENT!!!"); + return 0; + } + + CAM_DBG(CAM_ACTUATOR, "Release actuator from: %d", user); + + test_and_clear_bit(user, &mot_actuator_consumers); + + consumers = mot_actuator_get_consumers(); + if (((consumers & CLINET_VIBRATOR_MASK) == CLINET_VIBRATOR_MASK) && + (user != ACTUATOR_CLIENT_VIBRATOR)) { + //If only vibrator noise eliminator exists, move lens to required position + CAM_DBG(CAM_ACTUATOR, "Set actuator pos for vibrator"); + mot_actuator_on_vibrate_start(); + if ((mot_actuator_get_consumers() & CLINET_VIBRATOR_MASK) == 0) { + mot_actuator_on_vibrate_stop(); + } + } + + return atomic_sub_return(1, &mot_actuator_ref_count); +} +EXPORT_SYMBOL(mot_actuator_put); + +int mot_actuator_get_ref_count(void) +{ + return atomic_read(&mot_actuator_ref_count); +} +EXPORT_SYMBOL(mot_actuator_get_ref_count); + +unsigned int mot_actuator_get_consumers(void) +{ + return mot_actuator_consumers; +} +EXPORT_SYMBOL(mot_actuator_get_consumers); + +void mot_actuator_lock(void) +{ + mutex_lock(&actuator_res_lock); +} +EXPORT_SYMBOL(mot_actuator_lock); + +void mot_actuator_unlock(void) +{ + mutex_unlock(&actuator_res_lock); +} +EXPORT_SYMBOL(mot_actuator_unlock); + +ssize_t mot_actuator_dump(char *buf) +{ + int item_len = 0; + unsigned int consumers = mot_actuator_get_consumers(); + + item_len += sprintf(buf+item_len, "refCount: %d\n", mot_actuator_get_ref_count()); + item_len += sprintf(buf+item_len, "Consumers (0x%x):\n", consumers); + + if (consumers & CLINET_CAMERA_MASK) { + item_len += sprintf(buf+item_len, "camera"); + } + + if (consumers & CLINET_VIBRATOR_MASK) { + item_len += sprintf(buf+item_len, " vibrator"); + } + + item_len += sprintf(buf+item_len, "\n"); + + CAM_DBG(CAM_ACTUATOR, "ref cnt:%d, consumers:0x%x", mot_actuator_get_ref_count(), mot_actuator_get_consumers()); + return item_len; +} +EXPORT_SYMBOL(mot_actuator_dump); diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.h b/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.h new file mode 100644 index 000000000000..3278546e0e3a --- /dev/null +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator_policy.h @@ -0,0 +1,20 @@ +#ifndef __MOT_ACTUATOR_POLICY_H__ +#define __MOT_ACTUATOR_POLICY_H__ + +typedef enum { + ACTUATOR_CLIENT_INVALID, + ACTUATOR_CLIENT_CAMERA, + ACTUATOR_CLIENT_VIBRATOR, + ACTUATOR_CLIENT_MAX +} mot_actuator_client; + +#define CLINET_CAMERA_MASK (0x01 << ACTUATOR_CLIENT_CAMERA) +#define CLINET_VIBRATOR_MASK (0x01 << ACTUATOR_CLIENT_VIBRATOR) + +int mot_actuator_get(mot_actuator_client user); +int mot_actuator_put(mot_actuator_client user); +void mot_actuator_lock(void); +void mot_actuator_unlock(void); +ssize_t mot_actuator_dump(char *buf); +unsigned int mot_actuator_get_consumers(void); +#endif /*__MOT_ACTUATOR_POLICY_H__*/ diff --git a/drivers/camera_main.c b/drivers/camera_main.c index f59be8dbe113..4e838c377473 100644 --- a/drivers/camera_main.c +++ b/drivers/camera_main.c @@ -20,6 +20,7 @@ #include "cam_cci_dev.h" #include "cam_sensor_dev.h" #include "cam_actuator_dev.h" +#include "mot_actuator.h" #include "cam_csiphy_dev.h" #include "cam_eeprom_dev.h" #include "cam_ois_dev.h" @@ -105,6 +106,7 @@ static const struct camera_submodule_component camera_sensor[] = { {&cam_cci_init_module, &cam_cci_exit_module}, {&cam_csiphy_init_module, &cam_csiphy_exit_module}, {&cam_actuator_driver_init, &cam_actuator_driver_exit}, + {&mot_actuator_driver_init, &mot_actuator_driver_exit}, {&cam_sensor_driver_init, &cam_sensor_driver_exit}, {&cam_eeprom_driver_init, &cam_eeprom_driver_exit}, {&cam_ois_driver_init, &cam_ois_driver_exit}, diff --git a/include/uapi/camera/media/cam_req_mgr.h b/include/uapi/camera/media/cam_req_mgr.h index 2ce529fdf82b..5d0700529652 100644 --- a/include/uapi/camera/media/cam_req_mgr.h +++ b/include/uapi/camera/media/cam_req_mgr.h @@ -32,6 +32,7 @@ #define CAM_CUSTOM_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 14) #define CAM_OPE_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 15) #define CAM_TFE_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 16) +#define CAM_MOT_ACTUATOR_TYPE (CAM_DEVICE_TYPE_BASE + 17) /* cam_req_mgr hdl info */ #define CAM_REQ_MGR_HDL_IDX_POS 8 From 9d023ce9770533f0dd2fb0cbb8d435f1c851f443 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Wed, 7 Apr 2021 15:47:20 +0800 Subject: [PATCH 07/86] cam: add macro CONFIG_AF_NOISE_ELIMINATION judgment -fix build error -only integrate mot_actuator driver on device which enabled CONFIG_AF_NOISE_ELIMINATION -modify dac_pos to 480,follow hanoip Change-Id: I7205cd01df239ede3c7a54609d4c8eb54f42eb87 Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1918702 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Dawei Wang Reviewed-by: Bolei Shang Reviewed-by: Ji Zhao Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_actuator/mot_actuator.c | 2 +- drivers/camera_main.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index e8fe296ca82d..03d2bd9f3591 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -197,7 +197,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .actuator_info = { [0] = { .actuator_type = MOT_ACTUATOR_DW9714, - .dac_pos = 400, + .dac_pos = 480, .cci_addr = 0x0c, .cci_dev = 0x01, .cci_master = 0x01, diff --git a/drivers/camera_main.c b/drivers/camera_main.c index 4e838c377473..d126491e8d28 100644 --- a/drivers/camera_main.c +++ b/drivers/camera_main.c @@ -20,7 +20,9 @@ #include "cam_cci_dev.h" #include "cam_sensor_dev.h" #include "cam_actuator_dev.h" +#ifdef CONFIG_AF_NOISE_ELIMINATION #include "mot_actuator.h" +#endif #include "cam_csiphy_dev.h" #include "cam_eeprom_dev.h" #include "cam_ois_dev.h" @@ -106,7 +108,9 @@ static const struct camera_submodule_component camera_sensor[] = { {&cam_cci_init_module, &cam_cci_exit_module}, {&cam_csiphy_init_module, &cam_csiphy_exit_module}, {&cam_actuator_driver_init, &cam_actuator_driver_exit}, +#ifdef CONFIG_AF_NOISE_ELIMINATION {&mot_actuator_driver_init, &mot_actuator_driver_exit}, +#endif {&cam_sensor_driver_init, &cam_sensor_driver_exit}, {&cam_eeprom_driver_init, &cam_eeprom_driver_exit}, {&cam_ois_driver_init, &cam_ois_driver_exit}, From b7b5e8bc55ead5e40f3614ce2cd680badc02d1ec Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Wed, 21 Apr 2021 11:25:02 +0800 Subject: [PATCH 08/86] cam: Add actuator standalone diver for berlin -To eliminate the resonance noise during system vibrator vibrating, set actuator to specified DAC position(480 on GT9772), then the resonance noise can be obviously improved. To achieve the conbination between vibrator and camera AF actuator,we implemnte: - Actuator separately control during camera power off. - Actuator policy to avoid vibrating disturb normal camera AF. - reinitialize when the safe_pos parameter is manually configured. Change-Id: I8f674eb441e8382f4de77acbca27179f8302139e Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1928778 Reviewed-by: Shuo Wang Tested-by: Jira Key Reviewed-by: Long Cheng SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 03d2bd9f3591..d76a8ec3cf4f 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -51,6 +51,7 @@ typedef enum { typedef enum { MOT_DEVICE_NIO, MOT_DEVICE_BERLNA, + MOT_DEVICE_BERLIN, MOT_DEVICE_NUM, } mot_dev_type; @@ -207,6 +208,23 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, }, + { + .dev_type = MOT_DEVICE_BERLIN, + .actuator_num = 1, + .dev_name = "berlin", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_GT9772, + .dac_pos = 480, + .cci_addr = 0x0c, + .cci_dev = 0x01, + .cci_master = 0x1, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .park_lens_needed = true, + }, + }, + }, }; static uint32_t mot_device_index = MOT_DEVICE_NUM; @@ -881,7 +899,8 @@ static ssize_t mot_actuator_safe_pos_store(struct device *dev, } lens_safe_pos_dac = input; - + //reinitialize when the safe_pos parameter is manually configured. + runtime_inited = false; retval = count; exit: return retval; From 50d0d3de28a6a942dbf2e4e7568e8d79d1bc8867 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Thu, 29 Apr 2021 20:38:33 +0800 Subject: [PATCH 09/86] cam: enable cci dump when meet cci fail [detail] Default enable cci register dump when meet NACK or Timeout issue. Change-Id: I4656f4eca644fb4a8a8274323b5943122e15df58 Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1936494 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Dawei Wang Reviewed-by: Shuo Wang Reviewed-by: Bolei Shang Reviewed-by: Peng Zhang Reviewed-by: Xingyun Fu Reviewed-by: Ji Zhao Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_cci/cam_cci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/cam_sensor_module/cam_cci/cam_cci_core.c index bf4a2b975121..bfeef7b381f2 100644 --- a/drivers/cam_sensor_module/cam_cci/cam_cci_core.c +++ b/drivers/cam_sensor_module/cam_cci/cam_cci_core.c @@ -212,7 +212,7 @@ void cam_cci_dump_registers(struct cci_device *cci_dev, uint32_t reg_offset = 0; void __iomem *base = cci_dev->soc_info.reg_map[0].mem_base; - dump_en = cci_dev->dump_en; + dump_en = cci_dev->dump_en = 6; if (!(dump_en & CAM_CCI_NACK_DUMP_EN) && !(dump_en & CAM_CCI_TIMEOUT_DUMP_EN)) { CAM_DBG(CAM_CCI, From 47c3f617f13c193d851e3b224347613b17e578be Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Fri, 14 May 2021 15:49:15 +0800 Subject: [PATCH 10/86] cam: update berlin gt9772 DAC value for resonance noise issue -According KP's request,update DAC value to 900 for gt9772 on berlin. -This value may cause a small hit noise when actuator power on during vibrating. Change-Id: If366e101d0319fda77458827f400d91ad06f83cc Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1949296 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Zilong Zhang Reviewed-by: Bolei Shang Reviewed-by: Dawei Wang Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_actuator/mot_actuator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index d76a8ec3cf4f..2599041ec19f 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -215,7 +215,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .actuator_info = { [0] = { .actuator_type = MOT_ACTUATOR_GT9772, - .dac_pos = 480, + .dac_pos = 900, .cci_addr = 0x0c, .cci_dev = 0x01, .cci_master = 0x1, From bc6fc504f949de8654f6f688fa70f5332c629546 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Wed, 19 May 2021 21:27:06 +0800 Subject: [PATCH 11/86] cam: add launch_lens method and some optimization -On berlin gt9772, according to KP's testing,safe DAC pose is 900, it's too close to the edge,and may cause a small tick noise.So use launch_lens to move lens step-by-step to reduce tick noise. -It may cause about 180ms delay to move lens to specify location. -This change just take effect during vibrating, don't affect normal camera. -add some delay after camera action,to allow lens to be pulled into position -try to init cci again when meet cci init failed on the first time. -change log level and add some debug method to debug low probability resonance noise issues on berlna Change-Id: I7188a5fe2a7697af19b6830fc82a5f99195b7c44 Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1954392 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Wang Liu Reviewed-by: Zhilong Wang Reviewed-by: Bolei Shang Reviewed-by: Darong Huang Reviewed-by: Xu Ji Reviewed-by: Jian Zhang Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 113 +++++++++++++++--- 1 file changed, 98 insertions(+), 15 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 2599041ec19f..62208176d7b8 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -60,6 +60,11 @@ typedef struct { uint16_t step; } mot_park_lens_step; +typedef struct { + uint16_t kneePoint; + uint16_t step; +} mot_launch_lens_step; + typedef struct { struct cam_sensor_i2c_reg_setting *init_setting; struct cam_sensor_i2c_reg_setting *dac_setting; @@ -74,6 +79,7 @@ typedef struct { char *regulator_list[REGULATOR_NUM]; uint32_t regulator_volt_uv[REGULATOR_NUM]; bool park_lens_needed; + bool launch_lens_needed; } mot_actuator_hw_info; typedef struct { @@ -83,7 +89,7 @@ typedef struct { mot_actuator_hw_info actuator_info[MAX_ACTUATOR_NUM]; } mot_dev_info; -/*Register settings of GT9767*/ //todo +/*Register settings of GT9767*/ static struct cam_sensor_i2c_reg_array mot_gt9767_init_setting[] ={ {0x02, 0x00, 300}, {0x06, 0x0A, 0}, @@ -137,7 +143,7 @@ static struct cam_sensor_i2c_reg_setting mot_gt9772_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; -/*Register settings of DW9714*/ //todo +/*Register settings of DW9714*/ static struct cam_sensor_i2c_reg_array mot_dw9714_init_setting[] ={ {0xED, 0xAB, 0}, {0x02, 0x01, 0}, @@ -147,7 +153,7 @@ static struct cam_sensor_i2c_reg_array mot_dw9714_init_setting[] ={ {0x08, 0x78, 0}, }; -static struct cam_sensor_i2c_reg_array mot_dw9714_dac_setting[] ={ //todo +static struct cam_sensor_i2c_reg_array mot_dw9714_dac_setting[] ={ {0x03, 0x3ff, 0} }; @@ -222,6 +228,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .regulator_list = {"ldo7", "ldo5"}, .regulator_volt_uv = {1800000, 2800000}, .park_lens_needed = true, + .launch_lens_needed = true, }, }, }, @@ -298,6 +305,7 @@ static int cam_select_actuator_by_device_name(void) /*=================ACTUATOR RUNTIME====================*/ #define VIBRATING_MAX_INTERVAL 2000//ms #define PARK_LENS_MAX_STAGES 10 +#define LAUNCH_LENS_MAX_STAGES 10 struct mot_actuator_ctrl_t { struct cam_subdev v4l2_dev_str; @@ -331,6 +339,11 @@ static mot_park_lens_step lens_park_table[PARK_LENS_MAX_STAGES] = { {300, 60}, {200, 40}, }; +static mot_launch_lens_step lens_launch_table[LAUNCH_LENS_MAX_STAGES] = { + {300, 300}, + {720, 60}, + {840, 40}, +}; static bool runtime_inited = 0; static int mot_actuator_init_runtime(void) @@ -436,7 +449,9 @@ static int32_t mot_actuator_power_on(uint32_t index) for (i = 0; i < REGULATOR_NUM; i++) { if (mot_actuator_runtime[index].regulators[i] != NULL) { ret = regulator_enable(mot_actuator_runtime[index].regulators[i]); - CAM_DBG(CAM_ACTUATOR, "power on ret %d", ret); + if(ret){ + CAM_ERR(CAM_ACTUATOR, "power on regulators[%d] failed, ret:%d", i,ret); + } } } @@ -460,12 +475,20 @@ static int32_t mot_actuator_power_off(uint32_t index) int32_t mot_actuator_init_cci(uint32_t index) { - int32_t ret = 0; + int32_t ret = 0,rc = 0; CAM_DBG(CAM_ACTUATOR, "init cci."); ret = camera_io_init(&mot_actuator_runtime[index].io_master); if (ret != 0) { - CAM_ERR(CAM_ACTUATOR, "init cci failed, ret=%d!!!", ret); + rc = camera_io_release(&mot_actuator_runtime[index].io_master); + CAM_ERR(CAM_ACTUATOR, "init cci failed!!! ret=%d,release rc=%d. try again!", ret, rc); + /*delay 100ms and try again*/ + usleep_range(100000, 100100); + ret = camera_io_init(&mot_actuator_runtime[index].io_master); + if (ret != 0) { + rc = camera_io_release(&mot_actuator_runtime[index].io_master); + CAM_ERR(CAM_ACTUATOR, "try again init cci failed!!! ret=%d, release rc=%d", ret, rc); + } } return ret; } @@ -482,6 +505,58 @@ int32_t mot_actuator_release_cci(uint32_t index) return ret; } +static int32_t mot_actuator_launch_lens(uint32_t index, uint32_t dac_value) +{ + uint32_t cur_len_pos = 0; + uint32_t last_len_pos = 0; + int stageIndex; + unsigned int consumers = 0; + int32_t ret = 0; + uint32_t lens_launch_pos = dac_value; + + while (cur_len_pos < lens_launch_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "Launch lens was broken by other actuator requests."); + break; + } + + for (stageIndex=0; stageIndex 0) { + cur_len_pos += lens_launch_table[stageIndex].step; + break; + } + } + + if (stageIndex == LAUNCH_LENS_MAX_STAGES && cur_len_pos < lens_launch_pos) { + cur_len_pos += 10; + } + + if(last_len_pos == cur_len_pos) + /*break the cycle when cur_len_pos didn't update*/ + break; + else + last_len_pos = cur_len_pos; + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "Launch Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos >= lens_launch_pos) { + /*For skipping the last delay*/ + CAM_DBG(CAM_ACTUATOR, "Launch lens done."); + break; + } + + usleep_range(10000, 12000); + } + + return ret; +} + static int32_t mot_actuator_vib_move_lens(uint32_t index) { int32_t ret = 0; @@ -498,7 +573,7 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (ret == 0) { ret = mot_actuator_apply_settings(&mot_actuator_runtime[index].io_master, mot_actuator_get_init_settings(index)); if (ret == 0) { - CAM_DBG(CAM_ACTUATOR, "init acutator sucess", ret); + CAM_WARN(CAM_ACTUATOR, "init acutator sucess", ret); mot_actuator_state = MOT_ACTUATOR_INITED; } else { mot_actuator_release_cci(index); @@ -518,7 +593,7 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) /*Move lens to the specified position.*/ unsigned int consumers = mot_actuator_get_consumers(); - CAM_DBG(CAM_ACTUATOR, "actuator consumers: %d", consumers); + CAM_WARN(CAM_ACTUATOR, "actuator consumers: %d", consumers); if ((consumers & CLINET_VIBRATOR_MASK) == 0) { mot_actuator_get(ACTUATOR_CLIENT_VIBRATOR); @@ -526,19 +601,27 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (consumers == 0) { /*Just move lens when camera off and before first vibrating*/ - ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*use launch_lens to move lens step-by-step,reduce TICK noise*/ + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens_needed == true) { + ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); + }else { + ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*delay 10~12ms to wait lens move to specify location*/ + usleep_range(10000, 12000); + } if (ret == 0) { - CAM_DBG(CAM_ACTUATOR, "actuator:%d is safe now, please start vibrating"); + CAM_WARN(CAM_ACTUATOR, "actuator is safe now, safe_dac_pos:%d, please start vibrating.", + mot_actuator_runtime[index].safe_dac_pos); } else { CAM_ERR(CAM_ACTUATOR, "write dac failed, ret=%d!!!", ret); } } else { - CAM_DBG(CAM_ACTUATOR, "actuator is already in position."); + CAM_WARN(CAM_ACTUATOR, "actuator is already in position."); } mot_actuator_state = MOT_ACTUATOR_STARTED; } else { - CAM_DBG(CAM_ACTUATOR, "May be already in position. state: %d ret=%d.", mot_actuator_state, ret); + CAM_WARN(CAM_ACTUATOR, "May be already in position. state: %d ret=%d.", mot_actuator_state, ret); } return ret; @@ -604,15 +687,15 @@ int mot_actuator_on_vibrate_start(void) } mutex_lock(&mot_actuator_fctrl.actuator_lock); if (is_exiting) { - CAM_WARN(CAM_ACTUATOR, "Wait 2~3ms to let CCI release done."); - usleep_range(2, 3); + CAM_WARN(CAM_ACTUATOR, "Wait 20~30us to let CCI release done."); + usleep_range(20, 30); } mot_actuator_vib_move_lens(0); mutex_unlock(&mot_actuator_fctrl.actuator_lock); end = ktime_get(); duration = ktime_sub(end, start); duration /= 1000; - CAM_DBG(CAM_ACTUATOR, "Move lens delay: %dus", duration); + CAM_WARN(CAM_ACTUATOR, "Move lens delay: %dus", duration); return 0; } EXPORT_SYMBOL(mot_actuator_on_vibrate_start); From 70cfea590dc622c1aca09be13d9ccb99ccf99f20 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Thu, 10 Jun 2021 21:32:37 +0800 Subject: [PATCH 12/86] cam: reduce launch_lens step,add judgement before init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.Reduces the number and length of launch_lens,to reduce delay of vibrating. -Optimize delay of vibrating,but it still have about 110ms delay. 2.Do not init actuator when camera APP is holding actuator. -Fix the wide camera image shaking issue when the phone was vibrating Change-Id: I7ee1c1a063cb6428d36544b6958e1b2f19f518ed Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1976594 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Darong Huang Reviewed-by: Jian Zhang Reviewed-by: Long Cheng Reviewed-by: Xingyun Fu Reviewed-by: Qiang Guo Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- .../cam_sensor_module/cam_actuator/mot_actuator.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 62208176d7b8..2e3788154aa2 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -341,8 +341,9 @@ static mot_park_lens_step lens_park_table[PARK_LENS_MAX_STAGES] = { }; static mot_launch_lens_step lens_launch_table[LAUNCH_LENS_MAX_STAGES] = { {300, 300}, - {720, 60}, - {840, 40}, + {700, 100}, + {820, 60}, + {900, 40}, }; static bool runtime_inited = 0; @@ -560,13 +561,19 @@ static int32_t mot_actuator_launch_lens(uint32_t index, uint32_t dac_value) static int32_t mot_actuator_vib_move_lens(uint32_t index) { int32_t ret = 0; + unsigned int consumers = 0; if (mot_device_index >= MOT_DEVICE_NUM || index > mot_dev_list[mot_device_index].actuator_num) { CAM_ERR(CAM_ACTUATOR, "INVALID device!!!"); return -1; } - if (mot_actuator_state <= MOT_ACTUATOR_IDLE || mot_actuator_state >= MOT_ACTUATOR_RELEASED) { + consumers = mot_actuator_get_consumers(); + CAM_DBG(CAM_ACTUATOR, "consumers=%d",consumers); + if (consumers & CLINET_CAMERA_MASK) { + /*Don't init actuator when camera on*/ + CAM_WARN(CAM_ACTUATOR, "Camera is holding actuator,don't init actuator for vibrator,consumers=%d",consumers); + } else if (mot_actuator_state <= MOT_ACTUATOR_IDLE || mot_actuator_state >= MOT_ACTUATOR_RELEASED) { mot_actuator_init_runtime(); mot_actuator_power_on(index); ret = mot_actuator_init_cci(index); @@ -591,8 +598,6 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (ret == 0 && mot_actuator_state == MOT_ACTUATOR_INITED) { /*Move lens to the specified position.*/ - unsigned int consumers = mot_actuator_get_consumers(); - CAM_WARN(CAM_ACTUATOR, "actuator consumers: %d", consumers); if ((consumers & CLINET_VIBRATOR_MASK) == 0) { From 216643ab5694bfe68bc51a47d9da3eb1353bece5 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Mon, 21 Jun 2021 16:06:12 +0800 Subject: [PATCH 13/86] cam: add wakelock for the actuator noise reduction. -Sometimes system will suspend during the delaywork. so add wakelock to ensure system is awake. -port from 1984717 Change-Id: Ie081d6d3e6642c7d6f77b2a1f3eb9a3d82c9f69c Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1985991 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhenxin Xi Reviewed-by: Long Cheng Reviewed-by: Zhuoran Xu Reviewed-by: Bolei Shang Reviewed-by: Shuo Wang Reviewed-by: Yongqin Wan Reviewed-by: Zhilong Wang Reviewed-by: Quanlin Zhu Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_actuator/mot_actuator.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 2e3788154aa2..6483f6976a28 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -27,6 +27,8 @@ #include "mot_actuator_policy.h" #include "cam_sensor_io.h" #include "cam_req_mgr_dev.h" +#include "linux/pm_wakeup.h" + /*=================ACTUATOR HW INFO====================*/ #define DEVICE_NAME_LEN 32 #define MAX_ACTUATOR_NUM 3 @@ -314,6 +316,7 @@ struct mot_actuator_ctrl_t { struct workqueue_struct *mot_actuator_wq; struct delayed_work delay_work; struct mutex actuator_lock; + struct wakeup_source actuator_wakelock; }; enum mot_actuator_state_e { @@ -686,6 +689,7 @@ int mot_actuator_on_vibrate_start(void) bool is_exiting = false; ktime_t start,end,duration; start = ktime_get(); + __pm_stay_awake(&mot_actuator_fctrl.actuator_wakelock); cancel_delayed_work(&mot_actuator_fctrl.delay_work); if (mutex_is_locked(&mot_actuator_fctrl.actuator_lock)) { is_exiting = true; @@ -907,6 +911,7 @@ static void mot_actuator_delayed_process(struct work_struct *work) } mot_actuator_state = MOT_ACTUATOR_RELEASED; mutex_unlock(&actuator_fctrl->actuator_lock); + __pm_relax(&actuator_fctrl->actuator_wakelock); } static inline ssize_t msm_actuator_show(struct device *dev, @@ -1097,6 +1102,9 @@ static int mot_actuator_init_subdev(struct mot_actuator_ctrl_t *f_ctrl) INIT_DELAYED_WORK(&f_ctrl->delay_work, mot_actuator_delayed_process); mutex_init(&f_ctrl->actuator_lock); + memset(&f_ctrl->actuator_wakelock, 0, sizeof(f_ctrl->actuator_wakelock)); + f_ctrl->actuator_wakelock.name = "actuator_hold_wl"; + wakeup_source_add(&f_ctrl->actuator_wakelock); {//Debug/tuning interfaces int i; @@ -1133,6 +1141,8 @@ void mot_actuator_driver_exit(void) mot_actuator_fctrl.mot_actuator_wq = NULL; } cam_unregister_subdev(&mot_actuator_fctrl.v4l2_dev_str); + __pm_relax(&mot_actuator_fctrl.actuator_wakelock); + wakeup_source_remove(&mot_actuator_fctrl.actuator_wakelock); } MODULE_DESCRIPTION("MOT ACTUATOR"); From 861c99535557ae73a86d53aabb9fd3732e5f3890 Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Wed, 23 Jun 2021 17:40:16 +0800 Subject: [PATCH 14/86] cam: add reset lens to reduce pop noise during quick-draw -when use quick-draw to open camera,vibrator will be trigger first,and mot_acatuator will power on and pull lens to specify DAC position, DAC is 900 on berlin.And then camera will take control of actuator and init actuator,this will cause lens fall back from a high position to a low position,it will cause a obvious hit noise. -This change will move lens back to low position step-by-step,befor camera take control of actuator. -It will cause about 38ms delay,will affect focus lock performance of opening tele camera after vibration. Change-Id: Icded21d8a863af79abcb9e9f98559757158d75ba Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1989392 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Long Cheng Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- .../cam_actuator/cam_actuator_core.c | 3 + .../cam_actuator/mot_actuator.c | 94 +++++++++++++++++++ .../cam_actuator/mot_actuator.h | 1 + 3 files changed, 98 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index cfa2f8e0d6a7..3d318d1ff30f 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -12,6 +12,7 @@ #include "cam_packet_util.h" #ifdef CONFIG_AF_NOISE_ELIMINATION #include "mot_actuator_policy.h" +#include "mot_actuator.h" #endif int32_t cam_actuator_construct_default_power_setting( @@ -602,6 +603,8 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, #ifdef CONFIG_AF_NOISE_ELIMINATION if (a_ctrl->cam_act_state == CAM_ACTUATOR_ACQUIRE && a_ctrl->is_multi_user_supported == true) { + /*exile vibrator when camera want to take control of actuator*/ + mot_actuator_handle_exile(); mot_actuator_get(ACTUATOR_CLIENT_CAMERA); } #endif diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 6483f6976a28..e3a5ab98449d 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -62,6 +62,11 @@ typedef struct { uint16_t step; } mot_park_lens_step; +typedef struct { + uint16_t kneePoint; + uint16_t step; +} mot_reset_lens_step; + typedef struct { uint16_t kneePoint; uint16_t step; @@ -81,6 +86,7 @@ typedef struct { char *regulator_list[REGULATOR_NUM]; uint32_t regulator_volt_uv[REGULATOR_NUM]; bool park_lens_needed; + bool reset_lens_needed; bool launch_lens_needed; } mot_actuator_hw_info; @@ -230,6 +236,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .regulator_list = {"ldo7", "ldo5"}, .regulator_volt_uv = {1800000, 2800000}, .park_lens_needed = true, + .reset_lens_needed = true, .launch_lens_needed = true, }, }, @@ -307,6 +314,7 @@ static int cam_select_actuator_by_device_name(void) /*=================ACTUATOR RUNTIME====================*/ #define VIBRATING_MAX_INTERVAL 2000//ms #define PARK_LENS_MAX_STAGES 10 +#define RESET_LENS_MAX_STAGES 10 #define LAUNCH_LENS_MAX_STAGES 10 struct mot_actuator_ctrl_t { @@ -342,6 +350,10 @@ static mot_park_lens_step lens_park_table[PARK_LENS_MAX_STAGES] = { {300, 60}, {200, 40}, }; +static mot_reset_lens_step lens_reset_table[RESET_LENS_MAX_STAGES] = { + {400, 0}, + {100, 100}, +}; static mot_launch_lens_step lens_launch_table[LAUNCH_LENS_MAX_STAGES] = { {300, 300}, {700, 100}, @@ -889,6 +901,88 @@ static struct platform_device mot_actuator_device = { .id = -1, }; +static int32_t mot_actuator_reset_lens(uint32_t index) +{ + uint32_t cur_len_pos = mot_actuator_runtime[index].safe_dac_pos; + int stageIndex; + unsigned int consumers = 0; + int32_t ret = 0; + + if (mot_dev_list[mot_device_index].actuator_info[index].reset_lens_needed == false) { + CAM_DBG(CAM_ACTUATOR, "reset lens is not needed."); + return 0; + } + /*The first step is to get back to a specify position,regardless of the step size*/ + if(cur_len_pos > lens_reset_table[0].kneePoint) + { + cur_len_pos = lens_reset_table[0].kneePoint; + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + usleep_range(10000, 12000); + } + while (cur_len_pos > lens_park_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "reset lens was broken by other actuator requests."); + break; + } + + for (stageIndex=1; stageIndex= lens_reset_table[stageIndex].kneePoint && lens_reset_table[stageIndex].step > 0) { + cur_len_pos -= lens_reset_table[stageIndex].step; + break; + } + } + + if (lens_reset_table[stageIndex].step <= 0 && cur_len_pos > lens_park_pos) { + cur_len_pos -= 10; + } + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "reset Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos <= lens_park_pos) { + /*For skipping the last delay*/ + CAM_DBG(CAM_ACTUATOR, "reset lens done."); + break; + } + usleep_range(10000, 12000); + } + return 0; +} + +void mot_actuator_handle_exile(void) +{ + unsigned int consumers = 0,ret = 0; + int actuatorUsers = 0; + ktime_t start,end,duration; + mutex_lock(&mot_actuator_fctrl.actuator_lock); + consumers = mot_actuator_get_consumers(); + /*Only reset lens when vibrator in consumer list*/ + if ((consumers & CLINET_VIBRATOR_MASK) != 0) { + actuatorUsers = mot_actuator_put(ACTUATOR_CLIENT_VIBRATOR); + start = ktime_get(); + if (mot_actuator_state >= MOT_ACTUATOR_INITED && mot_actuator_state < MOT_ACTUATOR_RELEASED) { + if ((consumers & (~CLINET_VIBRATOR_MASK)) == 0) { + //Only reset lens when there's no other user holding actuator. + CAM_DBG(CAM_ACTUATOR, "reset _lens_now"); + ret = mot_actuator_reset_lens(0); + } + mot_actuator_power_off(0); + mot_actuator_release_cci(0); + } + mot_actuator_state = MOT_ACTUATOR_RELEASED; + end = ktime_get(); + duration = ktime_sub(end, start); + duration /= 1000; + CAM_WARN(CAM_ACTUATOR, "reset lens delay: %dus", duration); + } + mutex_unlock(&mot_actuator_fctrl.actuator_lock); +} + +EXPORT_SYMBOL(mot_actuator_handle_exile); static void mot_actuator_delayed_process(struct work_struct *work) { struct mot_actuator_ctrl_t *actuator_fctrl = container_of(work, diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.h b/drivers/cam_sensor_module/cam_actuator/mot_actuator.h index 1a70aead7e67..d6d1699799a0 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.h +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.h @@ -30,6 +30,7 @@ #define MOT_ACTUATOR_EXIT32 \ _IOWR('X', BASE_VIDIOC_PRIVATE + 54, int) +void mot_actuator_handle_exile(void); int mot_actuator_driver_init(void); void mot_actuator_driver_exit(void); #endif /*__MOT_ACTUATOR_H__*/ From 121a965a521e424930903eed1e1d4ccb843816ab Mon Sep 17 00:00:00 2001 From: wangshuo18 Date: Wed, 26 May 2021 15:54:32 +0800 Subject: [PATCH 15/86] cam: support volt compatible for hm2sp03&hm2sd03 -On xpeng,rear main camera s5khm2 will have two type(SP03&SD03), we need set correct DVDD voltage for each sensor per module pin_20 value. -Use gpio_48 to read module pin_20 -1 means hm2SP03,DVDD is 1.1v. 0 means hm2SD03,DVDD is 1.05v. Change-Id: I119d9c17795867c84b21ff0e8afa6b69f0579778 Signed-off-by: wangshuo18 Reviewed-on: https://gerrit.mot.com/1960645 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Ji Zhao Reviewed-by: Bolei Shang Reviewed-by: Zhuoran Xu Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- drivers/cam_utils/cam_soc_util.c | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/cam_utils/cam_soc_util.c b/drivers/cam_utils/cam_soc_util.c index 93ff740d22aa..9cd2adf27571 100644 --- a/drivers/cam_utils/cam_soc_util.c +++ b/drivers/cam_utils/cam_soc_util.c @@ -1230,6 +1230,11 @@ static int cam_soc_util_get_dt_regulator_info { int rc = 0, count = 0, i = 0; struct device_node *of_node = NULL; +#ifdef CONFIG_CAMERA_VOLTAGE_COMPATIBLE + int idpin_gpio = 0, idpin_value = 0; + unsigned int second_vol_range[2]; + const char *rgltr_name = ""; +#endif if (!soc_info || !soc_info->dev) { CAM_ERR(CAM_UTIL, "Invalid parameters"); @@ -1294,6 +1299,63 @@ static int cam_soc_util_get_dt_regulator_info return -EINVAL; } +#ifdef CONFIG_CAMERA_VOLTAGE_COMPATIBLE + idpin_gpio = of_get_named_gpio(of_node, "volt-compat-gpio",0); + if (idpin_gpio < 0) { + CAM_ERR(CAM_UTIL, "Not volt-compat-gpio found ,gpio=%d",idpin_gpio); + } else { + if(gpio_is_valid(idpin_gpio)) { + if(!gpio_request(idpin_gpio,"volt-compat-gpio")) { + gpio_direction_input(idpin_gpio); + CAM_DBG(CAM_UTIL, "volt-compat-gpio:%d =%d ", idpin_gpio, gpio_get_value(idpin_gpio)); + + rc = of_property_read_u32_array(of_node, "volt-compat-range", second_vol_range, 2); + if (rc) { + CAM_ERR(CAM_UTIL, "No volt-compat-range found, rc=%d", rc); + gpio_free(idpin_gpio); + idpin_gpio = 0; + return -EINVAL; + } + + rc = of_property_read_string(of_node,"volt-compat-rgltr-name",&rgltr_name); + if (rc) { + CAM_ERR(CAM_UTIL, "No volt-compat-rgltr-name found, rc=%d", rc); + gpio_free(idpin_gpio); + idpin_gpio = 0; + return -EINVAL; + } + + rc = of_property_read_u32(of_node,"volt-compat-gpio-value",&idpin_value); + if (rc) { + CAM_ERR(CAM_UTIL, "No volt-compat-gpio-value found, rc=%d", rc); + gpio_free(idpin_gpio); + idpin_gpio = 0; + return -EINVAL; + } + + if(soc_info->index == 0 && idpin_gpio > 0) { + for (i = 0; i < soc_info->num_rgltr; i++) { + if((strcmp(soc_info->rgltr_name[i], rgltr_name)== 0)) { + int val = 1; + val = gpio_get_value(idpin_gpio); + if(val == idpin_value) { + soc_info->rgltr_min_volt [i]= second_vol_range[0]; + soc_info->rgltr_max_volt[i]= second_vol_range[1]; + } + CAM_ERR(CAM_UTIL, "cam:%d, %s, voltage range: min:%d max:%d", + soc_info->index,soc_info->rgltr_name[i], soc_info->rgltr_min_volt [i],soc_info->rgltr_max_volt[i]); + } + } + } + }else{ + CAM_ERR(CAM_UTIL, "volt-compat-gpio request failed"); + } + }else{ + CAM_ERR(CAM_UTIL, "volt-compat-gpio is not vaild"); + } + } +#endif + return rc; } From 59915db63d785bdea8566be1d545e6cb00aae3fb Mon Sep 17 00:00:00 2001 From: zhuql3 Date: Thu, 23 Sep 2021 13:34:40 +0800 Subject: [PATCH 16/86] Berlin:add ois data type Fixed the issue that the submission milan ois bringup caused the Berlin tele sensor not work Change-Id: Ib77132b7ef9785f717bb95a51ba758ab7d761851 Signed-off-by: zhuql3 Reviewed-on: https://gerrit.mot.com/2074029 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Xingyun Fu Reviewed-by: Zilong Zhang Reviewed-by: Qiang Guo Reviewed-by: Shanghui Zhang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_core.c | 5 +++-- drivers/cam_sensor_module/cam_ois/cam_ois_dev.h | 1 + include/uapi/camera/media/cam_sensor.h | 1 + 3 files changed, 5 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 c40c8ee47cc4..4cde98f2ba6f 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -339,6 +339,7 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->ois_fw_txn_data_sz = ois_info->ois_fw_txn_data_sz; o_ctrl->ois_fw_inc_addr = ois_info->ois_fw_inc_addr; o_ctrl->ois_fw_addr_type = ois_info->ois_fw_addr_type; + o_ctrl->ois_fw_data_type = ois_info->ois_fw_data_type; memcpy(o_ctrl->ois_name, ois_info->ois_name, OIS_NAME_LEN); o_ctrl->ois_name[OIS_NAME_LEN - 1] = '\0'; o_ctrl->io_master_info.cci_client->retries = 3; @@ -396,7 +397,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) txn_data_size = o_ctrl->ois_fw_txn_data_sz; i2c_reg_setting.addr_type = o_ctrl->ois_fw_addr_type; - i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_reg_setting.data_type = o_ctrl->ois_fw_data_type; i2c_reg_setting.delay = 0; txn_regsetting_size = sizeof(struct cam_sensor_i2c_reg_array) * txn_data_size; vaddr = vmalloc(txn_regsetting_size); @@ -476,7 +477,7 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) txn_data_size = o_ctrl->ois_fw_txn_data_sz; i2c_reg_setting.addr_type = o_ctrl->ois_fw_addr_type; - i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_reg_setting.data_type = o_ctrl->ois_fw_data_type; i2c_reg_setting.delay = 0; txn_regsetting_size = sizeof(struct cam_sensor_i2c_reg_array) * txn_data_size; vaddr = vmalloc(txn_regsetting_size); 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 27eb1af573cc..af7473d413e9 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -141,6 +141,7 @@ struct cam_ois_ctrl_t { uint8_t ois_fw_txn_data_sz; uint8_t ois_fw_inc_addr; uint8_t ois_fw_addr_type; + uint8_t ois_fw_data_type; struct cam_ois_opcode opcode; }; diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 9552d118387a..a4195326ea6c 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -143,6 +143,7 @@ struct cam_cmd_ois_info { __u8 ois_fw_txn_data_sz; __u8 ois_fw_inc_addr; __u8 ois_fw_addr_type; + __u8 ois_fw_data_type; char ois_name[MAX_OIS_NAME_SIZE]; struct cam_ois_opcode opcode; } __attribute__((packed)); From d972a0c95a34403ba60e52b1fe331b164b95737e Mon Sep 17 00:00:00 2001 From: Qiang Guo Date: Tue, 28 Sep 2021 19:02:44 +0800 Subject: [PATCH 17/86] camera: porting af noise elimination porting: (CR) camera: add mot actuator driver porting: (CR) corfu5g: add mot actuator driver Change-Id: Ic6a16d17f745129545a17af3cc2d68181de72009 Signed-off-by: Qiang Guo Reviewed-on: https://gerrit.mot.com/2078653 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shanghui Zhang Reviewed-by: Bolei Shang Reviewed-by: XiaoFeng Wang Reviewed-by: Quanlin Zhu Reviewed-by: Zhuoran Xu Reviewed-by: Ji Zhao Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 372 ++++++++++++++++-- drivers/camera_main.h | 8 + 2 files changed, 353 insertions(+), 27 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index e3a5ab98449d..2c289c232085 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -12,6 +12,7 @@ * */ #include +#include #include #include #include @@ -34,6 +35,7 @@ #define MAX_ACTUATOR_NUM 3 #define REGULATOR_NAME_MAX_LEN 32 #define ANDROIDBOOT_DEVICE_MAX_LEN 32 +#define LENS_MAX_STAGES 10 typedef enum { MOT_ACTUATOR_INVALID, @@ -41,6 +43,7 @@ typedef enum { MOT_ACTUATOR_GT9767 = MOT_ACTUATOR_FIRST, MOT_ACTUATOR_GT9772, MOT_ACTUATOR_DW9714, + MOT_ACTUATOR_DW9800V, MOT_ACTUATOR_NUM, } mot_actuator_type; @@ -54,6 +57,12 @@ typedef enum { MOT_DEVICE_NIO, MOT_DEVICE_BERLNA, MOT_DEVICE_BERLIN, + MOT_DEVICE_CYPFG, + MOT_DEVICE_CYPFQ, + MOT_DEVICE_CYPFR, + MOT_DEVICE_CORFUP, + MOT_DEVICE_CORFUQ, + MOT_DEVICE_CORFUR, MOT_DEVICE_NUM, } mot_dev_type; @@ -76,10 +85,15 @@ typedef struct { struct cam_sensor_i2c_reg_setting *init_setting; struct cam_sensor_i2c_reg_setting *dac_setting; } mot_actuator_settings; +typedef struct { + bool launch_lens_needed; + mot_launch_lens_step launch_lens_step[LENS_MAX_STAGES]; +} mot_launch_lens; typedef struct { mot_actuator_type actuator_type; uint16_t dac_pos; + uint16_t init_pos; uint16_t cci_addr; uint16_t cci_dev; uint16_t cci_master; @@ -87,7 +101,7 @@ typedef struct { uint32_t regulator_volt_uv[REGULATOR_NUM]; bool park_lens_needed; bool reset_lens_needed; - bool launch_lens_needed; + mot_launch_lens launch_lens; } mot_actuator_hw_info; typedef struct { @@ -179,12 +193,38 @@ static struct cam_sensor_i2c_reg_setting mot_dw9714_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; +/*Register settings of DW9800V*/ +static struct cam_sensor_i2c_reg_array mot_dw9800v_init_setting[] ={ + {0x02, 0x02, 300}, + {0x06, 0x80, 0}, + {0x07, 0x62, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_dw9800v_dac_setting[] ={ + {0x03, 0x3ff, 0} +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9800v_init_settings = { + .reg_setting = mot_dw9800v_init_setting, + .size = ARRAY_SIZE(mot_dw9800v_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_dw9800v_dac_settings = { + .reg_setting = mot_dw9800v_dac_setting, + .size = ARRAY_SIZE(mot_dw9800v_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + /*Register settings of all supported actuator types*/ static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { //MUST be sorted as definition order in above structure: mot_actuator_type {&mot_gt9767_init_settings, &mot_gt9767_dac_settings}, {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, {&mot_dw9714_init_settings, &mot_dw9714_dac_settings}, + {&mot_dw9800v_init_settings, &mot_dw9800v_dac_settings}, }; static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { @@ -237,7 +277,170 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .regulator_volt_uv = {1800000, 2800000}, .park_lens_needed = true, .reset_lens_needed = true, - .launch_lens_needed = true, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {300, 300}, + {700, 100}, + {820, 60}, + {900, 40}, + }, + }, + }, + }, + }, + { + .dev_type = MOT_DEVICE_CYPFG, + .actuator_num = 1, + .dev_name = "cypfg", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x0, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + + { + .dev_type = MOT_DEVICE_CYPFQ, + .actuator_num = 1, + .dev_name = "cypfq", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x0, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + + { + .dev_type = MOT_DEVICE_CYPFR, + .actuator_num = 1, + .dev_name = "cypfr", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x0, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + + { + .dev_type = MOT_DEVICE_CORFUP, + .actuator_num = 1, + .dev_name = "corfup", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + + { + .dev_type = MOT_DEVICE_CORFUQ, + .actuator_num = 1, + .dev_name = "corfuq", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + + { + .dev_type = MOT_DEVICE_CORFUR, + .actuator_num = 1, + .dev_name = "corfur", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"ldo7", "ldo5"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, }, }, }, @@ -315,7 +518,7 @@ static int cam_select_actuator_by_device_name(void) #define VIBRATING_MAX_INTERVAL 2000//ms #define PARK_LENS_MAX_STAGES 10 #define RESET_LENS_MAX_STAGES 10 -#define LAUNCH_LENS_MAX_STAGES 10 +#define LAUNCH_LENS_MAX_STAGES LENS_MAX_STAGES struct mot_actuator_ctrl_t { struct cam_subdev v4l2_dev_str; @@ -354,12 +557,7 @@ static mot_reset_lens_step lens_reset_table[RESET_LENS_MAX_STAGES] = { {400, 0}, {100, 100}, }; -static mot_launch_lens_step lens_launch_table[LAUNCH_LENS_MAX_STAGES] = { - {300, 300}, - {700, 100}, - {820, 60}, - {900, 40}, -}; + static bool runtime_inited = 0; static int mot_actuator_init_runtime(void) @@ -523,13 +721,21 @@ int32_t mot_actuator_release_cci(uint32_t index) static int32_t mot_actuator_launch_lens(uint32_t index, uint32_t dac_value) { - uint32_t cur_len_pos = 0; + uint32_t init_len_pos = mot_dev_list[mot_device_index].actuator_info[0].init_pos; + uint32_t cur_len_pos = init_len_pos; uint32_t last_len_pos = 0; int stageIndex; unsigned int consumers = 0; int32_t ret = 0; uint32_t lens_launch_pos = dac_value; + mot_launch_lens_step const *lens_launch_table = mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_step; + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == false) { + CAM_DBG(CAM_ACTUATOR, "Launch lens is not needed."); + return 0; + } + + // from 0 to safe_dac_pos while (cur_len_pos < lens_launch_pos) { consumers = mot_actuator_get_consumers(); if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { @@ -562,6 +768,47 @@ static int32_t mot_actuator_launch_lens(uint32_t index, uint32_t dac_value) } if (cur_len_pos >= lens_launch_pos) { + /*For skipping the last delay*/ + CAM_WARN(CAM_ACTUATOR, "Launch lens done."); + break; + } + + usleep_range(10000, 12000); + } + + // from 512 to 0 + while ((cur_len_pos > lens_launch_pos) && init_len_pos) { + consumers = mot_actuator_get_consumers(); + if ((consumers & (~CLINET_VIBRATOR_MASK)) != 0) { + CAM_WARN(CAM_ACTUATOR, "Launch lens was broken by other actuator requests."); + break; + } + + for (stageIndex = 0; stageIndex < LENS_MAX_STAGES; stageIndex++) { + if (lens_launch_table[stageIndex].kneePoint == 0 && lens_launch_table[stageIndex].step == 0) { + break; + } + + if (cur_len_pos >= lens_launch_table[stageIndex].kneePoint && lens_launch_table[stageIndex].step > 0) { + cur_len_pos -= lens_launch_table[stageIndex].step; + break; + } + } + + if (lens_launch_table[stageIndex].step == 0 && cur_len_pos > lens_launch_pos) { + cur_len_pos -= 10; + if (cur_len_pos < 10) + cur_len_pos = 0; + } + + ret = mot_actuator_move_lens_by_dac(index, cur_len_pos); + + if (ret < 0 ) { + CAM_ERR(CAM_ACTUATOR, "Launch Lens encounter CCI error, break now."); + break; + } + + if (cur_len_pos <= lens_launch_pos) { /*For skipping the last delay*/ CAM_DBG(CAM_ACTUATOR, "Launch lens done."); break; @@ -622,7 +869,7 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (consumers == 0) { /*Just move lens when camera off and before first vibrating*/ /*use launch_lens to move lens step-by-step,reduce TICK noise*/ - if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens_needed == true) { + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); }else { ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); @@ -896,11 +1143,6 @@ static struct v4l2_subdev_ops mot_actuator_subdev_ops = { static const struct v4l2_subdev_internal_ops mot_actuator_internal_ops; -static struct platform_device mot_actuator_device = { - .name = "mot_actuator", - .id = -1, -}; - static int32_t mot_actuator_reset_lens(uint32_t index) { uint32_t cur_len_pos = mot_actuator_runtime[index].safe_dac_pos; @@ -1172,9 +1414,10 @@ static struct device_attribute mot_actuator_attrs[] = { mot_actuator_dump_store), }; -static int mot_actuator_init_subdev(struct mot_actuator_ctrl_t *f_ctrl) +static int mot_actuator_init_subdev(struct device *dev, struct mot_actuator_ctrl_t *f_ctrl) { int rc = 0; + struct platform_device *pdev = to_platform_device(dev); f_ctrl->v4l2_dev_str.internal_ops = &mot_actuator_internal_ops; f_ctrl->v4l2_dev_str.ops = &mot_actuator_subdev_ops; @@ -1185,13 +1428,12 @@ static int mot_actuator_init_subdev(struct mot_actuator_ctrl_t *f_ctrl) f_ctrl->v4l2_dev_str.ent_function = CAM_MOT_ACTUATOR_TYPE; f_ctrl->v4l2_dev_str.token = f_ctrl; - platform_device_register(&mot_actuator_device); - f_ctrl->v4l2_dev_str.pdev = &mot_actuator_device; + f_ctrl->v4l2_dev_str.pdev = pdev; f_ctrl->mot_actuator_wq = NULL; f_ctrl->mot_actuator_wq = create_singlethread_workqueue("mot_actuator_wq"); if (f_ctrl->mot_actuator_wq == NULL) { - pr_err("%s: create work queue failed!!!", __func__); + CAM_ERR(CAM_ACTUATOR, "create work queue failed!!!"); } INIT_DELAYED_WORK(&f_ctrl->delay_work, mot_actuator_delayed_process); @@ -1210,23 +1452,35 @@ static int mot_actuator_init_subdev(struct mot_actuator_ctrl_t *f_ctrl) rc = cam_register_subdev(&(f_ctrl->v4l2_dev_str)); if (rc) - pr_err("%s: Fail with cam_register_subdev rc: %d", __func__, rc); + CAM_ERR(CAM_ACTUATOR, "Fail with cam_register_subdev rc: %d", rc); return rc; } -int mot_actuator_driver_init(void) +static int mot_actuator_component_bind(struct device *dev, + struct device *master_dev, void *data) { - pr_debug("%s\n", __func__); + CAM_WARN(CAM_ACTUATOR,"enter"); - mot_actuator_init_subdev(&mot_actuator_fctrl); + (void)master_dev; + (void)data; + + mot_actuator_init_subdev(dev, &mot_actuator_fctrl); cam_select_actuator_by_device_name(); + + CAM_WARN(CAM_ACTUATOR,"exit"); + return 0; } -void mot_actuator_driver_exit(void) +static void mot_actuator_component_unbind(struct device *dev, + struct device *master_dev, void *data) { - pr_debug("%s\n", __func__); + CAM_WARN(CAM_ACTUATOR,"enter"); + + (void)dev; + (void)master_dev; + (void)data; cancel_delayed_work_sync(&mot_actuator_fctrl.delay_work); if (mot_actuator_fctrl.mot_actuator_wq != NULL) { @@ -1237,7 +1491,71 @@ void mot_actuator_driver_exit(void) cam_unregister_subdev(&mot_actuator_fctrl.v4l2_dev_str); __pm_relax(&mot_actuator_fctrl.actuator_wakelock); wakeup_source_remove(&mot_actuator_fctrl.actuator_wakelock); + + CAM_WARN(CAM_ACTUATOR,"exit"); } -MODULE_DESCRIPTION("MOT ACTUATOR"); +const static struct component_ops mot_actuator_component_ops = { + .bind = mot_actuator_component_bind, + .unbind = mot_actuator_component_unbind, +}; + +static int32_t mot_actuator_platform_remove( + struct platform_device *pdev) +{ + component_del(&pdev->dev, &mot_actuator_component_ops); + return 0; +} + +static const struct of_device_id mot_actuator_driver_dt_match[] = { + {.compatible = "mot,actuator"}, + {} +}; + +static int32_t mot_actuator_driver_platform_probe( + struct platform_device *pdev) +{ + int rc = 0; + + CAM_DBG(CAM_ACTUATOR, "Adding sensor actuator component"); + rc = component_add(&pdev->dev, &mot_actuator_component_ops); + if (rc) + CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc); + + return rc; +} + +MODULE_DEVICE_TABLE(of, mot_actuator_driver_dt_match); + +struct platform_driver mot_actuator_platform_driver = { + .probe = mot_actuator_driver_platform_probe, + .driver = { + .name = "mot,actuator", + .owner = THIS_MODULE, + .of_match_table = mot_actuator_driver_dt_match, + .suppress_bind_attrs = true, + }, + .remove = mot_actuator_platform_remove, +}; + +int mot_actuator_driver_init(void) +{ + int32_t rc = 0; + + rc = platform_driver_register(&mot_actuator_platform_driver); + if (rc < 0) { + CAM_ERR(CAM_ACTUATOR, + "platform_driver_register failed rc = %d", rc); + return rc; + } + + return rc; +} + +void mot_actuator_driver_exit(void) +{ + platform_driver_unregister(&mot_actuator_platform_driver); +} + +MODULE_DESCRIPTION("mot_actuator_driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/camera_main.h b/drivers/camera_main.h index 4cc6a6ae3e57..7bcd829d6df8 100644 --- a/drivers/camera_main.h +++ b/drivers/camera_main.h @@ -41,6 +41,9 @@ extern struct platform_driver cam_ois_platform_driver; IS_REACHABLE(CONFIG_LEDS_QTI_FLASH) extern struct platform_driver cam_flash_platform_driver; #endif +#ifdef CONFIG_AF_NOISE_ELIMINATION +extern struct platform_driver mot_actuator_platform_driver; +#endif #endif #ifdef CONFIG_SPECTRA_ICP extern struct platform_driver cam_a5_driver; @@ -102,6 +105,7 @@ static struct platform_driver *const cam_component_drivers[] = { &cci_driver, &csiphy_driver, &cam_actuator_platform_driver, + &cam_sensor_platform_driver, &cam_eeprom_platform_driver, &cam_ois_platform_driver, @@ -109,6 +113,10 @@ static struct platform_driver *const cam_component_drivers[] = { IS_REACHABLE(CONFIG_LEDS_QTI_FLASH) &cam_flash_platform_driver, #endif +#ifdef CONFIG_AF_NOISE_ELIMINATION + &mot_actuator_platform_driver, +#endif + #endif #ifdef CONFIG_SPECTRA_ICP &cam_a5_driver, From d43c0f4f90faff6b4c61c3763649ec74e4dda237 Mon Sep 17 00:00:00 2001 From: Qiang Guo Date: Tue, 28 Sep 2021 18:02:51 +0800 Subject: [PATCH 18/86] camera: porting dw9781c ois porting: (CR) milanf: dw9781c ois bringup Change-Id: Ibc40c253f4e4d04df41feeda4af41829b53e906c Signed-off-by: Qiang Guo Reviewed-on: https://gerrit.mot.com/2078610 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shanghui Zhang Reviewed-by: Bolei Shang Reviewed-by: XiaoFeng Wang Reviewed-by: Quanlin Zhu Reviewed-by: Zhuoran Xu Reviewed-by: Ji Zhao Submit-Approved: Jira Key --- drivers/Makefile | 1 + .../cam_sensor_module/cam_ois/cam_ois_core.c | 64 +++- .../cam_ois/cam_ois_dw9781.c | 324 ++++++++++++++++++ 3 files changed, 381 insertions(+), 8 deletions(-) create mode 100644 drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c diff --git a/drivers/Makefile b/drivers/Makefile index c2349c1f090e..47797e2972cb 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -162,6 +162,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \ cam_sensor_module/cam_ois/cam_ois_dev.o \ cam_sensor_module/cam_ois/cam_ois_core.o \ cam_sensor_module/cam_ois/cam_ois_soc.o \ + cam_sensor_module/cam_ois/cam_ois_dw9781.o \ cam_sensor_module/cam_sensor/cam_sensor_dev.o \ cam_sensor_module/cam_sensor/cam_sensor_core.o \ cam_sensor_module/cam_sensor/cam_sensor_soc.o \ 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 4cde98f2ba6f..165376ff152f 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -15,6 +15,9 @@ #include "cam_common_util.h" #include "cam_packet_util.h" +extern int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); +extern void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); + int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) { @@ -302,6 +305,13 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, i2c_list->i2c_settings.addr_type, i2c_list->i2c_settings.data_type, i2c_list->i2c_settings.reg_setting[i].delay); + if (rc == 1) { + CAM_ERR(CAM_OIS, + "i2c poll fails addr:data %x:%x", + i2c_list->i2c_settings.reg_setting[i].reg_addr, + i2c_list->i2c_settings.reg_setting[i].reg_data); + return rc; + } if (rc < 0) { CAM_ERR(CAM_OIS, "i2c poll apply setting Fail"); @@ -390,6 +400,15 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) return rc; } + if (strstr(o_ctrl->ois_name, "dw9781")) { + if (!dw9781c_check_fw_download(&(o_ctrl->io_master_info), fw->data, fw->size)) { + CAM_INFO(CAM_OIS, "Skip firmware download."); + release_firmware(fw); + return 0; + } + CAM_INFO(CAM_OIS, "Firmware download started."); + } + total_bytes = fw->size; if(o_ctrl->ois_fw_txn_data_sz == 0) txn_data_size = total_bytes; @@ -407,31 +426,55 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) return -ENOMEM; } + CAM_DBG(CAM_OIS, "fw len: %d, addr_type: %d, data_type: %d, chunck: %d, ois_fw_data_type:%d", total_bytes, + i2c_reg_setting.addr_type, + i2c_reg_setting.data_type, + txn_data_size, + o_ctrl->ois_fw_data_type); + i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) (vaddr); for (total_idx = 0, ptr = (uint8_t *)fw->data; total_idx < total_bytes;) { - for(packet_idx = 0; - (packet_idx < txn_data_size) && (total_idx + packet_idx < total_bytes); - packet_idx++, ptr++) + for (packet_idx = 0; + (packet_idx < (txn_data_size/o_ctrl->ois_fw_data_type)) && (total_idx + (packet_idx*o_ctrl->ois_fw_data_type) < total_bytes); + packet_idx ++, ptr += o_ctrl->ois_fw_data_type) { int regAddrOffset = 0; if(o_ctrl->ois_fw_inc_addr == 1) - regAddrOffset = total_idx + packet_idx; + regAddrOffset = total_idx/o_ctrl->ois_fw_data_type + packet_idx; i2c_reg_setting.reg_setting[packet_idx].reg_addr = o_ctrl->opcode.prog + regAddrOffset; - i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + if (o_ctrl->ois_fw_data_type == CAMERA_SENSOR_I2C_TYPE_WORD) { + i2c_reg_setting.reg_setting[packet_idx].reg_data = (uint32_t)(*ptr << 8) | *(ptr+1); + } else { + i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + } i2c_reg_setting.reg_setting[packet_idx].delay = 0; i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; + CAM_DBG(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", + i2c_reg_setting.reg_setting[packet_idx].reg_addr, + i2c_reg_setting.reg_setting[packet_idx].reg_data, + (ptr-(uint8_t *)fw->data)); } i2c_reg_setting.size = packet_idx; - rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), - &i2c_reg_setting, 1); + if (o_ctrl->ois_fw_inc_addr == 1) { + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 0); + } else { + rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 1); + } if (rc < 0) { CAM_ERR(CAM_OIS, "OIS FW download failed %d", rc); goto release_firmware; } - total_idx += packet_idx; + total_idx += packet_idx*o_ctrl->ois_fw_data_type; + CAM_DBG(CAM_OIS, "packet_idx: %d, total_idx: %d", packet_idx, total_idx); + } + + if (strstr(o_ctrl->ois_name, "dw9781")) { + dw9781_post_firmware_download(&(o_ctrl->io_master_info), fw->data, fw->size); } release_firmware: @@ -461,6 +504,11 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) return -EINVAL; } + if (strstr(o_ctrl->ois_name, "dw9781")) { + CAM_DBG(CAM_OIS, "not need download coeff fw!"); + return 0; + } + snprintf(name_coeff, 32, "%s.coeff", o_ctrl->ois_name); fw_name_coeff = name_coeff; diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c new file mode 100644 index 000000000000..752920e203c3 --- /dev/null +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2021 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "cam_ois_core.h" +#include "cam_ois_soc.h" +#include "cam_sensor_util.h" +#include "cam_debug_util.h" +#include "cam_common_util.h" + +#define DW9781C_CHIP_ID_ADDRESS 0x7000 +#define DW9781C_CHECKSUM_ADDRESS 0x7007 +#define DW9781C_CHIP_ID 0x9781 +#define FW_VER_CURR_ADDR 0x7001 +#define FW_TYPE_ADDR 0x700D +#define SET_FW 0x8001 + +#define EOK 0 + +#define FW_VERSION_OFFSET 10235 +#define FW_CHECKSUM_OFFSET 10234 + +typedef struct +{ + unsigned int driverIc; + unsigned int size; + const uint16_t *fwContentPtr; + uint16_t version; + uint16_t checksum; +} FirmwareContex; + +static FirmwareContex g_dw9781FirmwareContext; + +static int32_t dw9781_cci_write(struct camera_io_master * io_master_info, uint16_t reg, uint16_t val) +{ + int32_t rc = 0; + struct cam_sensor_i2c_reg_array reg_setting; + struct cam_sensor_i2c_reg_setting wr_setting; + + reg_setting.reg_addr = reg; + reg_setting.reg_data = val; + reg_setting.delay = 0; + reg_setting.data_mask = 0; + wr_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD; + wr_setting.data_type = CAMERA_SENSOR_I2C_TYPE_WORD; + wr_setting.reg_setting = ®_setting; + wr_setting.size = 1; + wr_setting.delay = 0; + rc = camera_io_dev_write(io_master_info, &wr_setting); + return rc; +} + +static int32_t dw9781_cci_read(struct camera_io_master * io_master_info, uint16_t reg, uint16_t *val) +{ + int32_t rc = 0; + uint32_t regVal = 0; + rc = camera_io_dev_read(io_master_info, reg, ®Val, CAMERA_SENSOR_I2C_TYPE_WORD, CAMERA_SENSOR_I2C_TYPE_WORD); + if (!rc) { + *val = (uint16_t)regVal; + } + return rc; +} + +static void dw9781_delay_ms(uint32_t ms) +{ + usleep_range(ms*1000, ms*1000+10); + return; +} + +void dw9781_ois_reset(struct camera_io_master * io_master_info) +{ + CAM_DBG(CAM_OIS, "[dw9781c_ois_reset] ois reset"); + dw9781_cci_write(io_master_info, 0xD002, 0x0001); /* DW9781_DBGc reset */ + dw9781_delay_ms(4); + dw9781_cci_write(io_master_info, 0xD001, 0x0001); /* Active mode (DSP ON) */ + dw9781_delay_ms(25); /* ST gyro - over wait 25ms, default Servo On */ + dw9781_cci_write(io_master_info, 0xEBF1, 0x56FA); /* User protection release */ +} + +void dw9781_ois_ready_check(struct camera_io_master * io_master_info) +{ + uint16_t fw_flag; + dw9781_cci_write(io_master_info, 0xD001, 0x0000); /* dsp off mode */ + dw9781_cci_write(io_master_info, 0xFAFA, 0x98AC); /* All protection(1) */ + dw9781_cci_write(io_master_info, 0xF053, 0x70BD); /* All protection(2) */ + dw9781_cci_read(io_master_info, 0xA7F9, &fw_flag); /* check checksum flag */ + CAM_DBG(CAM_OIS, "[dw9781c_ois_ready_check] checksum flag : 0x%04x", fw_flag); + if(fw_flag == 0xCC33) + { + CAM_DBG(CAM_OIS, "[dw9781c_ois_ready_check] checksum flag is ok"); + dw9781_ois_reset(io_master_info); /* ois reset */ + } else { + dw9781_cci_write(io_master_info, 0xD002, 0x0001); /* dw9781c reset */ + dw9781_delay_ms(4); + CAM_ERR(CAM_OIS, "[dw9781c_ois_ready_check] previous firmware download fail"); + } +} + +void dw9781_all_protection_release(struct camera_io_master * io_master_info) +{ + CAM_DBG(CAM_OIS, "[dw9781c_all_protection_release] execution"); + /* release all protection */ + dw9781_cci_write(io_master_info, 0xFAFA, 0x98AC); + dw9781_delay_ms(1); + dw9781_cci_write(io_master_info, 0xF053, 0x70BD); + dw9781_delay_ms(1); +} + +static uint16_t dw9781_fw_checksum_verify(struct camera_io_master * io_master_info) +{ + uint16_t data; + + /* FW checksum command */ + dw9781_cci_write(io_master_info, 0x7011, 0x2000); + /* command start */ + dw9781_cci_write(io_master_info, 0x7010, 0x8000); + dw9781_delay_ms(10); + /* calc the checksum to write the 0x7005 */ + dw9781_cci_read(io_master_info, 0x7005, &data); + CAM_DBG(CAM_OIS, "F/W Checksum calculated value : 0x%04X", data); + + return data; +} + +static int dw9781_erase_mtp_rewritefw(struct camera_io_master * io_master_info) +{ + CAM_DBG(CAM_OIS, "dw9781c erase for rewritefw starting.."); + + /* 512 byte page */ + dw9781_cci_write(io_master_info, 0xde03, 0x0027); + /* page erase */ + dw9781_cci_write(io_master_info, 0xde04, 0x0008); + dw9781_delay_ms(10); + + CAM_DBG(CAM_OIS, "dw9781c checksum flag erase : 0xCC33"); + return 0; +} + +static void dw9781_erase_mtp(struct camera_io_master * io_master_info) +{ + CAM_DBG(CAM_OIS, "[dw9781c_erase_mtp] start erasing firmware flash"); + /* 12c level adjust */ + dw9781_cci_write(io_master_info, 0xd005, 0x0001); + dw9781_cci_write(io_master_info, 0xdd03, 0x0002); + dw9781_cci_write(io_master_info, 0xdd04, 0x0002); + + /* 4k Sector_0 Erase*/ + dw9781_cci_write(io_master_info, 0xde03, 0x0000); + dw9781_cci_write(io_master_info, 0xde04, 0x0002); + dw9781_delay_ms(10); + /* 4k Sector_1 Erase*/ + dw9781_cci_write(io_master_info, 0xde03, 0x0008); + dw9781_cci_write(io_master_info, 0xde04, 0x0002); + dw9781_delay_ms(10); + /* 4k Sector_2 Erase*/ + dw9781_cci_write(io_master_info, 0xde03, 0x0010); + dw9781_cci_write(io_master_info, 0xde04, 0x0002); + dw9781_delay_ms(10); + /* 4k Sector_3 Erase*/ + dw9781_cci_write(io_master_info, 0xde03, 0x0018); + dw9781_cci_write(io_master_info, 0xde04, 0x0002); + dw9781_delay_ms(10); + /* 4k Sector_4 Erase*/ + dw9781_cci_write(io_master_info, 0xde03, 0x0020); + dw9781_cci_write(io_master_info, 0xde04, 0x0002); + dw9781_delay_ms(10); + CAM_DBG(CAM_OIS, "[dw9781c_erase_mtp] complete erasing firmware flash"); +} + +static int dw9781_prepare_fw_download(struct camera_io_master * io_master_info) +{ + /* step 1: MTP Erase and DSP Disable for firmware 0x8000 write */ + /* step 2: MTP setup */ + /* step 3: firmware sequential write to flash */ + /* step 4: firmware sequential read from flash */ + /* step 5: firmware verify */ + dw9781_cci_write(io_master_info, 0xd001, 0x0000); + dw9781_all_protection_release(io_master_info); + dw9781_erase_mtp(io_master_info); + CAM_DBG(CAM_OIS, "[dw9781c_download_fw] start firmware download"); + return 0; +} + +int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize) +{ + uint8_t ret; + uint8_t needDownload = 0; + uint16_t fwchecksum = 0; + uint16_t first_chip_id = 0; + uint16_t chip_checksum = 0; + uint16_t second_chip_id = 0; + uint16_t fw_version_current = 0; + uint16_t fw_version_latest = 0; + + if (io_master_info == NULL) { + printk("FATAL: OIS CCI context error!!!"); + return -1; + } + + if (fwData == NULL || fwSize < FW_VERSION_OFFSET*sizeof(uint16_t)) { + printk("FATAL: firmware buffer(%p) is NULL or size(%d) abnormal!!!", fwData, fwSize); + return -1; + } + + g_dw9781FirmwareContext.driverIc = 0x9781; + g_dw9781FirmwareContext.fwContentPtr = (const uint16_t *)fwData; + g_dw9781FirmwareContext.size = fwSize; + g_dw9781FirmwareContext.version = *(g_dw9781FirmwareContext.fwContentPtr+FW_VERSION_OFFSET); + g_dw9781FirmwareContext.version = ((g_dw9781FirmwareContext.version << 8) & 0xff00) | + ((g_dw9781FirmwareContext.version >> 8) & 0xff); + g_dw9781FirmwareContext.checksum = *(g_dw9781FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET); + g_dw9781FirmwareContext.checksum = ((g_dw9781FirmwareContext.checksum << 8) & 0xff00) | + ((g_dw9781FirmwareContext.checksum >> 8) & 0xff); + + dw9781_ois_ready_check(io_master_info); + + dw9781_cci_read(io_master_info, DW9781C_CHIP_ID_ADDRESS, &first_chip_id); + dw9781_cci_read(io_master_info, 0x7001, &chip_checksum); + CAM_DBG(CAM_OIS, "[dw9781c] FW_VER_PHONE_MAKER : 0x%x", chip_checksum); + dw9781_cci_read(io_master_info, 0x7002, &chip_checksum); + CAM_DBG(CAM_OIS, "[dw9781c] FW_DATE_PHONE_MAKER : 0x%x", chip_checksum); + + CAM_DBG(CAM_OIS, "[dw9781c] first_chip_id : 0x%x", first_chip_id); + if (first_chip_id != DW9781C_CHIP_ID) { /* first_chip_id verification failed */ + dw9781_all_protection_release(io_master_info); + dw9781_cci_read(io_master_info, 0xd060, &second_chip_id); /* second_chip_id: 0x0020 */ + if ( second_chip_id == 0x0020 ) /* Check the second_chip_id*/ + { + CAM_DBG(CAM_OIS, "[dw9781c] start flash download:: size:%d, version:0x%x", + g_dw9781FirmwareContext.size, g_dw9781FirmwareContext.version); + needDownload = 1; + ret = dw9781_prepare_fw_download(io_master_info); /* Need to forced update OIS firmware again. */ + } else { + dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */ + CAM_ERR(CAM_OIS, "[dw9781c] second_chip_id check fail"); + CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode"); + return needDownload; + } + } else { + + + dw9781_cci_read(io_master_info, FW_VER_CURR_ADDR, &fw_version_current); + fw_version_latest = g_dw9781FirmwareContext.version; /*Firmware version read from file content.*/ + + CAM_DBG(CAM_OIS, "[dw9781c] fw_version_current = 0x%x, fw_version_latest = 0x%x", + fw_version_current, fw_version_latest); + + /* download firmware, check if need update, download firmware to flash */ + if (((fw_version_current & 0xFF) != (fw_version_latest & 0xFF))) { + + fwchecksum = dw9781_fw_checksum_verify(io_master_info); + if(fwchecksum != g_dw9781FirmwareContext.checksum) + { + needDownload = 1; + CAM_DBG(CAM_OIS, "[dw9781c] firmware checksum error 0x%04X, 0x%04X", + g_dw9781FirmwareContext.checksum, fwchecksum); + } + + if (needDownload) + { + CAM_DBG(CAM_OIS, "[dw9781c] start flash download:: size:%d, version:0x%x needDownload %d", + g_dw9781FirmwareContext.size, g_dw9781FirmwareContext.version, needDownload); + + ret = dw9781_prepare_fw_download(io_master_info); + CAM_DBG(CAM_OIS, "[dw9781c] flash download::vendor_dw9781c"); + if (ret != EOK) { + dw9781_erase_mtp_rewritefw(io_master_info); + dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shut download mode */ + CAM_ERR(CAM_OIS, "[dw9781c] firmware download error, ret = 0x%x", ret); + CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode"); + needDownload = 1; + } + } else { + CAM_DBG(CAM_OIS, "[dw9781c] ois firmware version is updated, skip download"); + } + } else { + CAM_DBG(CAM_OIS, "[dw9781c] ois firmware version is updated, skip download"); + } + } + return needDownload; +} +EXPORT_SYMBOL(dw9781c_check_fw_download); + +void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize) +{ + uint16_t fwchecksum = 0; + + g_dw9781FirmwareContext.checksum = *(g_dw9781FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET); + g_dw9781FirmwareContext.checksum = ((g_dw9781FirmwareContext.checksum << 8) & 0xff00) | + ((g_dw9781FirmwareContext.checksum >> 8) & 0xff); + + dw9781_ois_ready_check(io_master_info); + + fwchecksum = dw9781_fw_checksum_verify(io_master_info); + if(fwchecksum != g_dw9781FirmwareContext.checksum) + { + CAM_ERR(CAM_OIS, "[dw9781c] firmware checksum error 0x%04X, 0x%04X", g_dw9781FirmwareContext.checksum, fwchecksum); + dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */ + dw9781_delay_ms(100); + dw9781_cci_write(io_master_info, 0xd000, 0x0001); /* Standby mode */ + dw9781_delay_ms(100); + dw9781_all_protection_release(io_master_info); /* Disable write protect */ + dw9781_erase_mtp_rewritefw(io_master_info); + dw9781_cci_write(io_master_info, 0xd000, 0x0000); /* Shutdown mode */ + CAM_ERR(CAM_OIS, "[dw9781c] firmware download error"); + CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode"); + } else { + CAM_DBG(CAM_OIS, "[dw9781c] Firmware download succes..."); + } + + return; +} + +EXPORT_SYMBOL(dw9781_post_firmware_download); From bd291b65f4e6de2747a254c536ef1274566d446a Mon Sep 17 00:00:00 2001 From: Qiang Guo Date: Tue, 28 Sep 2021 17:52:56 +0800 Subject: [PATCH 19/86] camera: porting flashlight modify porting: (CR) corfup:flashlight working abnormally porting: (CR) corfur: flashlight auto turn off Change-Id: I097f481394cf74bb7497a373078d3391a9748252 Signed-off-by: Qiang Guo Reviewed-on: https://gerrit.mot.com/2078599 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Bolei Shang Reviewed-by: Shanghui Zhang Reviewed-by: XiaoFeng Wang Reviewed-by: Quanlin Zhu Reviewed-by: Zhuoran Xu Reviewed-by: Ji Zhao Submit-Approved: Jira Key --- .../cam_flash/cam_flash_core.c | 94 ++++++++++++++++++- .../cam_flash/cam_flash_dev.c | 5 +- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 8c747c0cae8e..ba6677363f8f 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -15,6 +15,50 @@ static uint default_on_timer = 2; module_param(default_on_timer, uint, 0644); +static int flash_initstate = 0; +static struct i2c_settings_list* i2c_flash_off = NULL; +static struct i2c_settings_list* + cam_flash_get_i2c_ptr(struct i2c_settings_list *pi2c_list) +{ + struct i2c_settings_list *tmp; + struct cam_sensor_i2c_reg_array *i2c_reg_settings = + pi2c_list->i2c_settings.reg_setting; + uint32_t size = pi2c_list->i2c_settings.size; + int i = 0; + + tmp = kzalloc(sizeof(struct i2c_settings_list), GFP_KERNEL); + if (tmp == NULL) { + CAM_WARN(CAM_FLASH, "kzalloc failed"); + return NULL; + } + + tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *) + vzalloc(size * sizeof(struct cam_sensor_i2c_reg_array)); + if (tmp->i2c_settings.reg_setting == NULL) { + kfree(tmp); + CAM_WARN(CAM_FLASH, "vzalloc failed"); + return NULL; + } + + tmp->i2c_settings.size = size; + tmp->op_code = pi2c_list->op_code; + tmp->i2c_settings.addr_type = pi2c_list->i2c_settings.addr_type; + tmp->i2c_settings.data_type = pi2c_list->i2c_settings.data_type; + + for( i = 0; i < size ; i++ ) { + tmp->i2c_settings.reg_setting[i].reg_addr = + i2c_reg_settings[i].reg_addr; + tmp->i2c_settings.reg_setting[i].reg_data = + i2c_reg_settings[i].reg_data; + tmp->i2c_settings.reg_setting[i].data_mask = + i2c_reg_settings[i].data_mask; + tmp->i2c_settings.reg_setting[i].delay = + i2c_reg_settings[i].delay; + } + + return tmp; +} + int cam_flash_led_prepare(struct led_trigger *trigger, int options, int *max_current, bool is_wled) { @@ -289,6 +333,7 @@ int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl, int i = 0; uint32_t cancel_req_id_found = 0; struct i2c_settings_array *i2c_set = NULL; + struct i2c_settings_list *i2c_list = NULL; if (!fctrl) { CAM_ERR(CAM_FLASH, "Device data is NULL"); @@ -309,6 +354,17 @@ int cam_flash_i2c_flush_request(struct cam_flash_ctrl *fctrl, continue; if (i2c_set->is_settings_valid == 1) { + list_for_each_entry(i2c_list, + &(i2c_set->list_head), list) { + rc = cam_sensor_util_i2c_apply_setting( + &(fctrl->io_master_info), + i2c_list); + if (rc) { + CAM_ERR(CAM_FLASH, + "Failed to apply settings: %d", + rc); + } + } rc = delete_request(i2c_set); if (rc < 0) CAM_ERR(CAM_FLASH, @@ -479,6 +535,14 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl) "cannot apply streamoff settings"); } } + + if(i2c_flash_off) + { + CAM_DBG(CAM_FLASH, "i2c Flash OFF Triggered"); + cam_sensor_util_i2c_apply_setting(&(flash_ctrl->io_master_info), + i2c_flash_off); + } + return 0; } @@ -705,6 +769,8 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl, CAM_DBG(CAM_FLASH, "req_id=%llu", req_id); if (req_id == 0) { /* NonRealTime Init settings*/ + + if (fctrl->apply_streamoff == true) { fctrl->apply_streamoff = false; i2c_set = &fctrl->i2c_data.streamoff_settings; @@ -721,6 +787,9 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl, break; } } else if (fctrl->i2c_data.init_settings.is_settings_valid == true) { + if(flash_initstate) + goto config_setting; + list_for_each_entry(i2c_list, &(fctrl->i2c_data.init_settings.list_head), list) { @@ -742,8 +811,14 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl, rc); return rc; } + + if((NULL != i2c_list) && (NULL == i2c_flash_off)) { + i2c_flash_off = cam_flash_get_i2c_ptr(i2c_list); + } } + flash_initstate = CAM_FLASH_STATE_CONFIG; } +config_setting: /* NonRealTime (Widget/RER/INIT_FIRE settings) */ if (fctrl->i2c_data.config_settings.is_settings_valid == true) { list_for_each_entry(i2c_list, @@ -1230,7 +1305,12 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) CAM_DBG(CAM_FLASH, "settings already valid"); i2c_reg_settings->request_id = 0; i2c_reg_settings->is_settings_valid = false; - goto update_req_mgr; + //goto update_req_mgr; + rc = delete_request(i2c_reg_settings); + if (rc) { + CAM_ERR(CAM_FLASH, "Error deleting req: %d", rc); + return rc; + } } i2c_reg_settings->is_settings_valid = true; i2c_reg_settings->request_id = @@ -1907,6 +1987,18 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl) } } + if(i2c_flash_off != NULL) + { + if(i2c_flash_off->i2c_settings.reg_setting != NULL) { + vfree(i2c_flash_off->i2c_settings.reg_setting); + i2c_flash_off->i2c_settings.reg_setting = NULL; + } + + kfree(i2c_flash_off); + i2c_flash_off = NULL; + flash_initstate = 0; + } + if (fctrl->bridge_intf.device_hdl != 1) { rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl); if (rc) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index cc57a7124ae9..6334d2acdce1 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -482,8 +482,9 @@ static int cam_flash_component_bind(struct device *dev, rc = cam_sensor_util_init_gpio_pin_tbl(soc_info, &fctrl->power_info.gpio_num_info); if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) { - CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs"); - return -EINVAL; + //CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs"); + //return -EINVAL; + CAM_WARN(CAM_FLASH, "No/Error Flash GPIOs"); } rc = cam_sensor_util_regulator_powerup(soc_info); if (rc < 0) { From 074580ba46685ae10400fd0d976b5213dbb41080 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 17 Nov 2021 10:43:46 +0800 Subject: [PATCH 20/86] camera: add probe sub-device probe sub-device after probe sensor. sub-device could be eeprom/actuator/i2c flash. Change-Id: I4773a55bb80aa17b873e5f5022db1a44dfed5580 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2118615 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Shuo Wang Reviewed-by: Xingyun Fu Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 64 +++++++++++++++++++ .../cam_sensor/cam_sensor_dev.h | 6 ++ include/uapi/camera/media/cam_sensor.h | 6 ++ 3 files changed, 76 insertions(+) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index d8db350e033d..83578c81c00b 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -444,6 +444,14 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sensor_probe_addr_type = probe_info->addr_type; s_ctrl->sensor_probe_data_type = probe_info->data_type; + + s_ctrl->probe_sub_device = probe_info->probe_sub_device; + s_ctrl->sub_device_addr = probe_info->sub_device_addr; + s_ctrl->sub_device_data_type = probe_info->sub_device_data_type; + s_ctrl->sub_device_addr_type = probe_info->sub_device_addr_type; + s_ctrl->sub_device_id_addr = probe_info->sub_device_id_addr; + s_ctrl->expected_sub_device_id = probe_info->expected_sub_device_id; + CAM_DBG(CAM_SENSOR, "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x", s_ctrl->sensordata->slave_info.sensor_id_reg_addr, @@ -703,6 +711,54 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) return rc; } +int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) +{ + int rc = 0; + uint32_t sub_device_id = 0; + uint16_t sensor_address = 0; + + /* if hal doesn't config ProbeSubDevice parameter in sensor xml, return success immediately */ + if (!s_ctrl->probe_sub_device) { + return 0; + } + + /* save sensor i2c address */ + sensor_address = s_ctrl->io_master_info.cci_client->sid; + + /* set sub-device i2c address */ + if (s_ctrl->sub_device_addr) { + s_ctrl->io_master_info.cci_client->sid = s_ctrl->sub_device_addr >> 1; + } + + rc = camera_io_dev_read( + &(s_ctrl->io_master_info), + s_ctrl->sub_device_id_addr, + &sub_device_id, + s_ctrl->sub_device_addr_type, + s_ctrl->sub_device_data_type); + + CAM_INFO(CAM_SENSOR, "Read sub device id: 0x%x expected sub device id 0x%x:", + sub_device_id, s_ctrl->expected_sub_device_id); + + if (sub_device_id == s_ctrl->expected_sub_device_id) { + CAM_INFO(CAM_SENSOR, + "Probe sub device success,slot:%d,sub_device_addr:0x%x,sub_device_id:0x%x", + s_ctrl->soc_info.index, + s_ctrl->sub_device_addr, + s_ctrl->expected_sub_device_id); + rc = 0; + } + else { + CAM_ERR(CAM_SENSOR, "Probe sub device fail"); + rc = -EINVAL; + } + + /* restore sensor i2c address */ + s_ctrl->io_master_info.cci_client->sid = sensor_address; + + return rc; +} + int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, void *arg) { @@ -785,6 +841,14 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto free_power_settings; } + /* Match sub-device ID */ + rc = cam_sensor_match_sub_device_id(s_ctrl); + if (rc < 0) { + cam_sensor_power_down(s_ctrl); + msleep(20); + goto free_power_settings; + } + CAM_INFO(CAM_SENSOR, "Probe success,slot:%d,slave_addr:0x%x,sensor_id:0x%x", s_ctrl->soc_info.index, diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index 8586ce51c87f..c132b0a3846d 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -111,6 +111,12 @@ struct cam_sensor_ctrl_t { bool bob_pwm_switch; uint32_t last_flush_req; uint16_t pipeline_delay; + uint8_t probe_sub_device; + uint16_t sub_device_addr; + uint8_t sub_device_data_type; + uint8_t sub_device_addr_type; + uint16_t sub_device_id_addr; + uint16_t expected_sub_device_id; }; /** diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index a4195326ea6c..49cb7da7cdfd 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -172,6 +172,12 @@ struct cam_cmd_probe { __u32 data_mask; __u16 camera_id; __u16 reserved; + __u8 probe_sub_device; + __u32 sub_device_addr; + __u8 sub_device_data_type; + __u8 sub_device_addr_type; + __u32 sub_device_id_addr; + __u32 expected_sub_device_id; } __attribute__((packed)); /** From 09e1a7c0af38920368cd0451b8a2ac8f4764724a Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 19 Aug 2021 18:09:50 +0800 Subject: [PATCH 21/86] camera: ope: remove perframe log [detail] remove perframe cam ope log Change-Id: I5f5f2da761646fbf5a4ccc926b0b479bb2ef69c6 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2046072 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Zhenxin Xi Submit-Approved: Jira Key (cherry picked from commit 937376377ba9bf6cfc400dfeba61b3333ad46179) Reviewed-on: https://gerrit.mot.com/2128266 Reviewed-by: Zhichao Chen --- drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c b/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c index 9f16f0f48084..0bd8a844c297 100644 --- a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c +++ b/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c @@ -3299,7 +3299,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv, prepare_args->priv = ctx_data->req_list[request_idx]; prepare_args->pf_data->packet = packet; prepare_args->pf_data->req = ope_req; - CAM_INFO(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch); + CAM_DBG(CAM_REQ, "OPE req %x num_batch %d", ope_req, ope_req->num_batch); ope_req->hang_data.packet = packet; ktime_get_boottime_ts64(&ts); ctx_data->last_req_time = (uint64_t)((ts.tv_sec * 1000000000) + From 680078aeec90010e9847c844f42529fe568085fd Mon Sep 17 00:00:00 2001 From: huaqin90 Date: Fri, 3 Dec 2021 11:44:34 +0800 Subject: [PATCH 22/86] Rhodep: flash bring up(1/2) details: flash bring up Change-Id: Ic076ca9324f3ab0a0e83493484c14529ae3677b3 Signed-off-by: huaqin90 Reviewed-on: https://gerrit.mot.com/2134124 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Ying Xu Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- config/holicamera.conf | 1 + config/holicameraconf.h | 1 + drivers/Makefile | 1 + .../cam_flash/cam_flash_core.c | 49 ++++++++- .../cam_flash/cam_flash_dev.c | 4 + .../cam_flash/cam_flash_dev.h | 3 + .../cam_flash/cam_flash_soc.c | 26 +++++ .../cam_flash_pm6125_gpio/pm6125_flash_gpio.c | 100 ++++++++++++++++++ .../cam_flash_pm6125_gpio/pm6125_flash_gpio.h | 21 ++++ .../cam_res_mgr/cam_res_mgr.c | 4 +- .../cam_res_mgr/cam_res_mgr_api.h | 12 +++ drivers/camera_main.c | 4 + 12 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c create mode 100644 drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h diff --git a/config/holicamera.conf b/config/holicamera.conf index 85bc1dae00c6..a74f301e76c5 100644 --- a/config/holicamera.conf +++ b/config/holicamera.conf @@ -9,4 +9,5 @@ export CONFIG_SPECTRA_ISP=y export CONFIG_SPECTRA_OPE=y export CONFIG_SPECTRA_TFE=y export CONFIG_SPECTRA_SENSOR=y +export CONFIG_CAMERA_FLASH_PWM=y endif diff --git a/config/holicameraconf.h b/config/holicameraconf.h index 958fe154c124..1141c53aea4e 100644 --- a/config/holicameraconf.h +++ b/config/holicameraconf.h @@ -8,3 +8,4 @@ #define CONFIG_SPECTRA_OPE 1 #define CONFIG_SPECTRA_TFE 1 #define CONFIG_SPECTRA_SENSOR 1 +#define CONFIG_CAMERA_FLASH_PWM 1 diff --git a/drivers/Makefile b/drivers/Makefile index 47797e2972cb..ffcafe6fcbe6 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -171,6 +171,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \ cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.o \ cam_sensor_module/cam_sensor_io/cam_sensor_spi.o \ cam_sensor_module/cam_sensor_utils/cam_sensor_util.o \ + cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.o \ cam_sensor_module/cam_res_mgr/cam_res_mgr.o ifneq (,$(filter $(CONFIG_AF_NOISE_ELIMINATION), y m)) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index ba6677363f8f..7dc82ebe73cc 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -12,6 +12,11 @@ #include "cam_packet_util.h" #include +#ifdef CONFIG_CAMERA_FLASH_PWM +#include "cam_sensor_util.h" +#include "../cam_flash_pm6125_gpio/pm6125_flash_gpio.h" +#endif + static uint default_on_timer = 2; module_param(default_on_timer, uint, 0644); @@ -517,6 +522,11 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl) { int rc = 0; +#ifdef CONFIG_CAMERA_FLASH_PWM + struct cam_hw_soc_info soc_info = flash_ctrl->soc_info; + struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private; +#endif + if (!flash_ctrl) { CAM_ERR(CAM_FLASH, "Flash control Null"); return -EINVAL; @@ -542,7 +552,12 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl) cam_sensor_util_i2c_apply_setting(&(flash_ctrl->io_master_info), i2c_flash_off); } - +#ifdef CONFIG_CAMERA_FLASH_PWM + CAM_ERR(CAM_SENSOR,"cam_flash_off"); + cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0); + cam_res_mgr_gpio_free(soc_info.dev, soc_private->flash_gpio_enable); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND,1); +#endif return 0; } @@ -552,6 +567,11 @@ static int cam_flash_low( { int i = 0, rc = 0; +#ifdef CONFIG_CAMERA_FLASH_PWM + struct cam_hw_soc_info soc_info = flash_ctrl->soc_info; + struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private; +#endif + if (!flash_data) { CAM_ERR(CAM_FLASH, "Flash Data Null"); return -EINVAL; @@ -568,6 +588,17 @@ static int cam_flash_low( if (rc) CAM_ERR(CAM_FLASH, "Fire Torch failed: %d", rc); +#ifdef CONFIG_CAMERA_FLASH_PWM + CAM_ERR(CAM_FLASH, "Flash low Triggered"); + rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1"); + if(rc) { + CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable); + return rc; + } + cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, (u64)flash_data->led_current_ma[0]*10000/1500); +#endif + return rc; } @@ -577,6 +608,11 @@ static int cam_flash_high( { int i = 0, rc = 0; +#ifdef CONFIG_CAMERA_FLASH_PWM + struct cam_hw_soc_info soc_info = flash_ctrl->soc_info; + struct cam_flash_private_soc *soc_private = (struct cam_flash_private_soc *)soc_info.soc_private; +#endif + if (!flash_data) { CAM_ERR(CAM_FLASH, "Flash Data Null"); return -EINVAL; @@ -593,6 +629,17 @@ static int cam_flash_high( if (rc) CAM_ERR(CAM_FLASH, "Fire Flash Failed: %d", rc); +#ifdef CONFIG_CAMERA_FLASH_PWM + CAM_ERR(CAM_FLASH, "Flash high Triggered"); + rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1"); + if(rc) { + CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable); + return rc; + } + cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 1); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, (u64)flash_data->led_current_ma[0]*10000/1500); +#endif + return rc; } diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index 6334d2acdce1..323497be3b90 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -142,6 +142,10 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP"); flash_cap.slot_info = fctrl->soc_info.index; flash_cap.flash_type = soc_private->flash_type; + CAM_DBG(CAM_FLASH, "dts flash_type is %d, it should same with camx&chi flash_type", soc_private->flash_type); +#ifdef CONFIG_CAMERA_FLASH_PWM + CAM_DBG(CAM_FLASH, "get flash_enabel_gpio %d", soc_private->flash_gpio_enable); +#endif for (i = 0; i < fctrl->flash_num_sources; i++) { flash_cap.max_current_flash[i] = soc_private->flash_max_current[i]; diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h index f5437c93a843..8f76d5e8173e 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h @@ -153,6 +153,9 @@ struct cam_flash_private_soc { uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS]; bool is_wled_flash; uint32_t flash_type; +#ifdef CONFIG_CAMERA_FLASH_PWM + uint32_t flash_gpio_enable; +#endif }; struct cam_flash_func_tbl { diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c index 9eac7a8b8aaf..d5f3f1ca6572 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c @@ -70,6 +70,10 @@ static int32_t cam_get_source_node_info( struct device_node *flash_src_node = NULL; struct device_node *torch_src_node = NULL; struct device_node *switch_src_node = NULL; +#ifdef CONFIG_CAMERA_FLASH_PWM + int16_t gpio_array_size = 0; + uint16_t *gpio_array = NULL; +#endif soc_private->is_wled_flash = of_property_read_bool(of_node, "wled-flash-support"); @@ -79,7 +83,29 @@ static int32_t cam_get_source_node_info( CAM_ERR(CAM_FLASH, "flash-type read failed rc=%d", rc); soc_private->flash_type = CAM_FLASH_TYPE_PMIC; // default to PMIC flash +#ifdef CONFIG_CAMERA_FLASH_PWM + } else if(soc_private->flash_type == CAM_FLASH_TYPE_GPIO) { + gpio_array_size = of_gpio_count(of_node); + if (gpio_array_size == 1){ + gpio_array = kcalloc(gpio_array_size, sizeof(uint16_t), GFP_KERNEL); + if (!gpio_array) { + CAM_ERR(CAM_FLASH, "flash gpio array alloc fail"); + } else { + for (i = 0; i < gpio_array_size; i++) { + gpio_array[i] = of_get_gpio(of_node, i); + CAM_DBG(CAM_FLASH, "flash dts gpio_array[%d] = %d name is %s %s", i, gpio_array[i], of_node->name, of_node->full_name); + } + soc_private->flash_gpio_enable = gpio_array[0]; + CAM_DBG(CAM_FLASH, "flash gpio enable %d",soc_private->flash_gpio_enable); + kfree(gpio_array); + } + } else { + CAM_ERR(CAM_FLASH, "flash should have two gpio, first is enable in flash dts, second control by flash pm6125"); + } } +#else + } +#endif switch_src_node = of_parse_phandle(of_node, "switch-source", 0); if (!switch_src_node) { diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c new file mode 100644 index 000000000000..b1adf43a8d60 --- /dev/null +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c @@ -0,0 +1,100 @@ +/* + *Copyright (C) 2021 Motorola Mobility LLC, + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pm6125_flash_gpio.h" + + + +/***************************************************************************** + * Data Structure + *****************************************************************************/ + +struct pwm_device *pwm; + +/***************************************************************************** + * Function + *****************************************************************************/ + +void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, u64 flash_current){ + struct pwm_state pstate; + int rc = 0; + pwm_get_state(pwm, &pstate); + pstate.period = 50000; + pstate.duty_cycle = 500000*flash_current/10000; + switch(s){ + case PM6125_FLASH_GPIO_STATE_ACTIVE: + pstate.enabled = true; + rc = pwm_apply_state(pwm, &pstate); + break; + case PM6125_FLASH_GPIO_STATE_SUSPEND: + pstate.enabled = false; + rc = pwm_apply_state(pwm, &pstate); + break; + default: + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to control PWM use a err state!\n"); + } + + if(rc < 0) { + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Apply PWM state fail, rc = %d", rc); + } +} + +static int pm6125_flash_pwm_probe(struct platform_device *pdev) +{ + int rc = 0; + pwm = devm_pwm_get(&pdev->dev, NULL); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + return rc; +} + +static const struct of_device_id gpio_of_match[] = { + { .compatible = "qualcomm,pm6125_flash_gpio", }, + {}, +}; + +static struct platform_driver pm6125_flash_gpio_platform_driver = { + .probe = pm6125_flash_pwm_probe, + .driver = { + .name = "PM6125_FLASH_GPIO_DTS", + .of_match_table = gpio_of_match, + }, +}; + +int pm6125_flash_gpio_init_module(void) +{ + if (platform_driver_register(&pm6125_flash_gpio_platform_driver)) { + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to register pm6125_flash_gpio_platform_driver!\n"); + return -1; + } + return 0; +} + +void pm6125_flash_gpio_exit_module(void) +{ + platform_driver_unregister(&pm6125_flash_gpio_platform_driver); +} + +MODULE_AUTHOR("liyang "); +MODULE_DESCRIPTION("CONTROL PM6125 FLASH GPIO Driver"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h new file mode 100644 index 000000000000..efd6b279adb6 --- /dev/null +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h @@ -0,0 +1,21 @@ +#ifndef _PM6125_FLASH_GPIO_H_ +#define _PM6125_FLASH_GPIO_H_ + +#include "../cam_sensor_utils/cam_sensor_cmn_header.h" + +#define PM6125_FLASH_PRINT pr_info //printk + +/* DTS state */ +typedef enum { + PM6125_FLASH_GPIO_STATE_ACTIVE, + PM6125_FLASH_GPIO_STATE_SUSPEND, + PM6125_FLASH_GPIO_STATE_MAX, /* for array size */ +} PM6125_FLASH_GPIO_STATE; + +/***************************************************************************** + * Function Prototype + *****************************************************************************/ +extern void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, u64 flash_current); +int pm6125_flash_gpio_init_module(void); +void pm6125_flash_gpio_exit_module(void); +#endif /* _PM6125_FLASH_GPIO_H_*/ \ No newline at end of file diff --git a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c index 5165f6b2d1c9..8ea1889ebe2d 100644 --- a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c +++ b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c @@ -458,6 +458,7 @@ int cam_res_mgr_gpio_request(struct device *dev, uint gpio, * from the gpio_res_list * These two situations both need request gpio. */ + CAM_DBG(CAM_RES, "shared gpio enable is %d shared gpio num is %d", cam_res->shared_gpio_enabled, cam_res->dt.num_shared_gpio); if (!gpio_found) { CAM_DBG(CAM_RES, "gpio: %u not found in gpio_res list", gpio); rc = gpio_request_one(gpio, flags, label); @@ -571,7 +572,7 @@ bool cam_res_mgr_util_check_if_gpio_is_shared( } EXPORT_SYMBOL(cam_res_mgr_util_check_if_gpio_is_shared); -static void cam_res_mgr_gpio_free(struct device *dev, uint gpio) +void cam_res_mgr_gpio_free(struct device *dev, uint gpio) { bool gpio_found = false; bool need_free = true; @@ -644,6 +645,7 @@ static void cam_res_mgr_gpio_free(struct device *dev, uint gpio) mutex_unlock(&cam_res->gpio_res_lock); } +EXPORT_SYMBOL(cam_res_mgr_gpio_free); void cam_res_mgr_gpio_free_arry(struct device *dev, const struct gpio *array, size_t num) diff --git a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h index cb5022f482e5..9a4b2b8560b8 100644 --- a/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h +++ b/drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h @@ -73,6 +73,18 @@ bool cam_res_mgr_util_check_if_gpio_is_shared( int cam_res_mgr_gpio_request(struct device *dev, unsigned int gpio, unsigned long flags, const char *label); +/** + * @brief: Free a GPIO + * + * Free the GPIO and release corresponding gpio_res. + * + * @dev : Pointer to the device + * @gpio : A GPIO number + * + * @return Status of operation. Negative in case of error. Zero otherwise. + */ +void cam_res_mgr_gpio_free(struct device *dev, uint gpio); + /** * @brief: Free a array GPIO * diff --git a/drivers/camera_main.c b/drivers/camera_main.c index d126491e8d28..a49ba3b78018 100644 --- a/drivers/camera_main.c +++ b/drivers/camera_main.c @@ -26,6 +26,7 @@ #include "cam_csiphy_dev.h" #include "cam_eeprom_dev.h" #include "cam_ois_dev.h" +#include "pm6125_flash_gpio.h" #if IS_REACHABLE(CONFIG_LEDS_QPNP_FLASH_V2) || \ IS_REACHABLE(CONFIG_LEDS_QTI_FLASH) @@ -118,6 +119,9 @@ static const struct camera_submodule_component camera_sensor[] = { IS_REACHABLE(CONFIG_LEDS_QTI_FLASH) {&cam_flash_init_module, &cam_flash_exit_module}, #endif +#if IS_REACHABLE(CONFIG_CAMERA_FLASH_PWM) + {&pm6125_flash_gpio_init_module, &pm6125_flash_gpio_exit_module}, +#endif #endif }; From 2af5b829572489d57af5385ba9547f37344c66b5 Mon Sep 17 00:00:00 2001 From: huaqin90 Date: Mon, 6 Dec 2021 19:03:06 +0800 Subject: [PATCH 23/86] disable CONFIG_CAMERA_FLASH_PWM details: disable CONFIG_CAMERA_FLASH_PWM in holicamera.conf Eliminate impact on other projects Change-Id: I2648e11032870c3060b194a3bfc5eeadaa38866e Signed-off-by: huaqin90 Reviewed-on: https://gerrit.mot.com/2136223 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Ying Xu Reviewed-by: Zhuoran Xu Submit-Approved: Jira Key --- config/holicamera.conf | 1 - config/holicameraconf.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/config/holicamera.conf b/config/holicamera.conf index a74f301e76c5..85bc1dae00c6 100644 --- a/config/holicamera.conf +++ b/config/holicamera.conf @@ -9,5 +9,4 @@ export CONFIG_SPECTRA_ISP=y export CONFIG_SPECTRA_OPE=y export CONFIG_SPECTRA_TFE=y export CONFIG_SPECTRA_SENSOR=y -export CONFIG_CAMERA_FLASH_PWM=y endif diff --git a/config/holicameraconf.h b/config/holicameraconf.h index 1141c53aea4e..72c6202e0338 100644 --- a/config/holicameraconf.h +++ b/config/holicameraconf.h @@ -8,4 +8,4 @@ #define CONFIG_SPECTRA_OPE 1 #define CONFIG_SPECTRA_TFE 1 #define CONFIG_SPECTRA_SENSOR 1 -#define CONFIG_CAMERA_FLASH_PWM 1 + From fdd05557080413e7f10acaf24825bea40cd1ce45 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 24 Nov 2021 17:41:50 +0800 Subject: [PATCH 24/86] 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 { From 0e977529efa988ebacada7768b6bb257d9c9346e Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 8 Dec 2021 09:37:59 +0800 Subject: [PATCH 25/86] camera: ois: support vsync interrupt [detail] Use vsync interrupt timestamp for ois data timestamp. Change-Id: I56ffced64ad368129115067f84109d8a66663f59 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2138044 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 45 +++++++++-------- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 48 +++++++++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.h | 6 ++- .../cam_sensor_module/cam_ois/cam_ois_soc.c | 8 ++++ 4 files changed, 83 insertions(+), 24 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 d2663140d005..ff18135c2d52 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -112,7 +112,8 @@ 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; + o_ctrl->previous_timestamp = 0; + o_ctrl->current_timestamp = 0; soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; @@ -1157,7 +1158,6 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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; @@ -1167,6 +1167,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) uint32_t i, size; uint8_t packetCounter = 0; uint32_t k = 0, remain_len = 0, read_len = 0; + unsigned long flags; if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { rc = -EINVAL; @@ -1251,7 +1252,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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++) { + for (k = 0; (k < read_length/READ_BTYE + 1) && (read_len != 0); 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, @@ -1261,33 +1262,26 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) read_len); remain_len -= read_len; read_len = remain_len > READ_BTYE ? READ_BTYE:remain_len; + + if (rc < 0) { + CAM_ERR(CAM_OIS, "Failed: seq read I2C settings: %d", rc); + delete_request(&i2c_read_settings); + return rc; + } + + if (k == 0 && read_buff[1] == 0) { + CAM_WARN(CAM_OIS,"No-fatal: sample data is zero, break the loop read"); + break; + } } - 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"); + CAM_WARN(CAM_OIS,"No-fatal: 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]; @@ -1297,7 +1291,12 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_ERR(CAM_OIS, "Buffer not large enough for timestamp"); return -EINVAL; } - memcpy((void *)timestampBuf, (void *)×tamp, sizeof(uint64_t)); + + spin_lock_irqsave(&o_ctrl->ois_lock, flags); + memcpy((void *)timestampBuf, + (void *)&o_ctrl->previous_timestamp, + sizeof(uint64_t)); + spin_unlock_irqrestore(&o_ctrl->ois_lock, flags); packetCounter = (read_buff[1] + 9)/10; } diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index aa771b3bd14d..02ef393d348b 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -271,6 +271,30 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) return 0; } +static irqreturn_t ois_vsync_irq_handler(int irq, void *data) +{ + struct cam_ois_ctrl_t *o_ctrl = data; + int rc; + uint64_t qtime_ns = 0; + + rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d"); + return IRQ_NONE; + } + + CAM_DBG(CAM_OIS, "vsync sof timestamp is %lld", qtime_ns); + + spin_lock(&o_ctrl->ois_lock); + + o_ctrl->previous_timestamp = o_ctrl->current_timestamp; + o_ctrl->current_timestamp = qtime_ns; + + spin_unlock(&o_ctrl->ois_lock); + + return IRQ_HANDLED; +} + static int cam_ois_component_bind(struct device *dev, struct device *master_dev, void *data) { @@ -331,6 +355,30 @@ static int cam_ois_component_bind(struct device *dev, platform_set_drvdata(pdev, o_ctrl); o_ctrl->cam_ois_state = CAM_OIS_INIT; + + spin_lock_init(&o_ctrl->ois_lock); + + if (o_ctrl->is_ois_vsync_irq_supported) { + o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); + + if (o_ctrl->vsync_irq > 0) { + CAM_DBG(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); + + rc = devm_request_threaded_irq(dev, + o_ctrl->vsync_irq, + NULL, + ois_vsync_irq_handler, + (IRQF_TRIGGER_RISING | IRQF_ONESHOT), + "ois-vsync-irq", + o_ctrl); + if (rc != 0) + CAM_ERR(CAM_OIS, "failed: to request ois-vsync IRQ %d, rc %d", o_ctrl->vsync_irq, rc); + else + CAM_DBG(CAM_OIS, "request ois-vsync IRQ success"); + } else + CAM_ERR(CAM_OIS, "failed: to get ois-vsync IRQ"); + } + CAM_DBG(CAM_OIS, "Component bound successfully"); return rc; unreg_subdev: 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 3097f36c2763..aad789519799 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -142,8 +142,12 @@ 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; + uint64_t previous_timestamp; + uint64_t current_timestamp; struct cam_ois_opcode opcode; + bool is_ois_vsync_irq_supported; + int vsync_irq; + spinlock_t ois_lock; }; /** diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c index 510c81d9e9f3..59af6b297bd2 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c @@ -34,6 +34,14 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->ois_device_type); return -EINVAL; } + + if (!of_property_read_bool(of_node, "vsync-irq-support")) { + o_ctrl->is_ois_vsync_irq_supported = false; + } else { + o_ctrl->is_ois_vsync_irq_supported = true; + } + CAM_DBG(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); + rc = cam_soc_util_get_dt_properties(soc_info); if (rc < 0) { CAM_ERR(CAM_OIS, "cam_soc_util_get_dt_properties rc %d", From 8c97d184f6e90a789bf032b0c9e34189cdb4dbee Mon Sep 17 00:00:00 2001 From: huaqin78 Date: Sat, 11 Dec 2021 16:24:16 +0800 Subject: [PATCH 26/86] Rhodep: add flash current ma control details: add flash current ma control Change-Id: Ic3c89657ac568cf56fc2f402c90211fb433b6212 Signed-off-by: huaqin78 Signed-off-by: luozhq15 Reviewed-on: https://gerrit.mot.com/2142725 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Tested-by: Jira Key Submit-Approved: Jira Key --- .../cam_flash/cam_flash_core.c | 12 ++- .../cam_flash_pm6125_gpio/pm6125_flash_gpio.c | 95 ++++++++++++------- .../cam_flash_pm6125_gpio/pm6125_flash_gpio.h | 8 +- 3 files changed, 74 insertions(+), 41 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 7dc82ebe73cc..6c1bbaba624c 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -556,7 +556,7 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl) CAM_ERR(CAM_SENSOR,"cam_flash_off"); cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0); cam_res_mgr_gpio_free(soc_info.dev, soc_private->flash_gpio_enable); - pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND,1); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND, CAMERA_SENSOR_FLASH_OP_OFF, 0); #endif return 0; } @@ -589,14 +589,16 @@ static int cam_flash_low( CAM_ERR(CAM_FLASH, "Fire Torch failed: %d", rc); #ifdef CONFIG_CAMERA_FLASH_PWM - CAM_ERR(CAM_FLASH, "Flash low Triggered"); + CAM_DBG(CAM_FLASH, "Flash low Triggered flash_data->led_current_ma[0] = %u", flash_data->led_current_ma[0]); rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1"); if(rc) { CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable); return rc; } cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 0); - pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, (u64)flash_data->led_current_ma[0]*10000/1500); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, FLASH_FIRE_LOW_MAXCURRENT); + usleep_range(5000,6000); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIRELOW, flash_data->led_current_ma[0]); #endif return rc; @@ -630,14 +632,14 @@ static int cam_flash_high( CAM_ERR(CAM_FLASH, "Fire Flash Failed: %d", rc); #ifdef CONFIG_CAMERA_FLASH_PWM - CAM_ERR(CAM_FLASH, "Flash high Triggered"); + CAM_DBG(CAM_FLASH, "Flash high Triggered flash_data->led_current_ma[0] = %u", flash_data->led_current_ma[0]); rc = cam_res_mgr_gpio_request(soc_info.dev, soc_private->flash_gpio_enable, 0, "CUSTOM_GPIO1"); if(rc) { CAM_ERR(CAM_FLASH, "gpio %d request fails", soc_private->flash_gpio_enable); return rc; } cam_res_mgr_gpio_set_value(soc_private->flash_gpio_enable, 1); - pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, (u64)flash_data->led_current_ma[0]*10000/1500); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_ACTIVE, CAMERA_SENSOR_FLASH_OP_FIREHIGH, flash_data->led_current_ma[0]); #endif return rc; diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c index b1adf43a8d60..9b742629172e 100644 --- a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c @@ -35,28 +35,55 @@ struct pwm_device *pwm; * Function *****************************************************************************/ -void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, u64 flash_current){ - struct pwm_state pstate; - int rc = 0; - pwm_get_state(pwm, &pstate); - pstate.period = 50000; - pstate.duty_cycle = 500000*flash_current/10000; - switch(s){ - case PM6125_FLASH_GPIO_STATE_ACTIVE: - pstate.enabled = true; - rc = pwm_apply_state(pwm, &pstate); - break; - case PM6125_FLASH_GPIO_STATE_SUSPEND: - pstate.enabled = false; - rc = pwm_apply_state(pwm, &pstate); - break; - default: - PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to control PWM use a err state!\n"); - } +void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash_opcode opcode, u64 flash_current){ + struct pwm_state pstate; + int rc = 0; + u64 real_current = 0; - if(rc < 0) { - PM6125_FLASH_PRINT("[pm6125_flash_gpio]Apply PWM state fail, rc = %d", rc); - } + pwm_get_state(pwm, &pstate); + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Status duty_cycle = %u, period = %u\n", + pstate.duty_cycle, pstate.period); + pstate.period = PM6125_PWM_PERIOD; + switch (s) { + case PM6125_FLASH_GPIO_STATE_ACTIVE: + pstate.duty_cycle = 0; + pstate.enabled = false; + rc = pwm_apply_state(pwm, &pstate); + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Suspend before Active"); + + switch (opcode) + { + case CAMERA_SENSOR_FLASH_OP_FIRELOW: + real_current = (flash_current > FLASH_FIRE_LOW_MAXCURRENT?FLASH_FIRE_LOW_MAXCURRENT:flash_current); + pstate.duty_cycle = PM6125_PWM_PERIOD * real_current / FLASH_FIRE_LOW_MAXCURRENT; + break; + case CAMERA_SENSOR_FLASH_OP_FIREHIGH: + real_current = (flash_current > FLASH_FIRE_HIGH_MAXCURRENT?FLASH_FIRE_HIGH_MAXCURRENT:flash_current); + pstate.duty_cycle = PM6125_PWM_PERIOD * real_current / FLASH_FIRE_HIGH_MAXCURRENT; + break; + default: + pstate.duty_cycle = PM6125_PWM_PERIOD; + break; + } + + pstate.enabled = true; + rc = pwm_apply_state(pwm, &pstate); + + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Active duty_cycle = %u, period = %u, opcode = %u, real_current = %u\n", + pstate.duty_cycle, pstate.period, opcode, real_current); + break; + case PM6125_FLASH_GPIO_STATE_SUSPEND: + pstate.enabled = false; + rc = pwm_apply_state(pwm, &pstate); + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Suspend"); + break; + default: + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to control PWM use a err state!\n"); + } + + if(rc < 0) { + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Apply PWM state fail, rc = %d", rc); + } } static int pm6125_flash_pwm_probe(struct platform_device *pdev) @@ -69,30 +96,30 @@ static int pm6125_flash_pwm_probe(struct platform_device *pdev) } static const struct of_device_id gpio_of_match[] = { - { .compatible = "qualcomm,pm6125_flash_gpio", }, - {}, + { .compatible = "qualcomm,pm6125_flash_gpio", }, + {}, }; static struct platform_driver pm6125_flash_gpio_platform_driver = { - .probe = pm6125_flash_pwm_probe, - .driver = { - .name = "PM6125_FLASH_GPIO_DTS", - .of_match_table = gpio_of_match, - }, + .probe = pm6125_flash_pwm_probe, + .driver = { + .name = "PM6125_FLASH_GPIO_DTS", + .of_match_table = gpio_of_match, + }, }; int pm6125_flash_gpio_init_module(void) { - if (platform_driver_register(&pm6125_flash_gpio_platform_driver)) { - PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to register pm6125_flash_gpio_platform_driver!\n"); - return -1; - } - return 0; + if (platform_driver_register(&pm6125_flash_gpio_platform_driver)) { + PM6125_FLASH_PRINT("[pm6125_flash_gpio]Failed to register pm6125_flash_gpio_platform_driver!\n"); + return -1; + } + return 0; } void pm6125_flash_gpio_exit_module(void) { - platform_driver_unregister(&pm6125_flash_gpio_platform_driver); + platform_driver_unregister(&pm6125_flash_gpio_platform_driver); } MODULE_AUTHOR("liyang "); diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h index efd6b279adb6..1010065f9daf 100644 --- a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h @@ -12,10 +12,14 @@ typedef enum { PM6125_FLASH_GPIO_STATE_MAX, /* for array size */ } PM6125_FLASH_GPIO_STATE; +#define PM6125_PWM_PERIOD 50000 +#define FLASH_FIRE_HIGH_MAXCURRENT 1200 +#define FLASH_FIRE_LOW_MAXCURRENT 150 + /***************************************************************************** * Function Prototype *****************************************************************************/ -extern void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, u64 flash_current); +extern void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash_opcode opcode, u64 flash_current); int pm6125_flash_gpio_init_module(void); void pm6125_flash_gpio_exit_module(void); -#endif /* _PM6125_FLASH_GPIO_H_*/ \ No newline at end of file +#endif /* _PM6125_FLASH_GPIO_H_*/ From eb14c6118f6446db24127413558086a279790184 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 14 Dec 2021 16:58:58 +0800 Subject: [PATCH 27/86] camera: ois: read ois data in vsync irq thread when vsync arrived, ois data has updated. read it in the vsync thread. Change-Id: I1bde6a76cf85d051cdd72bdff7a6df91364c906c Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2143947 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 119 +++++------------ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 126 ++++++++++++++++-- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 14 +- 3 files changed, 156 insertions(+), 103 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 ff18135c2d52..03f06261af69 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -112,8 +112,9 @@ 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->previous_timestamp = 0; - o_ctrl->current_timestamp = 0; + o_ctrl->prev_timestamp = 0; + o_ctrl->curr_timestamp = 0; + o_ctrl->is_first_vsync = 1; soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; @@ -573,28 +574,6 @@ 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 @@ -1164,10 +1143,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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; - unsigned long flags; + uint32_t size; + unsigned long rem_jiffies = 0; if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { rc = -EINVAL; @@ -1235,82 +1212,46 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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); + delete_request(&i2c_read_settings); 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) && (read_len != 0); 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_OIS, "Failed: seq read I2C settings: %d", rc); - delete_request(&i2c_read_settings); - return rc; - } + 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 (k == 0 && read_buff[1] == 0) { - CAM_WARN(CAM_OIS,"No-fatal: sample data is zero, break the loop read"); - break; - } - } + if(timestampBufLen < sizeof(uint64_t)) { + CAM_ERR(CAM_OIS, "Buffer not large enough for timestamp"); + delete_request(&i2c_read_settings); + return -EINVAL; + } - if (!rc){ - if (read_buff[1] == 0){ - CAM_WARN(CAM_OIS,"No-fatal: header is zero, break the read"); - rc = -EINVAL; - break; - } else if ((read_buff[1] != 0) && (packetCounter == 0)) { + rem_jiffies = wait_for_completion_timeout(&o_ctrl->ois_data_complete, + msecs_to_jiffies(120)); + if (rem_jiffies == 0) { + CAM_ERR(CAM_OIS, "Wait ois data completion timeout 120 ms"); + delete_request(&i2c_read_settings); + return -ETIMEDOUT; + } - 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]; + mutex_lock(&(o_ctrl->vsync_mutex)); + memcpy((void *)timestampBuf, + (void *)&o_ctrl->prev_timestamp, + sizeof(uint64_t)); - if(timestampBufLen < sizeof(uint64_t)) { - CAM_ERR(CAM_OIS, "Buffer not large enough for timestamp"); - return -EINVAL; - } - - spin_lock_irqsave(&o_ctrl->ois_lock, flags); - memcpy((void *)timestampBuf, - (void *)&o_ctrl->previous_timestamp, - sizeof(uint64_t)); - spin_unlock_irqrestore(&o_ctrl->ois_lock, flags); - - 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); + memcpy((void *)read_buff, + (void *)o_ctrl->ois_data, + sizeof(o_ctrl->ois_data)); + mutex_unlock(&(o_ctrl->vsync_mutex)); } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) { size = i2c_list->i2c_settings.size; for (i = 0; i < size; i++) { diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 02ef393d348b..49321f11f7ec 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -10,6 +10,28 @@ #include "cam_debug_util.h" #include "camera_main.h" +static int cam_ois_clear_data_ready(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"); + } + + CAM_DBG(CAM_OIS,"Clear data-ready success"); + return rc; +} + static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { @@ -271,28 +293,109 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) return 0; } -static irqreturn_t ois_vsync_irq_handler(int irq, void *data) +static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) { struct cam_ois_ctrl_t *o_ctrl = data; - int rc; - uint64_t qtime_ns = 0; + int rc = 0, handled = IRQ_NONE; + uint64_t qtime_ns; + uint8_t *read_buff, packet_cnt, sample_cnt; + uint32_t k, read_len; + + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { + CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); + return IRQ_NONE; + } + + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state); + goto release_mutex; + } rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); if (rc < 0) { CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d"); - return IRQ_NONE; + goto release_mutex; } CAM_DBG(CAM_OIS, "vsync sof timestamp is %lld", qtime_ns); - spin_lock(&o_ctrl->ois_lock); + o_ctrl->prev_timestamp = o_ctrl->curr_timestamp; + o_ctrl->curr_timestamp = qtime_ns; - o_ctrl->previous_timestamp = o_ctrl->current_timestamp; - o_ctrl->current_timestamp = qtime_ns; + // when the first vsync arrived, clear data-ready, and return. + if (o_ctrl->is_first_vsync) { + o_ctrl->is_first_vsync = 0; + rc = cam_ois_clear_data_ready(o_ctrl); + udelay(1000); + goto release_mutex; + } - spin_unlock(&o_ctrl->ois_lock); + memset(o_ctrl->ois_data, 0, sizeof(o_ctrl->ois_data)); + read_buff = o_ctrl->ois_data; + packet_cnt = 0; + sample_cnt = 0; - return IRQ_HANDLED; + do { + // SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time. + // Each loop read max supported bytes(0xE). One packet(62 bytes) need 5 times loop read. + for (k = 0; k < PACKET_BYTE/READ_BYTE + 1; k++) { + if (k == PACKET_BYTE/READ_BYTE) + read_len = PACKET_BYTE%READ_BYTE; + else + read_len = READ_BYTE; + + rc = camera_io_dev_read_seq( + &o_ctrl->io_master_info, + PACKET_ADDR + k*READ_BYTE/2, + read_buff + k*READ_BYTE, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD, + read_len); + + if (rc < 0) { + CAM_ERR(CAM_OIS, "Failed: seq read I2C settings: %d", rc); + goto release_mutex; + } + + if (k == 0 && packet_cnt == 0) { + sample_cnt = read_buff[1]; + if (sample_cnt != 0) { + packet_cnt = (sample_cnt + 9)/10; + CAM_DBG(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); + } else { + CAM_WARN(CAM_OIS,"No-fatal: sample data is zero, break the loop read"); + goto release_mutex; + } + } + } + + if (sample_cnt > 10 && packet_cnt > 1) { + CAM_DBG(CAM_OIS,"more than 1 packet, clear data-ready and read next packet"); + rc = cam_ois_clear_data_ready(o_ctrl); + udelay(1000); + + if (rc < 0) { + CAM_ERR(CAM_OIS,"Write failed rc: %d", rc); + goto release_mutex; + } + } + + packet_cnt--; + read_buff += PACKET_BYTE; + } while(packet_cnt); + +release_mutex: + if (rc < 0) { + memset(o_ctrl->ois_data, 0, sizeof(o_ctrl->ois_data)); + handled = IRQ_NONE; + } else + handled = IRQ_HANDLED; + + mutex_unlock(&(o_ctrl->vsync_mutex)); + + complete(&o_ctrl->ois_data_complete); + + return handled; } static int cam_ois_component_bind(struct device *dev, @@ -356,7 +459,8 @@ static int cam_ois_component_bind(struct device *dev, platform_set_drvdata(pdev, o_ctrl); o_ctrl->cam_ois_state = CAM_OIS_INIT; - spin_lock_init(&o_ctrl->ois_lock); + mutex_init(&(o_ctrl->vsync_mutex)); + init_completion(&o_ctrl->ois_data_complete); if (o_ctrl->is_ois_vsync_irq_supported) { o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); @@ -367,7 +471,7 @@ static int cam_ois_component_bind(struct device *dev, rc = devm_request_threaded_irq(dev, o_ctrl->vsync_irq, NULL, - ois_vsync_irq_handler, + cam_ois_vsync_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT), "ois-vsync-irq", o_ctrl); 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 aad789519799..9292ee9f4210 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -25,6 +25,11 @@ #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) +#define PACKET_ADDR 0x70B0 +#define PACKET_BYTE 62 +#define MAX_PACKET 3 +#define READ_BYTE 0xE + enum cam_ois_state { CAM_OIS_INIT, CAM_OIS_ACQUIRE, @@ -142,12 +147,15 @@ 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 previous_timestamp; - uint64_t current_timestamp; + uint64_t prev_timestamp; + uint64_t curr_timestamp; struct cam_ois_opcode opcode; bool is_ois_vsync_irq_supported; int vsync_irq; - spinlock_t ois_lock; + struct mutex vsync_mutex; + struct completion ois_data_complete; + bool is_first_vsync; + uint8_t ois_data[PACKET_BYTE*MAX_PACKET]; }; /** From a77c5ebdb3a95d8f49377d0548361584a51f4400 Mon Sep 17 00:00:00 2001 From: luozhq15 Date: Wed, 15 Dec 2021 15:08:37 +0800 Subject: [PATCH 28/86] Rhodep: flash node control details: control flash enable & brightness Change-Id: I59933ae02344bf167dbc3c775d5c9f08061786c0 Signed-off-by: luozhq15 Reviewed-on: https://gerrit.mot.com/2145011 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Reviewed-by: Long Cheng Tested-by: Jira Key Reviewed-by: Reviewed-by: Wang Liu Reviewed-by: Xingyun Fu Reviewed-by: Shuo Wang Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_flash/cam_flash_dev.c | 16 ++ .../cam_flash_pm6125_gpio/pm6125_flash_gpio.c | 189 +++++++++++++++++- .../cam_flash_pm6125_gpio/pm6125_flash_gpio.h | 13 ++ 3 files changed, 211 insertions(+), 7 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index 323497be3b90..011ce8d8ecb1 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -9,6 +9,9 @@ #include "cam_flash_core.h" #include "cam_common_util.h" #include "camera_main.h" +#ifdef CONFIG_CAMERA_FLASH_PWM +#include "pm6125_flash_gpio.h" +#endif static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, void *arg, struct cam_flash_private_soc *soc_private) @@ -444,6 +447,9 @@ static int cam_flash_component_bind(struct device *dev, fctrl->soc_info.dev_name = pdev->name; platform_set_drvdata(pdev, fctrl); +#ifdef CONFIG_CAMERA_FLASH_PWM + dev_set_drvdata(&pdev->dev, fctrl); +#endif rc = cam_flash_get_dt_data(fctrl, &fctrl->soc_info); if (rc) { @@ -544,6 +550,9 @@ static int cam_flash_component_bind(struct device *dev, fctrl->flash_state = CAM_FLASH_STATE_INIT; CAM_DBG(CAM_FLASH, "Component bound successfully"); +#ifdef CONFIG_CAMERA_FLASH_PWM + pm6125_flash_control_create_device(&pdev->dev); +#endif return rc; free_cci_resource: @@ -566,6 +575,10 @@ static void cam_flash_component_unbind(struct device *dev, struct cam_flash_ctrl *fctrl; struct platform_device *pdev = to_platform_device(dev); +#ifdef CONFIG_CAMERA_FLASH_PWM + pm6125_flash_control_remove_device(&pdev->dev); +#endif + fctrl = platform_get_drvdata(pdev); if (!fctrl) { CAM_ERR(CAM_FLASH, "Flash device is NULL"); @@ -578,6 +591,9 @@ static void cam_flash_component_unbind(struct device *dev, cam_unregister_subdev(&(fctrl->v4l2_dev_str)); cam_flash_put_source_node_data(fctrl); platform_set_drvdata(pdev, NULL); +#ifdef CONFIG_CAMERA_FLASH_PWM + dev_set_drvdata(&pdev->dev, NULL); +#endif v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL); kfree(fctrl); CAM_INFO(CAM_FLASH, "Flash Sensor component unbind"); diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c index 9b742629172e..413f6b73bfc1 100644 --- a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.c @@ -22,7 +22,13 @@ #include #include #include "pm6125_flash_gpio.h" - +#ifdef CONFIG_CAMERA_FLASH_PWM +#include "cam_flash_dev.h" +#include "cam_flash_soc.h" +#include "cam_flash_core.h" +#include "cam_common_util.h" +#include "cam_res_mgr_api.h" +#endif /***************************************************************************** @@ -30,8 +36,10 @@ *****************************************************************************/ struct pwm_device *pwm; - -/***************************************************************************** +#ifdef CONFIG_CAMERA_FLASH_PWM +static unsigned int flashlight_enable = CAMERA_SENSOR_FLASH_STATUS_OFF; +static unsigned int flashlight_brightness = 0; +#endif/***************************************************************************** * Function *****************************************************************************/ @@ -46,10 +54,6 @@ void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash pstate.period = PM6125_PWM_PERIOD; switch (s) { case PM6125_FLASH_GPIO_STATE_ACTIVE: - pstate.duty_cycle = 0; - pstate.enabled = false; - rc = pwm_apply_state(pwm, &pstate); - PM6125_FLASH_PRINT("[pm6125_flash_gpio]Suspend before Active"); switch (opcode) { @@ -85,7 +89,178 @@ void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash PM6125_FLASH_PRINT("[pm6125_flash_gpio]Apply PWM state fail, rc = %d", rc); } } +#ifdef CONFIG_CAMERA_FLASH_PWM +static ssize_t flashlight_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", flashlight_enable); +} +static ssize_t flashlight_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct cam_flash_ctrl *fctrl = dev_get_drvdata(dev); + struct cam_flash_private_soc *soc_private = fctrl->soc_info.soc_private; + unsigned long state_to_set; + ssize_t ret = -EINVAL; + + CAM_INFO(CAM_FLASH, "Flash Enable Command: %s", buf); + ret = kstrtoul(buf, 10, &state_to_set); + if (ret) + return ret; + + if (CAMERA_SENSOR_FLASH_STATUS_OFF != state_to_set) { + // enable flash + if (CAMERA_SENSOR_FLASH_STATUS_OFF == flashlight_enable) { + ret = cam_res_mgr_gpio_request( + fctrl->soc_info.dev, + soc_private->flash_gpio_enable, 0, + "CUSTOM_GPIO1"); + if (ret) { + CAM_ERR(CAM_FLASH, "gpio %d request fails", + soc_private->flash_gpio_enable); + return ret; + } + } + + flashlight_enable = state_to_set; + cam_res_mgr_gpio_set_value( + soc_private->flash_gpio_enable, + flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH); + if (flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_LOW) { + pm6125_flash_gpio_select_state( + PM6125_FLASH_GPIO_STATE_ACTIVE, + CAMERA_SENSOR_FLASH_OP_FIRELOW, + FLASH_FIRE_LOW_MAXCURRENT); + usleep_range(5000, 6000); + } + pm6125_flash_gpio_select_state( + PM6125_FLASH_GPIO_STATE_ACTIVE, + flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ? + CAMERA_SENSOR_FLASH_OP_FIREHIGH : + CAMERA_SENSOR_FLASH_OP_FIRELOW, + (u64)flashlight_brightness); + } + else { + // disable flash + if (CAMERA_SENSOR_FLASH_STATUS_OFF != flashlight_enable) { + cam_res_mgr_gpio_set_value( + soc_private->flash_gpio_enable, 0); + cam_res_mgr_gpio_free(fctrl->soc_info.dev, + soc_private->flash_gpio_enable); + } + flashlight_enable = CAMERA_SENSOR_FLASH_STATUS_OFF; + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND, + CAMERA_SENSOR_FLASH_OP_OFF, 0); + } + return size; +} + +static ssize_t flashlight_brightness_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", flashlight_brightness); +} + +static ssize_t flashlight_brightness_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct cam_flash_ctrl *fctrl = dev_get_drvdata(dev); + struct cam_flash_private_soc *soc_private = fctrl->soc_info.soc_private; + unsigned long brightness_to_set; + ssize_t ret = -EINVAL; + + CAM_INFO(CAM_FLASH, "Flash Brightness Command: %s", buf); + ret = kstrtoul(buf, 10, &brightness_to_set); + if (ret) + return ret; + + flashlight_brightness = brightness_to_set; + + switch (flashlight_enable) + { + case CAMERA_SENSOR_FLASH_STATUS_LOW: // CAMERA_SENSOR_FLASH_OP_FIRELOW + case CAMERA_SENSOR_FLASH_STATUS_HIGH: // CAMERA_SENSOR_FLASH_OP_FIREHIGH + + CAM_INFO(CAM_FLASH, "Flash Mode %s: %d", + flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ? + "High" : + "Low", + flashlight_brightness); + + // disable first + cam_res_mgr_gpio_set_value( + soc_private->flash_gpio_enable, 0); + cam_res_mgr_gpio_free(fctrl->soc_info.dev, + soc_private->flash_gpio_enable); + pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE_SUSPEND, CAMERA_SENSOR_FLASH_OP_OFF, 0); + + // get handle + ret = cam_res_mgr_gpio_request( + fctrl->soc_info.dev, + soc_private->flash_gpio_enable, 0, + "CUSTOM_GPIO1"); + if (ret) { + CAM_ERR(CAM_FLASH, "gpio %d request fails", + soc_private->flash_gpio_enable); + return ret; + } + + cam_res_mgr_gpio_set_value( + soc_private->flash_gpio_enable, + flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH); + if (flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_LOW) { + pm6125_flash_gpio_select_state( + PM6125_FLASH_GPIO_STATE_ACTIVE, + CAMERA_SENSOR_FLASH_OP_FIRELOW, + FLASH_FIRE_LOW_MAXCURRENT); + usleep_range(5000, 6000); + } + pm6125_flash_gpio_select_state( + PM6125_FLASH_GPIO_STATE_ACTIVE, + flashlight_enable == CAMERA_SENSOR_FLASH_STATUS_HIGH ? + CAMERA_SENSOR_FLASH_OP_FIREHIGH : + CAMERA_SENSOR_FLASH_OP_FIRELOW, + (u64)flashlight_brightness); + break; + default: + CAM_INFO(CAM_FLASH, "flashlight had not been enable yet."); + break; + } + + return size; +} +static DEVICE_ATTR_RW(flashlight_enable); +static DEVICE_ATTR_RW(flashlight_brightness); +struct device_attribute *flashlight_attributes[] = { + &dev_attr_flashlight_enable, + &dev_attr_flashlight_brightness, +}; +int pm6125_flash_control_create_device(struct device* dev) +{ + int i, ret = 0; + for (i = 0; i < ARRAY_SIZE(flashlight_attributes); i++) { + ret = device_create_file(dev, + flashlight_attributes[i]); + if (ret) { + dev_err(dev, "failed: sysfs file %s\n", + flashlight_attributes[i]->attr.name); + pm6125_flash_control_remove_device(dev); + return ret; + } + } + return 0; +} + +int pm6125_flash_control_remove_device(struct device* dev) +{ + int i; + for (i = 0; i < ARRAY_SIZE(flashlight_attributes); i++) { + device_remove_file(dev, flashlight_attributes[i]); + } + return 0; +} +#endif static int pm6125_flash_pwm_probe(struct platform_device *pdev) { int rc = 0; diff --git a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h index 1010065f9daf..97b19ea341a6 100644 --- a/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h +++ b/drivers/cam_sensor_module/cam_flash_pm6125_gpio/pm6125_flash_gpio.h @@ -12,6 +12,15 @@ typedef enum { PM6125_FLASH_GPIO_STATE_MAX, /* for array size */ } PM6125_FLASH_GPIO_STATE; +#ifdef CONFIG_CAMERA_FLASH_PWM +enum{ + CAMERA_SENSOR_FLASH_STATUS_OFF, + CAMERA_SENSOR_FLASH_STATUS_LOW, + CAMERA_SENSOR_FLASH_STATUS_HIGH +}; +#endif + + #define PM6125_PWM_PERIOD 50000 #define FLASH_FIRE_HIGH_MAXCURRENT 1200 #define FLASH_FIRE_LOW_MAXCURRENT 150 @@ -20,6 +29,10 @@ typedef enum { * Function Prototype *****************************************************************************/ extern void pm6125_flash_gpio_select_state(PM6125_FLASH_GPIO_STATE s, enum camera_flash_opcode opcode, u64 flash_current); +#ifdef CONFIG_CAMERA_FLASH_PWM +extern int pm6125_flash_control_create_device(struct device* dev); +extern int pm6125_flash_control_remove_device(struct device* dev); +#endif int pm6125_flash_gpio_init_module(void); void pm6125_flash_gpio_exit_module(void); #endif /* _PM6125_FLASH_GPIO_H_*/ From d296bfbc9347409624f54fe80b79284fc53d3266 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 28 Dec 2021 11:32:57 +0800 Subject: [PATCH 29/86] camera: ois: read 0xC bytes in cci_read sm6375 cci only support read 0xE bytes each time. if we read 0xE bytes, it will access invalid memory. so change to read 0xC bytes each time. Change-Id: Id59620df4e5cb16bfb31396fdc6fc65c60449600 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2155699 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 1 - drivers/cam_sensor_module/cam_ois/cam_ois_dev.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 49321f11f7ec..f78a10ccd7f6 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -337,7 +337,6 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) do { // SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time. - // Each loop read max supported bytes(0xE). One packet(62 bytes) need 5 times loop read. for (k = 0; k < PACKET_BYTE/READ_BYTE + 1; k++) { if (k == PACKET_BYTE/READ_BYTE) read_len = PACKET_BYTE%READ_BYTE; 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 9292ee9f4210..a7425839b6ff 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -28,7 +28,7 @@ #define PACKET_ADDR 0x70B0 #define PACKET_BYTE 62 #define MAX_PACKET 3 -#define READ_BYTE 0xE +#define READ_BYTE 0xC enum cam_ois_state { CAM_OIS_INIT, From 0d6e82462dc27663f5a5e5559bfd10d77945000a Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 28 Dec 2021 14:08:04 +0800 Subject: [PATCH 30/86] camera: ois: add new cci read function for ois Qcom cci read function will use kzalloc()/kfree() to alloc temp buf for cci read data. As ois vsync irq thread use cci read very frequently, so don't alloc/free temp buf when cci read. Change-Id: I67a912d6ef5ba3f1820d5b571ff5bd55f8c1f561 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2155763 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 2 +- .../cam_sensor_io/cam_sensor_cci_i2c.c | 33 +++++++++++++++++++ .../cam_sensor_io/cam_sensor_i2c.h | 6 ++++ .../cam_sensor_io/cam_sensor_io.c | 25 ++++++++++++++ .../cam_sensor_io/cam_sensor_io.h | 6 ++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index f78a10ccd7f6..2216e2e8222c 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -343,7 +343,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) else read_len = READ_BYTE; - rc = camera_io_dev_read_seq( + rc = camera_io_dev_ois_read_seq( &o_ctrl->io_master_info, PACKET_ADDR + k*READ_BYTE/2, read_buff + k*READ_BYTE, diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c index a5e780a2e119..1400dc14b821 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.c @@ -93,6 +93,39 @@ int32_t cam_camera_cci_i2c_read_seq(struct cam_sensor_cci_client *cci_client, return rc; } +int32_t cam_camera_cci_i2c_ois_read_seq(struct cam_sensor_cci_client *cci_client, + uint32_t addr, uint8_t *data, + enum camera_sensor_i2c_type addr_type, + enum camera_sensor_i2c_type data_type, + uint32_t num_byte) +{ + int32_t rc = -EFAULT; + struct cam_cci_ctrl cci_ctrl; + + if ((addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) + || (data_type >= CAMERA_SENSOR_I2C_TYPE_MAX) + || (num_byte > I2C_REG_DATA_MAX)) { + CAM_ERR(CAM_SENSOR, "addr_type %d num_byte %d", addr_type, + num_byte); + return rc; + } + + cci_ctrl.cmd = MSM_CCI_I2C_READ; + cci_ctrl.cci_info = cci_client; + cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr; + cci_ctrl.cfg.cci_i2c_read_cfg.addr_type = addr_type; + cci_ctrl.cfg.cci_i2c_read_cfg.data_type = data_type; + cci_ctrl.cfg.cci_i2c_read_cfg.data = data; + cci_ctrl.cfg.cci_i2c_read_cfg.num_byte = num_byte; + cci_ctrl.status = -EFAULT; + rc = v4l2_subdev_call(cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + rc = cci_ctrl.status; + CAM_DBG(CAM_SENSOR, "addr = 0x%x, rc = %d", addr, rc); + + return rc; +} + static int32_t cam_cci_i2c_write_table_cmd( struct camera_io_master *client, struct cam_sensor_i2c_reg_setting *write_setting, diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i2c.h b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i2c.h index 6cece10403c9..9c3c108437fe 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i2c.h +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i2c.h @@ -49,6 +49,12 @@ int32_t cam_camera_cci_i2c_read_seq(struct cam_sensor_cci_client *client, enum camera_sensor_i2c_type data_type, uint32_t num_byte); +int32_t cam_camera_cci_i2c_ois_read_seq(struct cam_sensor_cci_client *client, + uint32_t addr, uint8_t *data, + enum camera_sensor_i2c_type addr_type, + enum camera_sensor_i2c_type data_type, + uint32_t num_byte); + /** * @client: CCI client structure * @write_setting: I2C register setting diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c index 108c47923eb7..38c64555b29f 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c @@ -115,6 +115,31 @@ int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info, return 0; } +int32_t camera_io_dev_ois_read_seq(struct camera_io_master *io_master_info, + uint32_t addr, uint8_t *data, + enum camera_sensor_i2c_type addr_type, + enum camera_sensor_i2c_type data_type, int32_t num_bytes) +{ + if (io_master_info->master_type == CCI_MASTER) { + return cam_camera_cci_i2c_ois_read_seq(io_master_info->cci_client, + addr, data, addr_type, data_type, num_bytes); + } else if (io_master_info->master_type == I2C_MASTER) { + return cam_qup_i2c_read_seq(io_master_info->client, + addr, data, addr_type, num_bytes); + } else if (io_master_info->master_type == SPI_MASTER) { + return cam_spi_read_seq(io_master_info, + addr, data, addr_type, num_bytes); + } else if (io_master_info->master_type == SPI_MASTER) { + return cam_spi_write_seq(io_master_info, + addr, data, addr_type, num_bytes); + } else { + CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d", + io_master_info->master_type); + return -EINVAL; + } + return 0; +} + int32_t camera_io_dev_write(struct camera_io_master *io_master_info, struct cam_sensor_i2c_reg_setting *write_setting) { diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.h b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.h index f70709997e69..7bd2457c2496 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.h +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.h @@ -57,6 +57,12 @@ int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info, enum camera_sensor_i2c_type data_type, int32_t num_bytes); +int32_t camera_io_dev_ois_read_seq(struct camera_io_master *io_master_info, + uint32_t addr, uint8_t *data, + enum camera_sensor_i2c_type addr_type, + enum camera_sensor_i2c_type data_type, + int32_t num_bytes); + /** * @io_master_info: I2C/SPI master information * From 5aa8af341f5d1b5a0a869bea41bda67bc3d69b5a Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Fri, 31 Dec 2021 10:42:00 +0800 Subject: [PATCH 31/86] camera: ois: modify active ois code modify max packet to 5. avoid buffer overflow issue. Change-Id: Idf60aeebe349dca8b7c0da3132abae74c3e892dc Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2159174 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 14 +++++++----- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 22 ++++++++++++++----- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 5 +++-- 3 files changed, 27 insertions(+), 14 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 03f06261af69..aedf8059436d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1216,6 +1216,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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 (read_length > buff_length) { CAM_ERR(CAM_SENSOR, "Invalid buffer size, readLen: %d, bufLen: %d", @@ -1244,13 +1246,13 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } mutex_lock(&(o_ctrl->vsync_mutex)); - memcpy((void *)timestampBuf, - (void *)&o_ctrl->prev_timestamp, - sizeof(uint64_t)); + memcpy((void *)timestampBuf, (void *)&o_ctrl->prev_timestamp, sizeof(uint64_t)); + + if (o_ctrl->ois_data_size <= buff_length) + memcpy((void *)read_buff, (void *)o_ctrl->ois_data, o_ctrl->ois_data_size); + else + memcpy((void *)read_buff, (void *)o_ctrl->ois_data, buff_length); - memcpy((void *)read_buff, - (void *)o_ctrl->ois_data, - sizeof(o_ctrl->ois_data)); mutex_unlock(&(o_ctrl->vsync_mutex)); } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) { size = i2c_list->i2c_settings.size; diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 2216e2e8222c..455b773b86ae 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -296,9 +296,9 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) { struct cam_ois_ctrl_t *o_ctrl = data; - int rc = 0, handled = IRQ_NONE; + int rc = 0, handled = IRQ_NONE, packet_cnt; uint64_t qtime_ns; - uint8_t *read_buff, packet_cnt, sample_cnt; + uint8_t *read_buff, sample_cnt; uint32_t k, read_len; if (!mutex_trylock(&o_ctrl->vsync_mutex)) { @@ -330,12 +330,15 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) goto release_mutex; } - memset(o_ctrl->ois_data, 0, sizeof(o_ctrl->ois_data)); + memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size); read_buff = o_ctrl->ois_data; packet_cnt = 0; sample_cnt = 0; do { + if (packet_cnt > 0) + read_buff += PACKET_BYTE; + // SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time. for (k = 0; k < PACKET_BYTE/READ_BYTE + 1; k++) { if (k == PACKET_BYTE/READ_BYTE) @@ -380,12 +383,11 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) } packet_cnt--; - read_buff += PACKET_BYTE; } while(packet_cnt); release_mutex: if (rc < 0) { - memset(o_ctrl->ois_data, 0, sizeof(o_ctrl->ois_data)); + memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size); handled = IRQ_NONE; } else handled = IRQ_HANDLED; @@ -415,12 +417,17 @@ static int cam_ois_component_bind(struct device *dev, o_ctrl->soc_info.dev_name = pdev->name; o_ctrl->ois_device_type = MSM_CAMERA_PLATFORM_DEVICE; + o_ctrl->ois_data_size = PACKET_BYTE*MAX_PACKET; + + o_ctrl->ois_data = kzalloc(o_ctrl->ois_data_size, GFP_KERNEL); + if (!o_ctrl->ois_data) + goto free_o_ctrl; o_ctrl->io_master_info.master_type = CCI_MASTER; o_ctrl->io_master_info.cci_client = kzalloc( sizeof(struct cam_sensor_cci_client), GFP_KERNEL); if (!o_ctrl->io_master_info.cci_client) - goto free_o_ctrl; + goto free_ois_data; soc_private = kzalloc(sizeof(struct cam_ois_soc_private), GFP_KERNEL); @@ -490,6 +497,8 @@ free_soc: kfree(soc_private); free_cci_client: kfree(o_ctrl->io_master_info.cci_client); +free_ois_data: + kfree(o_ctrl->ois_data); free_o_ctrl: kfree(o_ctrl); return rc; @@ -527,6 +536,7 @@ static void cam_ois_component_unbind(struct device *dev, kfree(o_ctrl->soc_info.soc_private); kfree(o_ctrl->io_master_info.cci_client); + kfree(o_ctrl->ois_data); platform_set_drvdata(pdev, NULL); v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL); kfree(o_ctrl); 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 a7425839b6ff..ace923fb978a 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -27,7 +27,7 @@ #define PACKET_ADDR 0x70B0 #define PACKET_BYTE 62 -#define MAX_PACKET 3 +#define MAX_PACKET 5 #define READ_BYTE 0xC enum cam_ois_state { @@ -155,7 +155,8 @@ struct cam_ois_ctrl_t { struct mutex vsync_mutex; struct completion ois_data_complete; bool is_first_vsync; - uint8_t ois_data[PACKET_BYTE*MAX_PACKET]; + uint8_t *ois_data; + int ois_data_size; }; /** From 86a6f14b0888f4f915254515a643c77c003b5abb Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 6 Jan 2022 14:55:49 +0800 Subject: [PATCH 32/86] camera: ois: add dw9781c packet judgement Sometimes dw9781c packet can reach to 20 for unknown reason. Add packet judgement to avoid buffer overflow. Change-Id: I6920fe1310cbf340e2e3b8c624d2c1b3400c75a0 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2163312 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Long Cheng Reviewed-by: Shuo Wang Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_core.c | 2 +- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 15 ++++++++++----- drivers/cam_sensor_module/cam_ois/cam_ois_dev.h | 1 + 3 files changed, 12 insertions(+), 6 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 aedf8059436d..cb148f775d02 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1218,7 +1218,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) CAM_DBG(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); - if (read_length > buff_length) { + if (read_length > buff_length || buff_length < PACKET_BYTE*MAX_PACKET) { CAM_ERR(CAM_SENSOR, "Invalid buffer size, readLen: %d, bufLen: %d", read_length, buff_length); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 455b773b86ae..4a225bb6c499 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -296,9 +296,9 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) { struct cam_ois_ctrl_t *o_ctrl = data; - int rc = 0, handled = IRQ_NONE, packet_cnt; + int rc = 0, handled = IRQ_NONE, packet_cnt = 0, sample_cnt = 0; uint64_t qtime_ns; - uint8_t *read_buff, sample_cnt; + uint8_t *read_buff; uint32_t k, read_len; if (!mutex_trylock(&o_ctrl->vsync_mutex)) { @@ -332,11 +332,9 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size); read_buff = o_ctrl->ois_data; - packet_cnt = 0; - sample_cnt = 0; do { - if (packet_cnt > 0) + if (packet_cnt > 0 && packet_cnt < MAX_PACKET) read_buff += PACKET_BYTE; // SM6375: CCI_VERSION_1_2_9 can only support read 0xE bytes data one time. @@ -364,6 +362,13 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) if (sample_cnt != 0) { packet_cnt = (sample_cnt + 9)/10; CAM_DBG(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); + + // we only need max 30 sample. + if (packet_cnt > MAX_PACKET || sample_cnt > MAX_SAMPLE) { + CAM_WARN(CAM_OIS,"Too many packet, skip this read"); + rc = -EINVAL; + goto release_mutex; + } } else { CAM_WARN(CAM_OIS,"No-fatal: sample data is zero, break the loop read"); goto release_mutex; 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 ace923fb978a..bb3a8df636f7 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -28,6 +28,7 @@ #define PACKET_ADDR 0x70B0 #define PACKET_BYTE 62 #define MAX_PACKET 5 +#define MAX_SAMPLE 30 #define READ_BYTE 0xC enum cam_ois_state { From f311d7c3d9009e608aec6463d0db83c14597e110 Mon Sep 17 00:00:00 2001 From: Bruno Melo Date: Thu, 6 Jan 2022 10:44:15 -0400 Subject: [PATCH 33/86] Revert "msm: camera: ife: Add ife num outport bound checks" Reverting QC patch temporarily to unblock Berlin/BerlinNA camera while we investigate its applicability. This reverts commit 45dbb6c0cde224cb333d62a9111c264367d27df2 Change-Id: I7ec6edc857787e48ebe4e5fb1405ad13604dfb36 Reviewed-on: https://gerrit.mot.com/2163860 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Monica Mabuchi Reviewed-by: Gilberto Gambugge Neto Submit-Approved: Jira Key --- .../isp_hw_mgr/hw_utils/cam_isp_packet_parser.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 7357cfd9f77b..bf059c109e43 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -124,12 +124,6 @@ static int cam_isp_update_dual_config( cpu_addr += (cmd_desc->offset / 4); dual_config = (struct cam_isp_dual_config *)cpu_addr; - if (dual_config->num_ports > size_isp_out) { - CAM_ERR(CAM_ISP, "num_ports %d more than max_vfe_out_res %d", - dual_config->num_ports, size_isp_out); - return -EINVAL; - } - if ((dual_config->num_ports * sizeof(struct cam_isp_dual_stripe_config)) > (remain_len - offsetof(struct cam_isp_dual_config, stripes))) { @@ -138,6 +132,14 @@ static int cam_isp_update_dual_config( } for (i = 0; i < dual_config->num_ports; i++) { + if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) { + CAM_ERR(CAM_ISP, + "failed update for i:%d > size_isp_out:%d", + i, size_isp_out); + rc = -EINVAL; + goto end; + } + hw_mgr_res = &res_list_isp_out[i]; if (!hw_mgr_res) { CAM_ERR(CAM_ISP, From 741a27ea0bbeccc24afa49976bb0f35982a305e7 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Fri, 7 Jan 2022 15:38:00 +0800 Subject: [PATCH 34/86] milanf: enable active eis [detail] add some condition judgement Change-Id: Idf7db283b79662084fa287a5743c8ad12f915d5b Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2164715 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 4a225bb6c499..6086557e33af 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -301,6 +301,11 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) uint8_t *read_buff; uint32_t k, read_len; + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "Invalid Args"); + return IRQ_NONE; + } + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); return IRQ_NONE; @@ -344,6 +349,11 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) else read_len = READ_BYTE; + if (read_len == 0) { + CAM_WARN(CAM_OIS, "Read length is zero, break loop read"); + break; + } + rc = camera_io_dev_ois_read_seq( &o_ctrl->io_master_info, PACKET_ADDR + k*READ_BYTE/2, @@ -377,7 +387,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) } if (sample_cnt > 10 && packet_cnt > 1) { - CAM_DBG(CAM_OIS,"more than 1 packet, clear data-ready and read next packet"); + CAM_WARN(CAM_OIS,"more than 1 packet, clear data-ready and read next packet"); rc = cam_ois_clear_data_ready(o_ctrl); udelay(1000); @@ -388,7 +398,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) } packet_cnt--; - } while(packet_cnt); + } while(packet_cnt > 0); release_mutex: if (rc < 0) { From 58847a6593067b0c61ddfa7f30b7f0c1e88b2e1f Mon Sep 17 00:00:00 2001 From: Bruno Melo Date: Fri, 7 Jan 2022 11:36:35 -0400 Subject: [PATCH 35/86] Revert "Revert "msm: camera: ife: Add ife num outport bound checks"" Adding back: msm: camera: ife: Add ife num outport bound checks. QC helped us to investigate the stability issue on Berlin/BerlinNA caused by the reverted change. ISP output number was being set incorectly on camx for Astro165. This reverts commit f3bb3c280110fb2961afac73d214f1411e0cb839 Change-Id: I3e9aac8ae3bf81ccb6ffa7434a8db609c3c76525 Reviewed-on: https://gerrit.mot.com/2165129 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Gilberto Gambugge Neto Reviewed-by: Monica Mabuchi Submit-Approved: Jira Key --- .../isp_hw_mgr/hw_utils/cam_isp_packet_parser.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index bf059c109e43..7357cfd9f77b 100644 --- a/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -124,6 +124,12 @@ static int cam_isp_update_dual_config( cpu_addr += (cmd_desc->offset / 4); dual_config = (struct cam_isp_dual_config *)cpu_addr; + if (dual_config->num_ports > size_isp_out) { + CAM_ERR(CAM_ISP, "num_ports %d more than max_vfe_out_res %d", + dual_config->num_ports, size_isp_out); + return -EINVAL; + } + if ((dual_config->num_ports * sizeof(struct cam_isp_dual_stripe_config)) > (remain_len - offsetof(struct cam_isp_dual_config, stripes))) { @@ -132,14 +138,6 @@ static int cam_isp_update_dual_config( } for (i = 0; i < dual_config->num_ports; i++) { - if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) { - CAM_ERR(CAM_ISP, - "failed update for i:%d > size_isp_out:%d", - i, size_isp_out); - rc = -EINVAL; - goto end; - } - hw_mgr_res = &res_list_isp_out[i]; if (!hw_mgr_res) { CAM_ERR(CAM_ISP, From 9fb3bd88bd6e45d381d24676288c621d7f3462b3 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 6 Jan 2022 16:56:28 +0800 Subject: [PATCH 36/86] 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 { From ca3c46daddb9e4330d7c6ed8fcc022713867173e Mon Sep 17 00:00:00 2001 From: handong Date: Wed, 19 Jan 2022 16:54:15 +0800 Subject: [PATCH 37/86] rhodec flash supplier distinguish[2/4] details: distinguish flash supplier Change-Id: I8c4692e80dc64cecb34f8d747ca40b44dea3b707 Reviewed-on: https://gerrit.mot.com/2174388 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 74 ++++++++++++++++--- .../cam_sensor/cam_sensor_dev.h | 3 + .../cam_sensor/cam_sensor_soc.c | 7 ++ include/uapi/camera/media/cam_sensor.h | 2 + 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 83578c81c00b..107365dbf6c3 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -445,12 +445,14 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sensor_probe_addr_type = probe_info->addr_type; s_ctrl->sensor_probe_data_type = probe_info->data_type; - s_ctrl->probe_sub_device = probe_info->probe_sub_device; - s_ctrl->sub_device_addr = probe_info->sub_device_addr; - s_ctrl->sub_device_data_type = probe_info->sub_device_data_type; - s_ctrl->sub_device_addr_type = probe_info->sub_device_addr_type; - s_ctrl->sub_device_id_addr = probe_info->sub_device_id_addr; - s_ctrl->expected_sub_device_id = probe_info->expected_sub_device_id; + s_ctrl->probe_sub_device = probe_info->probe_sub_device; + s_ctrl->sub_device_addr = probe_info->sub_device_addr; + s_ctrl->sub_device_data_type = probe_info->sub_device_data_type; + s_ctrl->sub_device_addr_type = probe_info->sub_device_addr_type; + s_ctrl->sub_device_id_addr = probe_info->sub_device_id_addr; + s_ctrl->expected_sub_device_id = probe_info->expected_sub_device_id; + s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master; + s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode; CAM_DBG(CAM_SENSOR, "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x", @@ -714,8 +716,11 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) { int rc = 0; + int ret = 0; uint32_t sub_device_id = 0; uint16_t sensor_address = 0; + uint16_t sensor_freq_mode = 0; + uint8_t sensor_cci_master = 0; /* if hal doesn't config ProbeSubDevice parameter in sensor xml, return success immediately */ if (!s_ctrl->probe_sub_device) { @@ -730,6 +735,32 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) s_ctrl->io_master_info.cci_client->sid = s_ctrl->sub_device_addr >> 1; } + /*if need change cci master*/ + if (s_ctrl->need_change_cci_master) { + sensor_cci_master = s_ctrl->io_master_info.cci_client->cci_i2c_master; + sensor_freq_mode = s_ctrl->io_master_info.cci_client->i2c_freq_mode; + + ret = camera_io_release(&(s_ctrl->io_master_info)); + if (ret != 0) { + CAM_ERR(CAM_SENSOR, "release sensor cci failed!"); + } + + s_ctrl->io_master_info.cci_client->cci_i2c_master = s_ctrl->sub_device_cci_master; + s_ctrl->io_master_info.cci_client->i2c_freq_mode = s_ctrl->sub_device_i2c_freq_mode; + + rc = camera_io_init(&(s_ctrl->io_master_info)); + if(rc != 0) { + ret = camera_io_release(&(s_ctrl->io_master_info)); + CAM_ERR(CAM_SENSOR, "init sensor cci failed! rc=%d, release ret=%d, try again!", rc, ret); + usleep_range(100000, 100000); + rc = camera_io_init(&(s_ctrl->io_master_info)); + if (rc != 0) { + ret = camera_io_release(&(s_ctrl->io_master_info)); + CAM_ERR(CAM_SENSOR, "try again init sensor cci failed again! rc=%d, release ret=%d", rc, ret); + } + } + } + rc = camera_io_dev_read( &(s_ctrl->io_master_info), s_ctrl->sub_device_id_addr, @@ -740,6 +771,32 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) CAM_INFO(CAM_SENSOR, "Read sub device id: 0x%x expected sub device id 0x%x:", sub_device_id, s_ctrl->expected_sub_device_id); + /* restore sensor i2c address */ + s_ctrl->io_master_info.cci_client->sid = sensor_address; + + /* reset cci master */ + if (s_ctrl->need_change_cci_master) { + ret = camera_io_release(&(s_ctrl->io_master_info)); + if (ret != 0) { + CAM_ERR(CAM_SENSOR, "release flash cci failed! "); + } + + s_ctrl->io_master_info.cci_client->cci_i2c_master = sensor_cci_master; + s_ctrl->io_master_info.cci_client->i2c_freq_mode = sensor_freq_mode; + + rc = camera_io_init(&(s_ctrl->io_master_info)); + if(rc != 0) { + ret = camera_io_release(&(s_ctrl->io_master_info)); + CAM_ERR(CAM_SENSOR, "init sensor cci failed! rc=%d, release ret=%d, try again!", rc, ret); + usleep_range(100000, 100000); + rc = camera_io_init(&(s_ctrl->io_master_info)); + if (rc != 0) { + ret = camera_io_release(&(s_ctrl->io_master_info)); + CAM_ERR(CAM_SENSOR, "try again init sensor cci failed again! rc=%d, release ret=%d", rc, ret); + } + } + } + if (sub_device_id == s_ctrl->expected_sub_device_id) { CAM_INFO(CAM_SENSOR, "Probe sub device success,slot:%d,sub_device_addr:0x%x,sub_device_id:0x%x", @@ -753,9 +810,6 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) rc = -EINVAL; } - /* restore sensor i2c address */ - s_ctrl->io_master_info.cci_client->sid = sensor_address; - return rc; } @@ -845,7 +899,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, rc = cam_sensor_match_sub_device_id(s_ctrl); if (rc < 0) { cam_sensor_power_down(s_ctrl); - msleep(20); + usleep_range(20000,20000); goto free_power_settings; } diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index c132b0a3846d..1883d1d48755 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -117,6 +117,9 @@ struct cam_sensor_ctrl_t { uint8_t sub_device_addr_type; uint16_t sub_device_id_addr; uint16_t expected_sub_device_id; + uint8_t sub_device_cci_master; + uint8_t sub_device_i2c_freq_mode; + bool need_change_cci_master; }; /** diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_soc.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_soc.c index d5cfe48223a5..dc41dacae0ea 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_soc.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_soc.c @@ -187,6 +187,13 @@ static int32_t cam_sensor_driver_get_dt_data(struct cam_sensor_ctrl_t *s_ctrl) CAM_DBG(CAM_SENSOR, "cci-index %d", s_ctrl->cci_num); } + if (of_property_read_bool(of_node, "need-change-cci-master")) { + CAM_DBG(CAM_SENSOR, "need-change-cci-master found in this imgsensor"); + s_ctrl->need_change_cci_master = true; + } else { + s_ctrl->need_change_cci_master = false; + } + if (of_property_read_u32(of_node, "sensor-position-pitch", &sensordata->pos_pitch) < 0) { CAM_DBG(CAM_SENSOR, "Invalid sensor position"); diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 49cb7da7cdfd..9dc2aee64a21 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -178,6 +178,8 @@ struct cam_cmd_probe { __u8 sub_device_addr_type; __u32 sub_device_id_addr; __u32 expected_sub_device_id; + __u8 sub_device_cci_master; + __u8 sub_device_i2c_freq_mode; } __attribute__((packed)); /** From 42b21db1fbf484a1f07c37e1d6c82006351f3f48 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 20 Jan 2022 14:13:17 +0800 Subject: [PATCH 38/86] camera: ois: read ois status in vsync thread Read ois status and mode in vsync thread. If ois is not enabled and not in move mode, skip vsync handle. Change-Id: I2ddbf839b089da75550aef03b63fe136cbd4bc43 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2175243 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 32 ++++++++++++++++++- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 2 ++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 6086557e33af..9dd1ae9bdf5c 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -300,6 +300,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) uint64_t qtime_ns; uint8_t *read_buff; uint32_t k, read_len; + uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; if (!o_ctrl) { CAM_ERR(CAM_OIS, "Invalid Args"); @@ -316,9 +317,38 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) goto release_mutex; } + rc = camera_io_dev_read( + &o_ctrl->io_master_info, + MODE_ADDR, + &mode_val, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read OIS 0x7014 reg rc: %d", rc); + goto release_mutex; + } + + rc = camera_io_dev_read( + &o_ctrl->io_master_info, + ENABLE_ADDR, + &enable_val, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read OIS 0x7015 reg rc: %d", rc); + goto release_mutex; + } + + CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); + + if (mode_val != 0 || enable_val != 0) { + CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); + goto release_mutex; + } + rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d"); + CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d", rc); goto release_mutex; } 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 b7cadb5e5367..dd69e47dd790 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -25,6 +25,8 @@ #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) +#define MODE_ADDR 0x7014 +#define ENABLE_ADDR 0x7015 #define PACKET_ADDR 0x70B0 #define PACKET_BYTE 62 #define MAX_PACKET 5 From 813ed251ffff87665f382815ab234e112cccb5d3 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Fri, 21 Jan 2022 16:18:38 +0800 Subject: [PATCH 39/86] camera: ois: use mono timestamp for ois data [detail] use mono timestamp for ois data Change-Id: Iefe79dc95bccabb431dbef24a13448b9a5aa6a1e Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2176429 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhuoran Xu Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 27 +++++++++---------- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 2 +- 2 files changed, 14 insertions(+), 15 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 37fb8ddc1b01..318b8d692030 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -115,8 +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; + o_ctrl->q_timer_cnt = QTIMER_SAMPLE_TIME*10*2; + o_ctrl->mono_timestamp = 0; soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private; @@ -582,7 +582,8 @@ static int cam_ois_write_q_timer(struct cam_ois_ctrl_t *o_ctrl) 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; + uint64_t mono_time_ns = 0; + struct timespec64 ts; if (!o_ctrl) { CAM_ERR(CAM_OIS, "Invalid Args"); @@ -601,14 +602,12 @@ static int cam_ois_write_q_timer(struct cam_ois_ctrl_t *o_ctrl) 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; + ktime_get_boottime_ts64(&ts); + mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); + o_ctrl->mono_timestamp = mono_time_ns; } - CAM_DBG(CAM_OIS,"Write Q-timer %d, timestamp %lld", data, qtime_ns); + CAM_DBG(CAM_OIS,"Write Q-timer %d, mono timestamp %lld", data, mono_time_ns); return rc; } @@ -1473,17 +1472,17 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } delta_timestamp_ns = (o_ctrl->q_timer_cnt - latest_data_ts)*100000; - o_ctrl->q_timer_timestamp -= delta_timestamp_ns; // latest ois data timestamp + o_ctrl->mono_timestamp -= delta_timestamp_ns; // latest ois data timestamp - if (o_ctrl->q_timer_timestamp == 0) { - CAM_ERR(CAM_OIS, "q_timer_timestamp is zero."); + if (o_ctrl->mono_timestamp == 0) { + CAM_ERR(CAM_OIS, "mono_timestamp is zero."); delete_request(&i2c_read_settings); return -EINVAL; } - CAM_DBG(CAM_OIS,"latest ois data timestamp %lld", o_ctrl->q_timer_timestamp); + CAM_DBG(CAM_OIS,"latest ois data mono timestamp %lld", o_ctrl->mono_timestamp); - memcpy((void *)timestampBuf, (void *)&o_ctrl->q_timer_timestamp, sizeof(uint64_t)); + memcpy((void *)timestampBuf, (void *)&o_ctrl->mono_timestamp, sizeof(uint64_t)); } } rc = delete_request(&i2c_read_settings); 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 dd69e47dd790..227c0e8377c6 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -165,7 +165,7 @@ struct cam_ois_ctrl_t { uint8_t *ois_data; int ois_data_size; uint16_t q_timer_cnt; - uint64_t q_timer_timestamp; + uint64_t mono_timestamp; }; /** From 87030b06d3f300423328b8f7072eb84c190a4aa0 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Fri, 21 Jan 2022 12:22:21 +0800 Subject: [PATCH 40/86] camera: ois: change timestamp type [detail] Change Qtimer timestap to mono timestamp. Change-Id: I6684b4b50f26d103521db21427da73e84799b85f Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2176215 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 9dd1ae9bdf5c..95414b9a0976 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -297,7 +297,8 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) { struct cam_ois_ctrl_t *o_ctrl = data; int rc = 0, handled = IRQ_NONE, packet_cnt = 0, sample_cnt = 0; - uint64_t qtime_ns; + uint64_t mono_time_ns; + struct timespec64 ts; uint8_t *read_buff; uint32_t k, read_len; uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; @@ -346,16 +347,13 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) goto release_mutex; } - rc = cam_sensor_util_get_current_qtimer_ns(&qtime_ns); - if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to get qtimer rc:%d", rc); - goto release_mutex; - } + ktime_get_boottime_ts64(&ts); + mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); - CAM_DBG(CAM_OIS, "vsync sof timestamp is %lld", qtime_ns); + CAM_DBG(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns); o_ctrl->prev_timestamp = o_ctrl->curr_timestamp; - o_ctrl->curr_timestamp = qtime_ns; + o_ctrl->curr_timestamp = mono_time_ns; // when the first vsync arrived, clear data-ready, and return. if (o_ctrl->is_first_vsync) { From a73de5791a25c6c5d325bcdc66b8b2673a1f0ac8 Mon Sep 17 00:00:00 2001 From: liuzy55 Date: Tue, 25 Jan 2022 20:16:36 +0800 Subject: [PATCH 41/86] rhodep: add ois_reset after download fw details: add ois_reset Change-Id: I1a542a5dd4552d544ab044485ce7049a77e408a4 Signed-off-by: liuzy55 Reviewed-on: https://gerrit.mot.com/2178679 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Zhichao Chen Reviewed-by: Tested-by: Jira Key Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c index 752920e203c3..b977eef2fc71 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9781.c @@ -316,6 +316,7 @@ void dw9781_post_firmware_download(struct camera_io_master * io_master_info, con CAM_ERR(CAM_OIS, "[dw9781c] change dw9781c state to shutdown mode"); } else { CAM_DBG(CAM_OIS, "[dw9781c] Firmware download succes..."); + dw9781_ois_reset(io_master_info); } return; From de858431fab2f3382c56a7271dd99b910249f4cd Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 26 Jan 2022 15:13:30 +0800 Subject: [PATCH 42/86] camera: ois: disable ois vsync irq in factory build [detail] disable ois vsync irq in factory build Change-Id: I047fe7425f5153dd4034d573643cb2b37813bcdf Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2179329 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: gaoyx9 --- drivers/cam_sensor_module/cam_ois/cam_ois_soc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c index 59af6b297bd2..f8f1eefe5f0b 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c @@ -40,6 +40,11 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl) } else { o_ctrl->is_ois_vsync_irq_supported = true; } + +#ifdef CONFIG_CAMERA_DISABLE_VSYNC_IRQ + o_ctrl->is_ois_vsync_irq_supported = false; + CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build"); +#endif CAM_DBG(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); rc = cam_soc_util_get_dt_properties(soc_info); From 01ccb7d2782a53abec6e32228d94b46ebc3d4954 Mon Sep 17 00:00:00 2001 From: liuzy55 Date: Tue, 8 Feb 2022 17:56:36 +0800 Subject: [PATCH 43/86] rhodep: open camera debug ois log details: modify CAM_DBG to CAM_INFO Change-Id: Iebd6265277bccb34df5e8aca8d44bfc1caf5d684 Signed-off-by: liuzy55 Reviewed-on: https://gerrit.mot.com/2185462 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Xingyun Fu Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 50 +++++++++---------- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 20 ++++---- .../cam_sensor_module/cam_ois/cam_ois_soc.c | 8 +-- 3 files changed, 39 insertions(+), 39 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 318b8d692030..2ef322c18f2c 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -96,7 +96,7 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; - CAM_DBG(CAM_OIS, "Device Handle: %d", ois_acq_dev.device_handle); + CAM_INFO(CAM_OIS, "Device Handle: %d", ois_acq_dev.device_handle); if (copy_to_user(u64_to_user_ptr(cmd->handle), &ois_acq_dev, sizeof(struct cam_sensor_acquire_dev))) { CAM_ERR(CAM_OIS, "ACQUIRE_DEV: copy to user failed"); @@ -249,7 +249,7 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set) return -EINVAL; } for (i = 0; i < size; i++) { - CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x", + CAM_INFO(CAM_OIS, "time: reg_data[%d]: 0x%x", i, (qtime_ns & 0xFF)); i2c_list->i2c_settings.reg_setting[i].reg_data = (qtime_ns & 0xFF); @@ -361,11 +361,11 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->io_master_info.cci_client->id_map = 0; memcpy(&(o_ctrl->opcode), &(ois_info->opcode), sizeof(struct cam_ois_opcode)); - CAM_DBG(CAM_OIS, "Slave addr: 0x%x Freq Mode: %d", + CAM_INFO(CAM_OIS, "Slave addr: 0x%x Freq Mode: %d", ois_info->slave_addr, ois_info->i2c_freq_mode); } else if (o_ctrl->io_master_info.master_type == I2C_MASTER) { o_ctrl->io_master_info.client->addr = ois_info->slave_addr; - CAM_DBG(CAM_OIS, "Slave addr: 0x%x", ois_info->slave_addr); + CAM_INFO(CAM_OIS, "Slave addr: 0x%x", ois_info->slave_addr); } else { CAM_ERR(CAM_OIS, "Invalid Master type : %d", o_ctrl->io_master_info.master_type); @@ -431,7 +431,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) return -ENOMEM; } - CAM_DBG(CAM_OIS, "fw len: %d, addr_type: %d, data_type: %d, chunck: %d, ois_fw_data_type:%d", total_bytes, + CAM_INFO(CAM_OIS, "fw len: %d, addr_type: %d, data_type: %d, chunck: %d, ois_fw_data_type:%d", total_bytes, i2c_reg_setting.addr_type, i2c_reg_setting.data_type, txn_data_size, @@ -457,7 +457,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) } i2c_reg_setting.reg_setting[packet_idx].delay = 0; i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; - CAM_DBG(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", + CAM_INFO(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", i2c_reg_setting.reg_setting[packet_idx].reg_addr, i2c_reg_setting.reg_setting[packet_idx].reg_data, (ptr-(uint8_t *)fw->data)); @@ -475,7 +475,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) goto release_firmware; } total_idx += packet_idx*o_ctrl->ois_fw_data_type; - CAM_DBG(CAM_OIS, "packet_idx: %d, total_idx: %d", packet_idx, total_idx); + CAM_INFO(CAM_OIS, "packet_idx: %d, total_idx: %d", packet_idx, total_idx); } if (strstr(o_ctrl->ois_name, "dw9781")) { @@ -510,7 +510,7 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) } if (strstr(o_ctrl->ois_name, "dw9781")) { - CAM_DBG(CAM_OIS, "not need download coeff fw!"); + CAM_INFO(CAM_OIS, "not need download coeff fw!"); return 0; } @@ -607,7 +607,7 @@ static int cam_ois_write_q_timer(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->mono_timestamp = mono_time_ns; } - CAM_DBG(CAM_OIS,"Write Q-timer %d, mono timestamp %lld", data, mono_time_ns); + CAM_INFO(CAM_OIS,"Write Q-timer %d, mono timestamp %lld", data, mono_time_ns); return rc; } @@ -721,7 +721,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) break; case CAMERA_SENSOR_CMD_TYPE_PWR_UP: case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN: - CAM_DBG(CAM_OIS, + CAM_INFO(CAM_OIS, "Received power settings buffer"); rc = cam_sensor_update_power_settings( cmd_buf, @@ -735,7 +735,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) break; default: if (o_ctrl->i2c_init_data.is_settings_valid == 0) { - CAM_DBG(CAM_OIS, + CAM_INFO(CAM_OIS, "Received init settings"); i2c_reg_settings = &(o_ctrl->i2c_init_data); @@ -752,7 +752,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_preprog_flag) != 0) && o_ctrl->i2c_preprog_data.is_settings_valid == 0) { - CAM_DBG(CAM_OIS, "Received PreProg Settings"); + CAM_INFO(CAM_OIS, "Received PreProg Settings"); i2c_reg_settings = &(o_ctrl->i2c_preprog_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -766,7 +766,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_precoeff_flag) != 0) && o_ctrl->i2c_precoeff_data.is_settings_valid == 0) { - CAM_DBG(CAM_OIS, "Received PreCoeff Settings"); + CAM_INFO(CAM_OIS, "Received PreCoeff Settings"); i2c_reg_settings = &(o_ctrl->i2c_precoeff_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -781,7 +781,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } else if ((o_ctrl->is_ois_calib != 0) && (o_ctrl->i2c_calib_data.is_settings_valid == 0)) { - CAM_DBG(CAM_OIS, + CAM_INFO(CAM_OIS, "Received calib settings"); i2c_reg_settings = &(o_ctrl->i2c_calib_data); i2c_reg_settings->is_settings_valid = 1; @@ -797,7 +797,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_postcalib_flag) != 0) && o_ctrl->i2c_postcalib_data.is_settings_valid == 0) { - CAM_DBG(CAM_OIS, "Received PostCalib Settings"); + CAM_INFO(CAM_OIS, "Received PostCalib Settings"); i2c_reg_settings = &(o_ctrl->i2c_postcalib_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -883,7 +883,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } if (o_ctrl->ois_postcalib_flag) { - CAM_DBG(CAM_OIS, "starting post calib data"); + CAM_INFO(CAM_OIS, "starting post calib data"); rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_postcalib_data); if (rc) { @@ -969,7 +969,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_DBG(CAM_OIS, "number of I/O configs: %d:", + CAM_INFO(CAM_OIS, "number of I/O configs: %d:", csl_packet->num_io_configs); if (csl_packet->num_io_configs == 0) { CAM_ERR(CAM_OIS, "No I/O configs to process"); @@ -1091,7 +1091,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_DBG(CAM_OIS, "number of I/O configs: %d:", + CAM_INFO(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"); @@ -1190,7 +1190,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_DBG(CAM_OIS, "number of I/O configs: %d:", + CAM_INFO(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"); @@ -1253,7 +1253,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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); + CAM_INFO(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); if (read_length > buff_length || buff_length < PACKET_BYTE*MAX_PACKET) { CAM_ERR(CAM_SENSOR, @@ -1340,7 +1340,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_DBG(CAM_OIS, "number of I/O configs: %d:", + CAM_INFO(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"); @@ -1401,7 +1401,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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); + CAM_INFO(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); @@ -1447,7 +1447,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) 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", + CAM_INFO(CAM_OIS, "flag = %d, sample_cnt = %d, latest_data_ts = %d", flag, sample_cnt, latest_data_ts); if (flag != 0x2 && flag != 0x3) { @@ -1480,7 +1480,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return -EINVAL; } - CAM_DBG(CAM_OIS,"latest ois data mono timestamp %lld", o_ctrl->mono_timestamp); + CAM_INFO(CAM_OIS,"latest ois data mono timestamp %lld", o_ctrl->mono_timestamp); memcpy((void *)timestampBuf, (void *)&o_ctrl->mono_timestamp, sizeof(uint64_t)); } @@ -1592,7 +1592,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = -EFAULT; goto release_mutex; } - CAM_DBG(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); + CAM_INFO(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); break; case CAM_ACQUIRE_DEV: rc = cam_ois_get_dev_handle(o_ctrl, arg); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 95414b9a0976..a506168cfb2e 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -28,7 +28,7 @@ static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl) CAM_ERR(CAM_OIS, "Failed in Applying i2c wrt settings"); } - CAM_DBG(CAM_OIS,"Clear data-ready success"); + CAM_INFO(CAM_OIS,"Clear data-ready success"); return rc; } @@ -56,7 +56,7 @@ static int cam_ois_subdev_close(struct v4l2_subdev *sd, bool crm_active = cam_req_mgr_is_open(CAM_OIS); if (crm_active) { - CAM_DBG(CAM_OIS, "CRM is ACTIVE, close should be from CRM"); + CAM_INFO(CAM_OIS, "CRM is ACTIVE, close should be from CRM"); return 0; } @@ -340,17 +340,17 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) goto release_mutex; } - CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); + CAM_INFO(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); if (mode_val != 0 || enable_val != 0) { - CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); + CAM_INFO(CAM_OIS, "ois is not in move mode, skip this irq"); goto release_mutex; } ktime_get_boottime_ts64(&ts); mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); - CAM_DBG(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns); + CAM_INFO(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns); o_ctrl->prev_timestamp = o_ctrl->curr_timestamp; o_ctrl->curr_timestamp = mono_time_ns; @@ -399,7 +399,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) sample_cnt = read_buff[1]; if (sample_cnt != 0) { packet_cnt = (sample_cnt + 9)/10; - CAM_DBG(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); + CAM_INFO(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); // we only need max 30 sample. if (packet_cnt > MAX_PACKET || sample_cnt > MAX_SAMPLE) { @@ -515,7 +515,7 @@ static int cam_ois_component_bind(struct device *dev, o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); if (o_ctrl->vsync_irq > 0) { - CAM_DBG(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); + CAM_INFO(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); rc = devm_request_threaded_irq(dev, o_ctrl->vsync_irq, @@ -527,12 +527,12 @@ static int cam_ois_component_bind(struct device *dev, if (rc != 0) CAM_ERR(CAM_OIS, "failed: to request ois-vsync IRQ %d, rc %d", o_ctrl->vsync_irq, rc); else - CAM_DBG(CAM_OIS, "request ois-vsync IRQ success"); + CAM_INFO(CAM_OIS, "request ois-vsync IRQ success"); } else CAM_ERR(CAM_OIS, "failed: to get ois-vsync IRQ"); } - CAM_DBG(CAM_OIS, "Component bound successfully"); + CAM_INFO(CAM_OIS, "Component bound successfully"); return rc; unreg_subdev: cam_unregister_subdev(&(o_ctrl->v4l2_dev_str)); @@ -595,7 +595,7 @@ static int32_t cam_ois_platform_driver_probe( { int rc = 0; - CAM_DBG(CAM_OIS, "Adding OIS Sensor component"); + CAM_INFO(CAM_OIS, "Adding OIS Sensor component"); rc = component_add(&pdev->dev, &cam_ois_component_ops); if (rc) CAM_ERR(CAM_OIS, "failed to add component rc: %d", rc); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c index f8f1eefe5f0b..8e77f3e7ea6a 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c @@ -45,7 +45,7 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->is_ois_vsync_irq_supported = false; CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build"); #endif - CAM_DBG(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); + CAM_INFO(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); rc = cam_soc_util_get_dt_properties(soc_info); if (rc < 0) { @@ -116,7 +116,7 @@ int cam_ois_driver_soc_init(struct cam_ois_ctrl_t *o_ctrl) rc = of_property_read_u32(of_node, "cci-master", &o_ctrl->cci_i2c_master); if (rc < 0) { - CAM_DBG(CAM_OIS, "failed rc %d", rc); + CAM_INFO(CAM_OIS, "failed rc %d", rc); return rc; } @@ -127,13 +127,13 @@ int cam_ois_driver_soc_init(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->cci_num = CCI_DEVICE_0; o_ctrl->io_master_info.cci_client->cci_device = o_ctrl->cci_num; - CAM_DBG(CAM_OIS, "cci-device %d", o_ctrl->cci_num, rc); + CAM_INFO(CAM_OIS, "cci-device %d", o_ctrl->cci_num, rc); } rc = cam_ois_get_dt_data(o_ctrl); if (rc < 0) - CAM_DBG(CAM_OIS, "failed: ois get dt data rc %d", rc); + CAM_INFO(CAM_OIS, "failed: ois get dt data rc %d", rc); return rc; } From 300796df8ae37b84545f627551b895e3a09b4038 Mon Sep 17 00:00:00 2001 From: liuzy55 Date: Fri, 11 Feb 2022 11:11:15 +0800 Subject: [PATCH 44/86] rhodec: Actuator noise reduction detalis: add MOT_DEVICE_RHODEC for workaround Change-Id: I5d24bb79f95a11f82781bd40ba14cbd64cadfa22 Signed-off-by: liuzy55 Reviewed-on: https://gerrit.mot.com/2188603 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: XiaoFeng Wang Reviewed-by: Shuo Wang Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Tested-by: Jira Key Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 2c289c232085..fe036ce1bbf6 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -63,6 +63,7 @@ typedef enum { MOT_DEVICE_CORFUP, MOT_DEVICE_CORFUQ, MOT_DEVICE_CORFUR, + MOT_DEVICE_RHODEC, MOT_DEVICE_NUM, } mot_dev_type; @@ -444,6 +445,32 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, }, + + { + .dev_type = MOT_DEVICE_RHODEC, + .actuator_num = 1, + .dev_name = "rhodec", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"pm6125_l9", "cam_rear_af"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, }; static uint32_t mot_device_index = MOT_DEVICE_NUM; From 9fba93b60ca0afc9e651138d5930a084c61a7a9a Mon Sep 17 00:00:00 2001 From: liuzy55 Date: Wed, 16 Feb 2022 14:44:34 +0800 Subject: [PATCH 45/86] rhodec: fixed macro camera not being opened detalis: switch the cci device to read the flash ID Change-Id: Idf29474ca4946afb122339eeefe01b7dacfc0485 Signed-off-by: liuzy55 Reviewed-on: https://gerrit.mot.com/2191857 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Long Cheng Tested-by: Jira Key Reviewed-by: XiaoFeng Wang Reviewed-by: Shuo Wang Reviewed-by: Xingyun Fu Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c | 8 ++++++++ drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h | 1 + include/uapi/camera/media/cam_sensor.h | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 107365dbf6c3..867716f505db 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -452,6 +452,7 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sub_device_id_addr = probe_info->sub_device_id_addr; s_ctrl->expected_sub_device_id = probe_info->expected_sub_device_id; s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master; + s_ctrl->sub_device_cci_device = probe_info->sub_device_cci_device; s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode; CAM_DBG(CAM_SENSOR, @@ -721,6 +722,7 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) uint16_t sensor_address = 0; uint16_t sensor_freq_mode = 0; uint8_t sensor_cci_master = 0; + uint8_t sensor_cci_device = 0; /* if hal doesn't config ProbeSubDevice parameter in sensor xml, return success immediately */ if (!s_ctrl->probe_sub_device) { @@ -739,6 +741,7 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) if (s_ctrl->need_change_cci_master) { sensor_cci_master = s_ctrl->io_master_info.cci_client->cci_i2c_master; sensor_freq_mode = s_ctrl->io_master_info.cci_client->i2c_freq_mode; + sensor_cci_device = s_ctrl->io_master_info.cci_client->cci_device; ret = camera_io_release(&(s_ctrl->io_master_info)); if (ret != 0) { @@ -748,6 +751,10 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) s_ctrl->io_master_info.cci_client->cci_i2c_master = s_ctrl->sub_device_cci_master; s_ctrl->io_master_info.cci_client->i2c_freq_mode = s_ctrl->sub_device_i2c_freq_mode; + if(s_ctrl->io_master_info.cci_client->cci_device != s_ctrl->sub_device_cci_device) + { + s_ctrl->io_master_info.cci_client->cci_device = s_ctrl->sub_device_cci_device; + } rc = camera_io_init(&(s_ctrl->io_master_info)); if(rc != 0) { ret = camera_io_release(&(s_ctrl->io_master_info)); @@ -783,6 +790,7 @@ int cam_sensor_match_sub_device_id(struct cam_sensor_ctrl_t *s_ctrl) s_ctrl->io_master_info.cci_client->cci_i2c_master = sensor_cci_master; s_ctrl->io_master_info.cci_client->i2c_freq_mode = sensor_freq_mode; + s_ctrl->io_master_info.cci_client->cci_device = sensor_cci_device; rc = camera_io_init(&(s_ctrl->io_master_info)); if(rc != 0) { diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index 1883d1d48755..faf8fc8c8eab 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -118,6 +118,7 @@ struct cam_sensor_ctrl_t { uint16_t sub_device_id_addr; uint16_t expected_sub_device_id; uint8_t sub_device_cci_master; + uint8_t sub_device_cci_device; uint8_t sub_device_i2c_freq_mode; bool need_change_cci_master; }; diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 9dc2aee64a21..3df242f29044 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -179,6 +179,7 @@ struct cam_cmd_probe { __u32 sub_device_id_addr; __u32 expected_sub_device_id; __u8 sub_device_cci_master; + __u8 sub_device_cci_device; __u8 sub_device_i2c_freq_mode; } __attribute__((packed)); From fec34e29a50365a3421a81536efbaa97885c390d Mon Sep 17 00:00:00 2001 From: Xiaojie Liu Date: Thu, 24 Feb 2022 19:26:55 +0800 Subject: [PATCH 46/86] msm: camera: icp: fix memory overflow to slove ramdump increase flush_req_pending's number to slove memory overflow CRs-Fixed: 05724712 Mot-CRs-fixed: (CR) Signed-off-by: Xiaojie Liu Change-Id: Ifab545c0705cf18f3c479e14e6d66f815aac4f60 Reviewed-on: https://gerrit.mot.com/2200505 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zilong Zhang Reviewed-by: Lei Wang Reviewed-by: Reviewed-by: Zhuoran Xu Submit-Approved: Jira Key --- drivers/cam_core/cam_hw_mgr_intf.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/cam_core/cam_hw_mgr_intf.h b/drivers/cam_core/cam_hw_mgr_intf.h index 2b56d21b20be..22864250ca67 100644 --- a/drivers/cam_core/cam_hw_mgr_intf.h +++ b/drivers/cam_core/cam_hw_mgr_intf.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_HW_MGR_INTF_H_ @@ -26,6 +27,12 @@ /* Maximum reg dump cmd buffer entries in a context */ #define CAM_REG_DUMP_MAX_BUF_ENTRIES 10 +/* + * This value should align with MAX requests supported by + * hw modules like ICP, IFE, JPEG etc. + */ +#define CAM_MAX_FLUSH_REQS 40 + /** * enum cam_context_dump_id - * context dump type @@ -289,9 +296,9 @@ struct cam_hw_config_args { struct cam_hw_flush_args { void *ctxt_to_hw_map; uint32_t num_req_pending; - void *flush_req_pending[20]; + void *flush_req_pending[CAM_MAX_FLUSH_REQS]; uint32_t num_req_active; - void *flush_req_active[20]; + void *flush_req_active[CAM_MAX_FLUSH_REQS]; enum flush_type_t flush_type; uint32_t last_flush_req; }; From 2f54a392122132f67e774ccfbad488ca06a9d653 Mon Sep 17 00:00:00 2001 From: liuzy55 Date: Mon, 7 Mar 2022 00:45:28 -0600 Subject: [PATCH 47/86] rhodep: Revert "(CR): rhodep: open camera debug ois log" This reverts commit 69bc63863b2db2b8fb8f5e24644147a13d68b024. Change-Id: I788daed45da882c3db2b4492c0b0e9de29474564 Signed-off-by: liuzy55 Reviewed-on: https://gerrit.mot.com/2208633 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: XiaoFeng Wang Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 50 +++++++++---------- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 20 ++++---- .../cam_sensor_module/cam_ois/cam_ois_soc.c | 8 +-- 3 files changed, 39 insertions(+), 39 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 2ef322c18f2c..318b8d692030 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -96,7 +96,7 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; - CAM_INFO(CAM_OIS, "Device Handle: %d", ois_acq_dev.device_handle); + CAM_DBG(CAM_OIS, "Device Handle: %d", ois_acq_dev.device_handle); if (copy_to_user(u64_to_user_ptr(cmd->handle), &ois_acq_dev, sizeof(struct cam_sensor_acquire_dev))) { CAM_ERR(CAM_OIS, "ACQUIRE_DEV: copy to user failed"); @@ -249,7 +249,7 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set) return -EINVAL; } for (i = 0; i < size; i++) { - CAM_INFO(CAM_OIS, "time: reg_data[%d]: 0x%x", + 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); @@ -361,11 +361,11 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl, o_ctrl->io_master_info.cci_client->id_map = 0; memcpy(&(o_ctrl->opcode), &(ois_info->opcode), sizeof(struct cam_ois_opcode)); - CAM_INFO(CAM_OIS, "Slave addr: 0x%x Freq Mode: %d", + CAM_DBG(CAM_OIS, "Slave addr: 0x%x Freq Mode: %d", ois_info->slave_addr, ois_info->i2c_freq_mode); } else if (o_ctrl->io_master_info.master_type == I2C_MASTER) { o_ctrl->io_master_info.client->addr = ois_info->slave_addr; - CAM_INFO(CAM_OIS, "Slave addr: 0x%x", ois_info->slave_addr); + CAM_DBG(CAM_OIS, "Slave addr: 0x%x", ois_info->slave_addr); } else { CAM_ERR(CAM_OIS, "Invalid Master type : %d", o_ctrl->io_master_info.master_type); @@ -431,7 +431,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) return -ENOMEM; } - CAM_INFO(CAM_OIS, "fw len: %d, addr_type: %d, data_type: %d, chunck: %d, ois_fw_data_type:%d", total_bytes, + CAM_DBG(CAM_OIS, "fw len: %d, addr_type: %d, data_type: %d, chunck: %d, ois_fw_data_type:%d", total_bytes, i2c_reg_setting.addr_type, i2c_reg_setting.data_type, txn_data_size, @@ -457,7 +457,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) } i2c_reg_setting.reg_setting[packet_idx].delay = 0; i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; - CAM_INFO(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", + CAM_DBG(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", i2c_reg_setting.reg_setting[packet_idx].reg_addr, i2c_reg_setting.reg_setting[packet_idx].reg_data, (ptr-(uint8_t *)fw->data)); @@ -475,7 +475,7 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) goto release_firmware; } total_idx += packet_idx*o_ctrl->ois_fw_data_type; - CAM_INFO(CAM_OIS, "packet_idx: %d, total_idx: %d", packet_idx, total_idx); + CAM_DBG(CAM_OIS, "packet_idx: %d, total_idx: %d", packet_idx, total_idx); } if (strstr(o_ctrl->ois_name, "dw9781")) { @@ -510,7 +510,7 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) } if (strstr(o_ctrl->ois_name, "dw9781")) { - CAM_INFO(CAM_OIS, "not need download coeff fw!"); + CAM_DBG(CAM_OIS, "not need download coeff fw!"); return 0; } @@ -607,7 +607,7 @@ static int cam_ois_write_q_timer(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->mono_timestamp = mono_time_ns; } - CAM_INFO(CAM_OIS,"Write Q-timer %d, mono timestamp %lld", data, mono_time_ns); + CAM_DBG(CAM_OIS,"Write Q-timer %d, mono timestamp %lld", data, mono_time_ns); return rc; } @@ -721,7 +721,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) break; case CAMERA_SENSOR_CMD_TYPE_PWR_UP: case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN: - CAM_INFO(CAM_OIS, + CAM_DBG(CAM_OIS, "Received power settings buffer"); rc = cam_sensor_update_power_settings( cmd_buf, @@ -735,7 +735,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) break; default: if (o_ctrl->i2c_init_data.is_settings_valid == 0) { - CAM_INFO(CAM_OIS, + CAM_DBG(CAM_OIS, "Received init settings"); i2c_reg_settings = &(o_ctrl->i2c_init_data); @@ -752,7 +752,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_preprog_flag) != 0) && o_ctrl->i2c_preprog_data.is_settings_valid == 0) { - CAM_INFO(CAM_OIS, "Received PreProg Settings"); + CAM_DBG(CAM_OIS, "Received PreProg Settings"); i2c_reg_settings = &(o_ctrl->i2c_preprog_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -766,7 +766,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_precoeff_flag) != 0) && o_ctrl->i2c_precoeff_data.is_settings_valid == 0) { - CAM_INFO(CAM_OIS, "Received PreCoeff Settings"); + CAM_DBG(CAM_OIS, "Received PreCoeff Settings"); i2c_reg_settings = &(o_ctrl->i2c_precoeff_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -781,7 +781,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } else if ((o_ctrl->is_ois_calib != 0) && (o_ctrl->i2c_calib_data.is_settings_valid == 0)) { - CAM_INFO(CAM_OIS, + CAM_DBG(CAM_OIS, "Received calib settings"); i2c_reg_settings = &(o_ctrl->i2c_calib_data); i2c_reg_settings->is_settings_valid = 1; @@ -797,7 +797,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } } else if (((o_ctrl->ois_postcalib_flag) != 0) && o_ctrl->i2c_postcalib_data.is_settings_valid == 0) { - CAM_INFO(CAM_OIS, "Received PostCalib Settings"); + CAM_DBG(CAM_OIS, "Received PostCalib Settings"); i2c_reg_settings = &(o_ctrl->i2c_postcalib_data); i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser( @@ -883,7 +883,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } if (o_ctrl->ois_postcalib_flag) { - CAM_INFO(CAM_OIS, "starting post calib data"); + CAM_DBG(CAM_OIS, "starting post calib data"); rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_postcalib_data); if (rc) { @@ -969,7 +969,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_INFO(CAM_OIS, "number of I/O configs: %d:", + CAM_DBG(CAM_OIS, "number of I/O configs: %d:", csl_packet->num_io_configs); if (csl_packet->num_io_configs == 0) { CAM_ERR(CAM_OIS, "No I/O configs to process"); @@ -1091,7 +1091,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_INFO(CAM_OIS, "number of I/O configs: %d:", + 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"); @@ -1190,7 +1190,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_INFO(CAM_OIS, "number of I/O configs: %d:", + 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"); @@ -1253,7 +1253,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) buff_length = i2c_list->i2c_settings.read_buff_len; read_length = i2c_list->i2c_settings.size; - CAM_INFO(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); + CAM_DBG(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); if (read_length > buff_length || buff_length < PACKET_BYTE*MAX_PACKET) { CAM_ERR(CAM_SENSOR, @@ -1340,7 +1340,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } - CAM_INFO(CAM_OIS, "number of I/O configs: %d:", + 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"); @@ -1401,7 +1401,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) buff_length = i2c_list->i2c_settings.read_buff_len; read_length = i2c_list->i2c_settings.size; - CAM_INFO(CAM_OIS, "buff_length = %d, read_length = %d", buff_length, read_length); + 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); @@ -1447,7 +1447,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) sample_cnt = ((read_buff[0] & 0xF) << 8) | read_buff[1]; latest_data_ts = (read_buff[2] << 8) | read_buff[3]; - CAM_INFO(CAM_OIS, "flag = %d, sample_cnt = %d, latest_data_ts = %d", + CAM_DBG(CAM_OIS, "flag = %d, sample_cnt = %d, latest_data_ts = %d", flag, sample_cnt, latest_data_ts); if (flag != 0x2 && flag != 0x3) { @@ -1480,7 +1480,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return -EINVAL; } - CAM_INFO(CAM_OIS,"latest ois data mono timestamp %lld", o_ctrl->mono_timestamp); + CAM_DBG(CAM_OIS,"latest ois data mono timestamp %lld", o_ctrl->mono_timestamp); memcpy((void *)timestampBuf, (void *)&o_ctrl->mono_timestamp, sizeof(uint64_t)); } @@ -1592,7 +1592,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = -EFAULT; goto release_mutex; } - CAM_INFO(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); + CAM_DBG(CAM_OIS, "ois_cap: ID: %d", ois_cap.slot_info); break; case CAM_ACQUIRE_DEV: rc = cam_ois_get_dev_handle(o_ctrl, arg); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index a506168cfb2e..95414b9a0976 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -28,7 +28,7 @@ static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl) CAM_ERR(CAM_OIS, "Failed in Applying i2c wrt settings"); } - CAM_INFO(CAM_OIS,"Clear data-ready success"); + CAM_DBG(CAM_OIS,"Clear data-ready success"); return rc; } @@ -56,7 +56,7 @@ static int cam_ois_subdev_close(struct v4l2_subdev *sd, bool crm_active = cam_req_mgr_is_open(CAM_OIS); if (crm_active) { - CAM_INFO(CAM_OIS, "CRM is ACTIVE, close should be from CRM"); + CAM_DBG(CAM_OIS, "CRM is ACTIVE, close should be from CRM"); return 0; } @@ -340,17 +340,17 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) goto release_mutex; } - CAM_INFO(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); + CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); if (mode_val != 0 || enable_val != 0) { - CAM_INFO(CAM_OIS, "ois is not in move mode, skip this irq"); + CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); goto release_mutex; } ktime_get_boottime_ts64(&ts); mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); - CAM_INFO(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns); + CAM_DBG(CAM_OIS, "vsync sof mono timestamp is %lld", mono_time_ns); o_ctrl->prev_timestamp = o_ctrl->curr_timestamp; o_ctrl->curr_timestamp = mono_time_ns; @@ -399,7 +399,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) sample_cnt = read_buff[1]; if (sample_cnt != 0) { packet_cnt = (sample_cnt + 9)/10; - CAM_INFO(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); + CAM_DBG(CAM_OIS,"sample data = 0x%x, packet_cnt = %d", sample_cnt, packet_cnt); // we only need max 30 sample. if (packet_cnt > MAX_PACKET || sample_cnt > MAX_SAMPLE) { @@ -515,7 +515,7 @@ static int cam_ois_component_bind(struct device *dev, o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); if (o_ctrl->vsync_irq > 0) { - CAM_INFO(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); + CAM_DBG(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); rc = devm_request_threaded_irq(dev, o_ctrl->vsync_irq, @@ -527,12 +527,12 @@ static int cam_ois_component_bind(struct device *dev, if (rc != 0) CAM_ERR(CAM_OIS, "failed: to request ois-vsync IRQ %d, rc %d", o_ctrl->vsync_irq, rc); else - CAM_INFO(CAM_OIS, "request ois-vsync IRQ success"); + CAM_DBG(CAM_OIS, "request ois-vsync IRQ success"); } else CAM_ERR(CAM_OIS, "failed: to get ois-vsync IRQ"); } - CAM_INFO(CAM_OIS, "Component bound successfully"); + CAM_DBG(CAM_OIS, "Component bound successfully"); return rc; unreg_subdev: cam_unregister_subdev(&(o_ctrl->v4l2_dev_str)); @@ -595,7 +595,7 @@ static int32_t cam_ois_platform_driver_probe( { int rc = 0; - CAM_INFO(CAM_OIS, "Adding OIS Sensor component"); + CAM_DBG(CAM_OIS, "Adding OIS Sensor component"); rc = component_add(&pdev->dev, &cam_ois_component_ops); if (rc) CAM_ERR(CAM_OIS, "failed to add component rc: %d", rc); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c index 8e77f3e7ea6a..f8f1eefe5f0b 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c @@ -45,7 +45,7 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->is_ois_vsync_irq_supported = false; CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build"); #endif - CAM_INFO(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); + CAM_DBG(CAM_OIS, "is_ois_vsync_irq_supported %d", o_ctrl->is_ois_vsync_irq_supported); rc = cam_soc_util_get_dt_properties(soc_info); if (rc < 0) { @@ -116,7 +116,7 @@ int cam_ois_driver_soc_init(struct cam_ois_ctrl_t *o_ctrl) rc = of_property_read_u32(of_node, "cci-master", &o_ctrl->cci_i2c_master); if (rc < 0) { - CAM_INFO(CAM_OIS, "failed rc %d", rc); + CAM_DBG(CAM_OIS, "failed rc %d", rc); return rc; } @@ -127,13 +127,13 @@ int cam_ois_driver_soc_init(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->cci_num = CCI_DEVICE_0; o_ctrl->io_master_info.cci_client->cci_device = o_ctrl->cci_num; - CAM_INFO(CAM_OIS, "cci-device %d", o_ctrl->cci_num, rc); + CAM_DBG(CAM_OIS, "cci-device %d", o_ctrl->cci_num, rc); } rc = cam_ois_get_dt_data(o_ctrl); if (rc < 0) - CAM_INFO(CAM_OIS, "failed: ois get dt data rc %d", rc); + CAM_DBG(CAM_OIS, "failed: ois get dt data rc %d", rc); return rc; } From a1daf6ff57542b2c50ccaf10578789537671e2de Mon Sep 17 00:00:00 2001 From: chenlj26 Date: Thu, 17 Mar 2022 14:14:50 +0800 Subject: [PATCH 48/86] camera-kernel: miami: support IIC Addr Switch method -For ov32c4c,must write reg 0x1001=0x4 to switch iic addr to 0x20 before any iic operation. -add preInitSetting,it will be wroten into sensor before init. -add IICAddrSwitch,it will be wroten into sensor before probe. Change-Id: I0d0d3959371355843fc4e384042e4ad44a42243d Signed-off-by: chenlj26 Reviewed-on: https://gerrit.mot.com/2218769 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Shuo Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 82 ++++++++++++++++++- .../cam_sensor/cam_sensor_dev.h | 9 ++ include/uapi/camera/media/cam_sensor.h | 7 ++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 867716f505db..2b67e567f362 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -454,16 +454,80 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master; s_ctrl->sub_device_cci_device = probe_info->sub_device_cci_device; s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode; +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH + s_ctrl->i2c_addr_switch = probe_info->i2c_addr_switch; + s_ctrl->second_i2c_address = probe_info->second_i2c_address; + s_ctrl->i2c_switch_reg_addr_Type = probe_info->i2c_switch_reg_addr_Type; + s_ctrl->i2c_switch_reg_data_Type = probe_info->i2c_switch_reg_data_Type; + s_ctrl->i2c_switch_reg_addr = probe_info->i2c_switch_reg_addr; + s_ctrl->i2c_switch_reg_data = probe_info->i2c_switch_reg_data; + s_ctrl->i2c_switch_reg_delayMs = probe_info->i2c_switch_reg_delayMs; CAM_DBG(CAM_SENSOR, - "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x", + "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x i2c_addr_switch: 0x%x second_i2c_address: 0x%x i2c_switch_reg_addr: 0x%x", s_ctrl->sensordata->slave_info.sensor_id_reg_addr, s_ctrl->sensordata->slave_info.sensor_id, s_ctrl->sensordata->slave_info.sensor_id_mask, - s_ctrl->pipeline_delay); + s_ctrl->pipeline_delay, + s_ctrl->i2c_addr_switch , + s_ctrl->second_i2c_address , + s_ctrl->i2c_switch_reg_addr); +#endif return rc; } +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH +int cam_sensor_set_i2c_addr_switch_reg(struct cam_sensor_ctrl_t *s_ctrl) +{ + int rc = 0; + uint16_t sensor_address = 0; + struct cam_sensor_i2c_reg_setting wr_setting; + struct cam_sensor_i2c_reg_array reg_setting; + + /* if hal doesn't config i2c_addr_switch parameter in sensor xml, return success immediately */ + if (!s_ctrl->i2c_addr_switch) { + return 0; + } + + /* save sensor i2c address */ + sensor_address = s_ctrl->io_master_info.cci_client->sid; + + /* set sub-device i2c address */ + if (s_ctrl->second_i2c_address) { + s_ctrl->io_master_info.cci_client->sid = s_ctrl->second_i2c_address >> 1; + } + + reg_setting.reg_addr = s_ctrl->i2c_switch_reg_addr; + reg_setting.reg_data = s_ctrl->i2c_switch_reg_data; + reg_setting.delay = s_ctrl->i2c_switch_reg_delayMs; /* delay after switch iic addr */ + reg_setting.data_mask = 0; + wr_setting.addr_type = s_ctrl->i2c_switch_reg_addr_Type; + wr_setting.data_type = s_ctrl->i2c_switch_reg_data_Type; + wr_setting.reg_setting = ®_setting; + wr_setting.size = 1; + wr_setting.delay = 0; + rc = camera_io_dev_write(&s_ctrl->io_master_info, &wr_setting); +CAM_ERR(CAM_SENSOR, + "cam_sensor_set_i2c_addr_switch_reg slot:%d, slave_addr:0x%x, sensor_id:0x%x, sensor_address:0x%x", + s_ctrl->soc_info.index, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensordata->slave_info.sensor_id, + sensor_address); + /* restore sensor i2c address */ + s_ctrl->io_master_info.cci_client->sid = sensor_address; + + if (rc == 0) { + CAM_ERR(CAM_SENSOR, "write i2c addr switch reg success"); + } + else { + CAM_ERR(CAM_SENSOR, "write i2c addr switch reg fail"); + rc = -EINVAL; + } + + return rc; +} +#endif + int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, struct cam_sensor_ctrl_t *s_ctrl, int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len) @@ -895,6 +959,20 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto free_power_settings; } +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH + /* load probe setting before read sensorID */ + rc = cam_sensor_set_i2c_addr_switch_reg(s_ctrl); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "set i2c addr switch reg failed ! slot:%d, slave_addr:0x%x, sensor_id:0x%x", + s_ctrl->soc_info.index, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensordata->slave_info.sensor_id); + cam_sensor_power_down(s_ctrl); + msleep(20); + goto free_power_settings; + } +#endif /* Match sensor ID */ rc = cam_sensor_match_id(s_ctrl); if (rc < 0) { diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index faf8fc8c8eab..23b68b7038bd 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -121,6 +121,15 @@ struct cam_sensor_ctrl_t { uint8_t sub_device_cci_device; uint8_t sub_device_i2c_freq_mode; bool need_change_cci_master; +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH + uint8_t i2c_addr_switch; + uint16_t second_i2c_address; + uint8_t i2c_switch_reg_addr_Type; + uint8_t i2c_switch_reg_data_Type; + uint16_t i2c_switch_reg_addr; + uint16_t i2c_switch_reg_data; + uint16_t i2c_switch_reg_delayMs; +#endif }; /** diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 3df242f29044..7f52004c4f85 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -181,6 +181,13 @@ struct cam_cmd_probe { __u8 sub_device_cci_master; __u8 sub_device_cci_device; __u8 sub_device_i2c_freq_mode; + __u8 i2c_addr_switch; + __u32 second_i2c_address; + __u8 i2c_switch_reg_addr_Type; + __u8 i2c_switch_reg_data_Type; + __u32 i2c_switch_reg_addr; + __u32 i2c_switch_reg_data; + __u32 i2c_switch_reg_delayMs; } __attribute__((packed)); /** From b26a4c2545b58aeca23627a6443781501e579b8f Mon Sep 17 00:00:00 2001 From: huqian4 Date: Wed, 30 Mar 2022 09:45:43 +0800 Subject: [PATCH 49/86] Dubai: Add retries for sensor id matching details: Add retries in the sensor id matching during kernel camera probe to handle any transient failures Change-Id: I71e43566e4d9f8f27cac1f2a96470bfb76fc9663 Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2228991 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 2b67e567f362..28891aa3d2cf 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -749,6 +749,10 @@ void cam_sensor_shutdown(struct cam_sensor_ctrl_t *s_ctrl) int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) { int rc = 0; +#ifdef CONFIG_CAM_SENSOR_PROBE_RETRY + int retries = 5; + bool matched = false; +#endif uint32_t chipid = 0; struct cam_camera_slave_info *slave_info; @@ -760,6 +764,28 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) return -EINVAL; } +#ifdef CONFIG_CAM_SENSOR_PROBE_RETRY + while (retries-- && !matched) { + rc = camera_io_dev_read( + &(s_ctrl->io_master_info), + slave_info->sensor_id_reg_addr, + &chipid, + s_ctrl->sensor_probe_addr_type, + s_ctrl->sensor_probe_data_type); + + CAM_INFO(CAM_SENSOR, "read id: 0x%x expected id 0x%x:", + chipid, slave_info->sensor_id); + + if (cam_sensor_id_by_mask(s_ctrl, chipid) == slave_info->sensor_id) + matched = true; + + if (!matched && !retries) { + CAM_ERR(CAM_SENSOR, "Failed read id: 0x%x expected id 0x%x:", + chipid, slave_info->sensor_id); + + } + } +#else rc = camera_io_dev_read( &(s_ctrl->io_master_info), slave_info->sensor_id_reg_addr, @@ -775,6 +801,7 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) chipid, slave_info->sensor_id); return -ENODEV; } +#endif return rc; } From 82fb44bef63bdeefdec2e527a803122d373ce623 Mon Sep 17 00:00:00 2001 From: chenlj26 Date: Wed, 30 Mar 2022 07:17:28 -0500 Subject: [PATCH 50/86] Revert "(CR): camera-kernel: miami: support IIC Addr Switch method" This reverts commit a25467f6bef17606af91ec342708c37d5ceff460. Change-Id: I57a1300a03bdfd240ce76dc17076156c550b3591 Reviewed-on: https://gerrit.mot.com/2229671 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 82 +------------------ .../cam_sensor/cam_sensor_dev.h | 9 -- include/uapi/camera/media/cam_sensor.h | 7 -- 3 files changed, 2 insertions(+), 96 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 28891aa3d2cf..5bcd6bb6f1ad 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -454,80 +454,16 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master; s_ctrl->sub_device_cci_device = probe_info->sub_device_cci_device; s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode; -#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH - s_ctrl->i2c_addr_switch = probe_info->i2c_addr_switch; - s_ctrl->second_i2c_address = probe_info->second_i2c_address; - s_ctrl->i2c_switch_reg_addr_Type = probe_info->i2c_switch_reg_addr_Type; - s_ctrl->i2c_switch_reg_data_Type = probe_info->i2c_switch_reg_data_Type; - s_ctrl->i2c_switch_reg_addr = probe_info->i2c_switch_reg_addr; - s_ctrl->i2c_switch_reg_data = probe_info->i2c_switch_reg_data; - s_ctrl->i2c_switch_reg_delayMs = probe_info->i2c_switch_reg_delayMs; CAM_DBG(CAM_SENSOR, - "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x i2c_addr_switch: 0x%x second_i2c_address: 0x%x i2c_switch_reg_addr: 0x%x", + "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x", s_ctrl->sensordata->slave_info.sensor_id_reg_addr, s_ctrl->sensordata->slave_info.sensor_id, s_ctrl->sensordata->slave_info.sensor_id_mask, - s_ctrl->pipeline_delay, - s_ctrl->i2c_addr_switch , - s_ctrl->second_i2c_address , - s_ctrl->i2c_switch_reg_addr); -#endif + s_ctrl->pipeline_delay); return rc; } -#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH -int cam_sensor_set_i2c_addr_switch_reg(struct cam_sensor_ctrl_t *s_ctrl) -{ - int rc = 0; - uint16_t sensor_address = 0; - struct cam_sensor_i2c_reg_setting wr_setting; - struct cam_sensor_i2c_reg_array reg_setting; - - /* if hal doesn't config i2c_addr_switch parameter in sensor xml, return success immediately */ - if (!s_ctrl->i2c_addr_switch) { - return 0; - } - - /* save sensor i2c address */ - sensor_address = s_ctrl->io_master_info.cci_client->sid; - - /* set sub-device i2c address */ - if (s_ctrl->second_i2c_address) { - s_ctrl->io_master_info.cci_client->sid = s_ctrl->second_i2c_address >> 1; - } - - reg_setting.reg_addr = s_ctrl->i2c_switch_reg_addr; - reg_setting.reg_data = s_ctrl->i2c_switch_reg_data; - reg_setting.delay = s_ctrl->i2c_switch_reg_delayMs; /* delay after switch iic addr */ - reg_setting.data_mask = 0; - wr_setting.addr_type = s_ctrl->i2c_switch_reg_addr_Type; - wr_setting.data_type = s_ctrl->i2c_switch_reg_data_Type; - wr_setting.reg_setting = ®_setting; - wr_setting.size = 1; - wr_setting.delay = 0; - rc = camera_io_dev_write(&s_ctrl->io_master_info, &wr_setting); -CAM_ERR(CAM_SENSOR, - "cam_sensor_set_i2c_addr_switch_reg slot:%d, slave_addr:0x%x, sensor_id:0x%x, sensor_address:0x%x", - s_ctrl->soc_info.index, - s_ctrl->sensordata->slave_info.sensor_slave_addr, - s_ctrl->sensordata->slave_info.sensor_id, - sensor_address); - /* restore sensor i2c address */ - s_ctrl->io_master_info.cci_client->sid = sensor_address; - - if (rc == 0) { - CAM_ERR(CAM_SENSOR, "write i2c addr switch reg success"); - } - else { - CAM_ERR(CAM_SENSOR, "write i2c addr switch reg fail"); - rc = -EINVAL; - } - - return rc; -} -#endif - int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, struct cam_sensor_ctrl_t *s_ctrl, int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len) @@ -986,20 +922,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto free_power_settings; } -#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH - /* load probe setting before read sensorID */ - rc = cam_sensor_set_i2c_addr_switch_reg(s_ctrl); - if (rc < 0) { - CAM_ERR(CAM_SENSOR, - "set i2c addr switch reg failed ! slot:%d, slave_addr:0x%x, sensor_id:0x%x", - s_ctrl->soc_info.index, - s_ctrl->sensordata->slave_info.sensor_slave_addr, - s_ctrl->sensordata->slave_info.sensor_id); - cam_sensor_power_down(s_ctrl); - msleep(20); - goto free_power_settings; - } -#endif /* Match sensor ID */ rc = cam_sensor_match_id(s_ctrl); if (rc < 0) { diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index 23b68b7038bd..faf8fc8c8eab 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -121,15 +121,6 @@ struct cam_sensor_ctrl_t { uint8_t sub_device_cci_device; uint8_t sub_device_i2c_freq_mode; bool need_change_cci_master; -#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH - uint8_t i2c_addr_switch; - uint16_t second_i2c_address; - uint8_t i2c_switch_reg_addr_Type; - uint8_t i2c_switch_reg_data_Type; - uint16_t i2c_switch_reg_addr; - uint16_t i2c_switch_reg_data; - uint16_t i2c_switch_reg_delayMs; -#endif }; /** diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 7f52004c4f85..3df242f29044 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -181,13 +181,6 @@ struct cam_cmd_probe { __u8 sub_device_cci_master; __u8 sub_device_cci_device; __u8 sub_device_i2c_freq_mode; - __u8 i2c_addr_switch; - __u32 second_i2c_address; - __u8 i2c_switch_reg_addr_Type; - __u8 i2c_switch_reg_data_Type; - __u32 i2c_switch_reg_addr; - __u32 i2c_switch_reg_data; - __u32 i2c_switch_reg_delayMs; } __attribute__((packed)); /** From 543572a53a443c1fa97ceff4e78b45b5084d1dc9 Mon Sep 17 00:00:00 2001 From: hansx3 Date: Mon, 28 Mar 2022 15:08:42 +0800 Subject: [PATCH 51/86] rhodei: Actuator noise reduction detalis: add MOT_DEVICE_RHODEI for workaround Change-Id: I158117f91479a3e6c63cbc070de2f9dad5f337e9 Signed-off-by: hansx3 Reviewed-on: https://gerrit.mot.com/2227387 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Zhichao Chen Tested-by: Jira Key Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index fe036ce1bbf6..72f9f4a4909f 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -64,6 +64,7 @@ typedef enum { MOT_DEVICE_CORFUQ, MOT_DEVICE_CORFUR, MOT_DEVICE_RHODEC, + MOT_DEVICE_RHODEI, MOT_DEVICE_NUM, } mot_dev_type; @@ -471,6 +472,33 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, }, + + { + .dev_type = MOT_DEVICE_RHODEI, + .actuator_num = 1, + .dev_name = "rhodei", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"pm6125_l9", "cam_rear_af"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + }; static uint32_t mot_device_index = MOT_DEVICE_NUM; From acc791f60f63f225317d26cb159ad17f35556177 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 23 Mar 2022 17:41:35 +0800 Subject: [PATCH 52/86] camera: ois: add aw86006 driver [detail] add aw86006 driver Change-Id: I62ae76380aea2d239453d6abfc2c8a774293139b Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2224040 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/Makefile | 1 + .../cam_ois/cam_ois_aw86006.c | 2017 +++++++++++++++++ .../cam_ois/cam_ois_aw86006.h | 193 ++ .../cam_sensor_module/cam_ois/cam_ois_core.c | 11 +- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 9 + .../cam_sensor_module/cam_ois/cam_ois_dev.h | 7 + .../cam_sensor_module/cam_ois/cam_ois_soc.c | 6 + 7 files changed, 2242 insertions(+), 2 deletions(-) create mode 100644 drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c create mode 100644 drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h diff --git a/drivers/Makefile b/drivers/Makefile index ffcafe6fcbe6..10d91f552fac 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -163,6 +163,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \ cam_sensor_module/cam_ois/cam_ois_core.o \ cam_sensor_module/cam_ois/cam_ois_soc.o \ cam_sensor_module/cam_ois/cam_ois_dw9781.o \ + cam_sensor_module/cam_ois/cam_ois_aw86006.o \ cam_sensor_module/cam_sensor/cam_sensor_dev.o \ cam_sensor_module/cam_sensor/cam_sensor_core.o \ cam_sensor_module/cam_sensor/cam_sensor_soc.o \ diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c new file mode 100644 index 000000000000..c1acd5227d70 --- /dev/null +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -0,0 +1,2017 @@ +/* + * File: cam_ois_aw86006.c + * + * Author: hushanping + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cam_ois_core.h" +#include "cam_ois_soc.h" +#include "cam_ois_dev.h" +#include "cam_cci_dev.h" +#include "cam_sensor_util.h" +#include "cam_debug_util.h" +#include "cam_res_mgr_api.h" +#include "cam_common_util.h" +#include "cam_packet_util.h" +#include "cam_ois_aw86006.h" + +#define AW86006_DRIVER_VERSION "v0.4.7" +#define AW86006_FW_NAME "mot_aw86006.prog" + +const char fw_check_str[] = { 'A', 'W', 'I', 'N', 'I', 'C', 0, 0 }; +uint8_t g_cci_freq = I2C_FAST_PLUS_MODE; +struct cam_ois_ctrl_t *o_ctrl_g; +static struct class *ois_debug_class; +struct aw86006_info g_aw86006_info = { + .checkinfo_fw = { 0 }, + .checkinfo_rd = { 0 }, + .fw = { 0 }, +}; + +static int ois_block_read_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint32_t addr_type, uint8_t *data, uint32_t num_byte) +{ + enum i2c_freq_mode temp_freq; + int ret = -1; + + + if (o_ctrl == NULL || data == NULL) { + CAM_ERR(CAM_OIS, "Invalid Args o_ctrl: %pK, data: %pK", + o_ctrl, data); + return -EINVAL; + } + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + CAM_ERR(CAM_OIS, "Not in right state to start soc reads: %d", + o_ctrl->cam_ois_state); + return -EINVAL; + } + temp_freq = o_ctrl->io_master_info.cci_client->i2c_freq_mode; + /* Modify i2c freq to 100K */ + o_ctrl->io_master_info.cci_client->i2c_freq_mode = I2C_STANDARD_MODE; + ret = camera_io_dev_read_seq(&(o_ctrl->io_master_info), addr, data, + addr_type, CAMERA_SENSOR_I2C_TYPE_BYTE, num_byte); + if (ret < 0) + CAM_ERR(CAM_OIS, "err! ret:%d", ret); + o_ctrl->io_master_info.cci_client->i2c_freq_mode = temp_freq; + + return ret; +} + +static int ois_block_write_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint32_t addr_type, uint8_t *data, uint32_t num_byte) +{ + int ret = -1; + int cnt; + enum i2c_freq_mode temp_freq; + struct cam_sensor_i2c_reg_setting i2c_reg_setting; + + + if (o_ctrl == NULL || data == NULL) { + CAM_ERR(CAM_OIS, "Invalid Args o_ctrl: %pK, data: %pK", + o_ctrl, data); + return -EINVAL; + } + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + CAM_ERR(CAM_OIS, "Not in right state to start soc writes: %d", + o_ctrl->cam_ois_state); + return -EINVAL; + } + temp_freq = o_ctrl->io_master_info.cci_client->i2c_freq_mode; + o_ctrl->io_master_info.cci_client->i2c_freq_mode = g_cci_freq; + i2c_reg_setting.addr_type = addr_type; + i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + i2c_reg_setting.size = num_byte; + i2c_reg_setting.delay = 0; + i2c_reg_setting.reg_setting = + (struct cam_sensor_i2c_reg_array *) + kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * num_byte, + GFP_KERNEL); + if (i2c_reg_setting.reg_setting == NULL) { + CAM_ERR(CAM_OIS, "kzalloc failed"); + return OIS_ERROR; + } + i2c_reg_setting.reg_setting[0].reg_addr = addr; + i2c_reg_setting.reg_setting[0].reg_data = data[0]; + i2c_reg_setting.reg_setting[0].delay = 0; + i2c_reg_setting.reg_setting[0].data_mask = 0; + for (cnt = 1; cnt < num_byte; cnt++) { + i2c_reg_setting.reg_setting[cnt].reg_addr = 0; + i2c_reg_setting.reg_setting[cnt].reg_data = data[cnt]; + i2c_reg_setting.reg_setting[cnt].delay = 0; + i2c_reg_setting.reg_setting[cnt].data_mask = 0; + } + ret = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), + &i2c_reg_setting, 0); + if (ret < 0) + CAM_ERR(CAM_OIS, "err! ret:%d", ret); + o_ctrl->io_master_info.cci_client->i2c_freq_mode = temp_freq; + kfree(i2c_reg_setting.reg_setting); + + + return ret; +} + +static int aw_reset(struct cam_ois_ctrl_t *o_ctrl) +{ + int ret = OIS_ERROR; + uint16_t temp_addr = 0; + uint8_t boot_cmd_1[] = { 0xFF, 0xF0, 0x20, 0x20, 0x02, 0x02, 0x19, 0x29, + 0x19, 0x29 }; + uint8_t boot_cmd_2[] = { 0xFF, 0xC4, 0xC4 }; + uint8_t boot_cmd_3[] = { 0xFF, 0xC4, 0x00 }; + uint8_t boot_cmd_4[] = { 0xFF, 0x10, 0xC3 }; + + CAM_INFO(CAM_OIS, "enter"); + /* first: shutdown */ + temp_addr = o_ctrl->io_master_info.cci_client->sid; + o_ctrl->io_master_info.cci_client->sid = AW_SHUTDOWN_I2C_ADDR; + ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_1[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, + &boot_cmd_1[1], sizeof(boot_cmd_1) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "boot_cmd_1 write error!"); + goto err_exit; + } + ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_2[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, + &boot_cmd_2[1], sizeof(boot_cmd_2) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "boot_cmd_2 write error!"); + goto err_exit; + } + usleep_range(AW_SHUTDOWN_DELAY, AW_SHUTDOWN_DELAY + 50); /* 2 ms */ + /* second: wake up */ + o_ctrl->io_master_info.cci_client->sid = AW_WAKEUP_I2C_ADDR; + ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_3[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, + &boot_cmd_3[1], sizeof(boot_cmd_3) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "boot_cmd_3 write error!"); + goto err_exit; + } + ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_4[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, + &boot_cmd_4[1], sizeof(boot_cmd_4) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "boot_cmd_4 write error!"); + goto err_exit; + } + + o_ctrl->io_master_info.cci_client->sid = temp_addr; + return OIS_SUCCESS; + err_exit: + o_ctrl->io_master_info.cci_client->sid = temp_addr; + return OIS_ERROR; +} + +static int aw_runtime_check(struct cam_ois_ctrl_t *o_ctrl) +{ + int ret = OIS_ERROR; + uint32_t version = 0; + uint8_t reg_val[4] = { 0 }; + uint8_t chip_id = 0; + + ret = ois_block_read_addr8_data8(o_ctrl, REG_CHIPID, + CAMERA_SENSOR_I2C_TYPE_WORD, &chip_id, 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read chipid error!"); + return ret; + } + + ret = ois_block_read_addr8_data8(o_ctrl, REG_VERSION, + CAMERA_SENSOR_I2C_TYPE_WORD, ®_val[0], 4); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read version error!"); + return ret; + } + version = (reg_val[3] << AW_DATA_SHIFT_24_BIT) | + (reg_val[2] << AW_DATA_SHIFT_16_BIT) | + (reg_val[1] << AW_DATA_SHIFT_8_BIT) | + (reg_val[0] << AW_DATA_SHIFT_0_BIT); + CAM_INFO(CAM_OIS, "Chip_ID: 0x%02X, Version: v%d.%d.%d.%d", chip_id, + reg_val[3], reg_val[2], reg_val[1], reg_val[0]); + + if ((chip_id != g_aw86006_info.fw.app_id) + || (version != g_aw86006_info.fw.app_version)) { + CAM_ERR(CAM_OIS, "Chip_ID or Version not match!"); + return OIS_ERROR; + } + CAM_INFO(CAM_OIS, "pass!"); + + return OIS_SUCCESS; +} + +static int aw_soc_buf_build(struct cam_ois_ctrl_t *o_ctrl, uint8_t *buf, + struct soc_protocol *soc_struct) +{ + int i = 0; + uint8_t *p_head = (uint8_t *)soc_struct; + uint8_t checksum = 0; + uint8_t data_sum = 0; + + if ((buf == NULL) || ((soc_struct == NULL))) + return OIS_ERROR; + if (soc_struct->p_data == NULL) + soc_struct->len[0] = 0; + soc_struct->protocol_ver = SOC_VERSION; + soc_struct->ack = SOC_ACK; + soc_struct->addr = + ((soc_struct->ack_juge == SOC_CTL) ? SOC_ADDR : SOC_READ_ADDR); + for (i = 0; i < soc_struct->len[0]; i++) { + data_sum += soc_struct->p_data[i]; + buf[i + SOC_PROTOCAL_HEAD] = soc_struct->p_data[i]; + } + soc_struct->sum = data_sum; + for (i = 1; i < SOC_PROTOCAL_HEAD; i++) { + checksum += p_head[i]; + buf[i] = p_head[i]; + } + soc_struct->checksum = checksum; + buf[0] = p_head[0]; + + return OIS_SUCCESS; +} + +static int aw_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) +{ + struct soc_protocol soc_struct = { 0 }; + int ret = OIS_ERROR; + uint8_t w_buf[14] = { 0 }; + uint8_t r_buf[14] = { 0 }; + uint8_t cmp_buf[5] = {0x00, 0x01, 0x00, 0x00, 0x00}; + + soc_struct.module = SOC_HANK; + + soc_struct.event = SOC_HANK_CONNECT; + soc_struct.len[0] = 0; + soc_struct.p_data = NULL; + soc_struct.ack_juge = SOC_CTL; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], + SOC_CONNECT_WRITE_LEN - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "write connect w_buf error!"); + return ret; + } + + usleep_range(SOC_CONNECT_DELAY, SOC_CONNECT_DELAY + 50); + + memset(r_buf, 0, sizeof(r_buf)); + ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, + CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 14); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read connect r_buf error!"); + return ret; + } + /* regroup w_buf */ + soc_struct.event = SOC_HANK_CONNECT_ACK; + soc_struct.ack_juge = SOC_ACK; + soc_struct.len[0] = 5; + soc_struct.p_data = cmp_buf; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = memcmp(w_buf, r_buf, sizeof(r_buf)); + if (ret != 0) { + CAM_ERR(CAM_OIS, "connect memcmp error!"); + return OIS_ERROR; + } + + return OIS_SUCCESS; +} + +static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint8_t *bin_buf, uint32_t len) +{ + struct soc_protocol soc_struct = { 0 }; + int i = 0; + int ret = OIS_ERROR; + int loop = 0; + uint8_t temp_buf[SOC_READ_STRUCT_LEN] = { 0 }; + uint8_t w_buf[SOC_READ_WRITE_LEN] = { 0 }; + uint8_t r_buf[80] = { 0 }; + uint8_t checksum = 0; + + temp_buf[0] = len; + temp_buf[1] = 0; + for (i = 0; i < 4; i++) + temp_buf[i + 2] = (uint8_t) (addr >> (i * 8)); + soc_struct.module = SOC_FLASH; + + do { + soc_struct.event = SOC_FLASH_READ; + soc_struct.len[0] = SOC_READ_STRUCT_LEN; + soc_struct.p_data = temp_buf; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], sizeof(w_buf) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + continue; + } + usleep_range(SOC_READ_BLOCK_DELAY, SOC_READ_BLOCK_DELAY + 50); + + memset(r_buf, 0, sizeof(r_buf)); + ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, + CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 14 + len); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + continue; + } + /* check error flag */ + if (r_buf[9] != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "error flag wrong: %d, loop: %d", + r_buf[10], loop); + continue; + } + checksum = 0; + /* compute data checksum */ + for (i = 0; i < len + 5; i++) + checksum += r_buf[9 + i]; + if (checksum != r_buf[8]) { + CAM_ERR(CAM_OIS, "data checksum error:0x%02x != 0x%02x, loop:%d", + checksum, r_buf[8], loop); + continue; + } + checksum = 0; + /* compute head checksum */ + for (i = 1; i < 9; i++) + checksum += r_buf[i]; + if (checksum != r_buf[0]) { + CAM_ERR(CAM_OIS, "head checksum error:0x%02x != 0x%02x, loop:%d", + checksum, r_buf[0], loop); + continue; + } + memcpy(bin_buf, (uint8_t *)&r_buf[14], len); + break; /* Check pass */ + } while ((++loop) < AW_FLASH_READ_ERROR_LOOP); + if (loop >= AW_FLASH_READ_ERROR_LOOP) + return OIS_ERROR; + + return OIS_SUCCESS; +} + +static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint32_t block_num, uint8_t *bin_buf, uint32_t len) +{ + struct soc_protocol soc_struct = { 0 }; + int i = 0; + int ret = OIS_ERROR; + int loop = 0; + +#ifdef AW_FLASH_WRITE_CONNECT + int connect_loop = 0; +#endif + + uint8_t temp_buf[68] = { 0 }; + uint8_t w_buf[77] = { 0 }; + uint8_t r_buf[10] = { 0 }; + uint8_t cmp_buf[1] = { 0 }; + + for (i = 0; i < 4; i++) + temp_buf[i] = (uint8_t) ((addr + + block_num * AW_FLASH_WRITE_LEN) >> (i * 8)); + for (i = 0; i < len; i++) + temp_buf[i + 4] = (bin_buf + block_num * AW_FLASH_WRITE_LEN)[i]; + + soc_struct.module = SOC_FLASH; + +#ifdef AW_FLASH_WRITE_CONNECT + do { + ret = aw_soc_connect_check(o_ctrl); + if (ret == OIS_SUCCESS) + break; + CAM_ERR(CAM_OIS, "connect_loop error ret: %d, connect_loop: %d", + ret, connect_loop); + } while ((++connect_loop) < AW_ERROR_LOOP); + if (connect_loop >= AW_ERROR_LOOP) + return OIS_ERROR; +#endif + + do { + soc_struct.event = SOC_FLASH_WRITE; + soc_struct.len[0] = (uint8_t) (4 + len); + soc_struct.p_data = temp_buf; + soc_struct.ack_juge = SOC_CTL; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], + SOC_WRITE_BLOCK_HEAD - 1 + len); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + continue; + } + usleep_range(SOC_WRITE_BLOCK_DELAY, SOC_WRITE_BLOCK_DELAY + 50); + + memset(r_buf, 0, sizeof(r_buf)); + ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, + CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 10); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + continue; + } + /* regroup w_buf */ + soc_struct.event = SOC_FLASH_WRITE_ACK; + soc_struct.len[0] = 1; + soc_struct.p_data = cmp_buf; + soc_struct.ack_juge = SOC_ACK; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = memcmp(w_buf, r_buf, sizeof(r_buf)); + if (ret == 0) + break; + CAM_ERR(CAM_OIS, "memcmp error! ret=%d, loop: %d",ret , loop); + } while ((++loop) < AW_FLASH_WRITE_ERROR_LOOP); + if (loop >= AW_FLASH_WRITE_ERROR_LOOP) + return OIS_ERROR; + + return OIS_SUCCESS; +} + +static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint32_t len) +{ + struct soc_protocol soc_struct = { 0 }; + uint32_t erase_block = 0; + int i = 0; + int ret = OIS_ERROR; + int loop = 0; + uint8_t temp_buf[6] = { 0 }; + uint8_t cmp_buf[1] = { 0 }; + uint8_t w_buf[15] = { 0 }; + uint8_t r_buf[10] = { 0 }; + + erase_block = len / AW_FLASH_ERASE_LEN + + ((len % AW_FLASH_ERASE_LEN) ? 1 : 0); + temp_buf[0] = (uint8_t) erase_block; + temp_buf[1] = 0x00; + for (i = 0; i < 4; i++) + temp_buf[i + 2] = (uint8_t) (addr >> (i * 8)); + + soc_struct.module = SOC_FLASH; + + do { + soc_struct.event = SOC_FLASH_ERASE_BLOCK; + soc_struct.len[0] = SOC_ERASE_STRUCT_LEN; + soc_struct.p_data = temp_buf; + soc_struct.ack_juge = SOC_CTL; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], + SOC_ERASE_WRITE_LEN - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + continue; + } + msleep(erase_block * SOC_ERASE_BLOCK_DELAY); + + memset(r_buf, 0, sizeof(r_buf)); + ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, + CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 10); + if (ret < 0) { + CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + continue; + } + soc_struct.event = SOC_FLASH_ERASE_BLOCK_ACK; + soc_struct.len[0] = 1; + soc_struct.ack_juge = SOC_ACK; + soc_struct.p_data = cmp_buf; + + memset(w_buf, 0, sizeof(w_buf)); + aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = memcmp(w_buf, r_buf, sizeof(r_buf)); + if (ret == 0) + break; + CAM_ERR(CAM_OIS, "memcmp error!, loop: %d", loop); + } while ((++loop) < AW_FLASH_ERASE_ERROR_LOOP); + if (loop >= AW_FLASH_ERASE_ERROR_LOOP) + return OIS_ERROR; + + CAM_INFO(CAM_OIS, "flash erase success!, addr: 0x%08x, len: 0x%08x", + addr, len); + return OIS_SUCCESS; +} + +static int aw_soc_flash_download_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint8_t *bin_buf, size_t len) +{ + uint32_t flash_block = 0; + uint32_t flash_tail = 0; + uint32_t flash_checkinfo = 0; + int i = 0; + int ret = OIS_ERROR; + + flash_block = len / AW_FLASH_WRITE_LEN; + flash_tail = len % AW_FLASH_WRITE_LEN; + + if (addr == AW_FLASH_BASE_ADDR) { + flash_checkinfo = AW_FLASH_MOVE_LENGTH / AW_FLASH_WRITE_LEN; + /* first erase app+info data */ + ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, + len - AW_FLASH_MOVE_LENGTH); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to erase app+checkinfo!"); + return ret; + } + /* then erase move data */ + ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_BASE_ADDR, + AW_FLASH_MOVE_LENGTH); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to erase move!"); + return ret; + } + /* write move data */ + for (i = 0; i < flash_checkinfo; i++) { + ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, + AW_FLASH_WRITE_LEN); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); + return ret; + } + } + /* write app block data */ + for (i = flash_checkinfo + 1; i < flash_block; i++) { + ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, + AW_FLASH_WRITE_LEN); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); + return ret; + } + } + /* write app tail data */ + if ((flash_tail != 0) && (len > AW_FLASH_MOVE_LENGTH)) { + ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, + flash_tail); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write flash app tail"); + return ret; + } + } + } else if (addr == AW_FLASH_APP_ADDR) { + flash_checkinfo = 0; + /* erase app+info data */ + ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, len); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to erase app+checkinfo!"); + return ret; + } + /* write app block data */ + for (i = 1; i < flash_block; i++) { + ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, + AW_FLASH_WRITE_LEN); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); + return ret; + } + } + /* write app tail data */ + if (flash_tail != 0) { + ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, + flash_tail); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write flash tail"); + return ret; + } + } + } else { + CAM_ERR(CAM_OIS, "wrong addr!"); + return OIS_ERROR; + } + + /* Write checkinfo data */ + ret = aw_soc_flash_write_check(o_ctrl, AW_FLASH_APP_ADDR, 0, + g_aw86006_info.checkinfo_fw, + AW_FLASH_WRITE_LEN); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "Failed to write checkinfo!"); + return ret; + } + + return OIS_SUCCESS; +} + +static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) +{ + ktime_t kstart; + ktime_t kend; + uint32_t move_version = 0; + uint32_t ms_count_reset = 0; + uint32_t ms_count_stop = 0; + uint32_t ms_first_f0 = 0; + int ret = OIS_ERROR; + int i = 0; + int jump_loop = 0; + uint8_t move_cmd[] = {0xF0, 0xF0, 0xF0}; + uint8_t version_cmd[] = {0x00, 0x55}; + uint8_t version_ack[5] = {0x00}; + + do { + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_reset error, ret: %d, loop: %d", + ret, jump_loop); + continue; + } + /* delay: 9ms */ + kstart = ktime_get(); + for (i = 0; i < AW_JUMP_MOVE_DELAY_MAX; i++) { + mdelay(1); + kend = ktime_get(); + ms_count_reset = ktime_to_ms(ktime_sub(kend, kstart)); + if (ms_count_reset >= AW_JUMP_MOVE_DELAY) + break; + } + if (ms_count_reset >= AW_JUMP_MOVE_DELAY_MAX) { + CAM_ERR(CAM_OIS, "ms_count_reset timeout: %d, loop: %d", + ms_count_reset, jump_loop); + continue; + } + /* send jump cmd */ + for (i = 0; i < AW_STAY_ON_MOVE_LOOP; i++) { /* loop 20 */ + ois_block_write_addr8_data8(o_ctrl, move_cmd[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &move_cmd[1], + sizeof(move_cmd) - 1); + if (i == 0) { + kend = ktime_get(); + ms_first_f0 = + ktime_to_ms(ktime_sub(kend, kstart)); + } + } + + kend = ktime_get(); + ms_count_stop = ktime_to_ms(ktime_sub(kend, kstart)); + CAM_INFO(CAM_OIS, "ms_count_reset: %u, ms_count_stop: %u", + ms_count_reset, ms_count_stop); + + if (ms_first_f0 > AW_JUMP_MOVE_DELAY_MAX) { + CAM_INFO(CAM_OIS, "first 0xF0: %d ms", ms_first_f0); + continue; + } + + /* send read move version cmd */ + ret = ois_block_write_addr8_data8(o_ctrl, version_cmd[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, &version_cmd[1], + sizeof(version_cmd) - 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "write version_cmd, loop: %d", jump_loop); + continue; + } + usleep_range(ISP_READ_VERSION_DELAY, + ISP_READ_VERSION_DELAY + 50); + ret = ois_block_read_addr8_data8(o_ctrl, ISP_VERS_CONNECT_ACK, + CAMERA_SENSOR_I2C_TYPE_BYTE, + &version_ack[0], ISP_VERSION_ACK_LEN); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read version error, loop:%d", jump_loop); + continue; + } + + if (version_ack[0] != ISP_EVENT_OK) { + CAM_ERR(CAM_OIS, "wrong version_ack: %d, loop: %d", + version_ack[0], jump_loop); + continue; + } + move_version = (version_ack[4] << AW_DATA_SHIFT_24_BIT) | + (version_ack[3] << AW_DATA_SHIFT_16_BIT) | + (version_ack[2] << AW_DATA_SHIFT_8_BIT) | + (version_ack[1] << AW_DATA_SHIFT_0_BIT); + + if (move_version == g_aw86006_info.fw.move_version) + break; + + CAM_ERR(CAM_OIS, "move_version not match: 0x%08X != 0x%08X, loop:%d", + move_version, g_aw86006_info.fw.move_version, + jump_loop); + } while ((++jump_loop) < AW_JUMP_MOVE_LOOP); + if (jump_loop >= AW_JUMP_MOVE_LOOP) + return OIS_ERROR; + + CAM_INFO(CAM_OIS, "Success! move_version: 0x%08X", move_version); + + return OIS_SUCCESS; +} + +static int aw_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) +{ + ktime_t kend; + ktime_t kstart; + uint32_t ms_count_reset = 0; + uint32_t ms_count_stop = 0; + uint32_t ms_first_ac = 0; + int ret = OIS_ERROR; + int i = 0; + int jump_loop = 0; + uint8_t boot_cmd[] = {0xAC, 0xAC, 0xAC}; + + do { + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_reset error, ret: %d, loop: %d", + ret, jump_loop); + continue; + } + /* delay: 2ms */ + kstart = ktime_get(); + for (i = 0; i < AW_JUMP_BOOT_DELAY_MAX; i++) { + mdelay(1); + kend = ktime_get(); + ms_count_reset = ktime_to_ms(ktime_sub(kend, kstart)); + if (ms_count_reset >= AW_JUMP_BOOT_DELAY) + break; + } + if (ms_count_reset >= AW_JUMP_BOOT_DELAY_MAX) { + CAM_ERR(CAM_OIS, "ms_count_reset timeout: %d, loop: %d", + ms_count_reset, jump_loop); + continue; + } + /* send jump boot cmd */ + for (i = 0; i < AW_STAY_ON_BOOT_LOOP; i++) { + ois_block_write_addr8_data8(o_ctrl, boot_cmd[0], + CAMERA_SENSOR_I2C_TYPE_BYTE, + &boot_cmd[1], sizeof(boot_cmd) - 1); + if (i == 0) { + kend = ktime_get(); + ms_first_ac = + ktime_to_ms(ktime_sub(kend, kstart)); + } + } + /* get the end time of send boot cmd */ + kend = ktime_get(); + ms_count_stop = ktime_to_ms(ktime_sub(kend, kstart)); + CAM_INFO(CAM_OIS, "ms_count_reset: %u, ms_count_stop: %u", + ms_count_reset, ms_count_stop); + if (ms_first_ac > AW_JUMP_BOOT_DELAY_MAX) { + CAM_INFO(CAM_OIS, "first 0xAC: %d ms", ms_first_ac); + continue; + } + + ret = aw_soc_connect_check(o_ctrl); + if (ret == OIS_SUCCESS) + break; + + CAM_ERR(CAM_OIS, "soc connect failed! loop:%d", jump_loop); + } while ((++jump_loop) < AW_JUMP_BOOT_LOOP); + if (jump_loop >= AW_JUMP_BOOT_LOOP) + return OIS_ERROR; + + CAM_INFO(CAM_OIS, "success"); + + return OIS_SUCCESS; +} + +static int aw_soc_flash_update(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, + uint8_t *data_p, size_t fw_size) +{ + int ret = OIS_ERROR; + int loop = 0; + + if (!data_p) { + CAM_ERR(CAM_OIS, "data_p is NULL"); + return OIS_ERROR; + } + /* enter boot mode */ + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "jump boot failed!"); + return OIS_ERROR; + } + /* update flash */ + do { + ret = aw_soc_flash_download_check(o_ctrl, addr, data_p, fw_size); + if (ret == OIS_SUCCESS) + break; + CAM_ERR(CAM_OIS, "aw_soc_flash_download_check failed! loop:%d", loop); + } while ((++loop) < AW_ERROR_LOOP); + if (loop >= AW_ERROR_LOOP) + return OIS_ERROR; + + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_reset failed!"); + return ret; + } + msleep(AW_RESET_DELAY); + + CAM_INFO(CAM_OIS, "success!"); + + return OIS_SUCCESS; +} + +static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, + const struct firmware *fw) +{ + uint32_t temp = 0; + uint32_t *check_ptr = NULL; + int i = 0; + int ret = 0; + char *identify = (char *)fw->data + AW_FW_SHIFT_IDENTIFY; + + if (fw == NULL) { + CAM_ERR(CAM_OIS, "FW Empty!!!"); + return OIS_ERROR; + } + + ret = memcmp(fw_check_str, identify, 8); /* AWINIC00 8bytes */ + if (ret != 0) { + CAM_ERR(CAM_OIS, "loaded wrong firmware!"); + return OIS_ERROR; + } + + /* get fw info */ + g_aw86006_info.fw.size = fw->size; + g_aw86006_info.fw.checksum = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_CHECKSUM]); + g_aw86006_info.fw.app_checksum = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_APP_CHECKSUM]); + /* app_length: app + check_info */ + g_aw86006_info.fw.app_length = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_APP_LENGTH]) + + AW_FW_INFO_LENGTH; + g_aw86006_info.fw.app_version = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_APP_VERSION]); + g_aw86006_info.fw.app_id = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_APP_ID]); + g_aw86006_info.fw.move_checksum = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_MOVE_CHECKSUM]); + g_aw86006_info.fw.move_version = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_MOVE_VERSION]); + g_aw86006_info.fw.move_length = + *(uint32_t *) (&fw->data[AW_FW_SHIFT_MOVE_LENGTH]); + + CAM_INFO(CAM_OIS, "fw->size:0x%04X, app_length:0x%04X, app_version:0x%08X, app_id:0x%02X, move_version:0x%08X, move_length:0x%04X", + g_aw86006_info.fw.size, g_aw86006_info.fw.app_length, + g_aw86006_info.fw.app_version, g_aw86006_info.fw.app_id, + g_aw86006_info.fw.move_version, g_aw86006_info.fw.move_length); + + /* length check */ + temp = g_aw86006_info.fw.move_length + g_aw86006_info.fw.app_length; + if (g_aw86006_info.fw.size != temp) { + CAM_ERR(CAM_OIS, "fw->size error: 0x%X != 0x%X", + g_aw86006_info.fw.size, temp); + return OIS_ERROR; + } + + /* move checksum check */ + check_ptr = (uint32_t *) &fw->data[0]; + temp = 0; + for (i = 0; i < (g_aw86006_info.fw.move_length / sizeof(uint32_t)); i++) + temp += check_ptr[i]; + if (temp != g_aw86006_info.fw.move_checksum) { + CAM_ERR(CAM_OIS, "move checksum error:0x%08X != 0x%08X", + g_aw86006_info.fw.move_checksum, temp); + return OIS_ERROR; + } + + /* info checksum check */ + check_ptr = (uint32_t *) &fw->data[AW_FW_SHIFT_CHECKSUM_ADDR]; + temp = 0; + /* identify length:8bytes; info_checksum length:4byes */ + for (i = 0; i < ((AW_FW_INFO_LENGTH - 8 - 4) / sizeof(uint32_t)); i++) + temp += check_ptr[i]; + if (temp != g_aw86006_info.fw.checksum) { + CAM_ERR(CAM_OIS, "check_info checksum error:0x%08X != 0x%08X", + g_aw86006_info.fw.checksum, temp); + return OIS_ERROR; + } + + /* app checksum check */ + check_ptr = (uint32_t *) &fw->data[AW_FLASH_MOVE_LENGTH + + AW_FW_INFO_LENGTH]; + temp = 0; + for (i = 0; i < ((g_aw86006_info.fw.app_length - AW_FW_INFO_LENGTH) / + sizeof(uint32_t)); i++) + temp += check_ptr[i]; + + if (temp != g_aw86006_info.fw.app_checksum) { + CAM_ERR(CAM_OIS, "app checksum error:0x%08X != 0x%08X", + g_aw86006_info.fw.app_checksum, temp); + return OIS_ERROR; + } + /* Save firmware checkinfo */ + memcpy(&g_aw86006_info.checkinfo_fw[0], + fw->data + AW_FLASH_MOVE_LENGTH, AW_FW_INFO_LENGTH); + + CAM_INFO(CAM_OIS, "pass!"); + + return OIS_SUCCESS; +} + +static int aw_checkinfo_analyse(struct cam_ois_ctrl_t *o_ctrl, + uint8_t *checkinfo_rd, struct aw86006_fw *info) +{ + uint32_t temp = 0; + uint32_t *check_ptr = NULL; + int i = 0; + int ret = 0; + + if ((checkinfo_rd == NULL) || (info == NULL)) { + CAM_ERR(CAM_OIS, "checkinfo empty!"); + return OIS_ERROR; + } + /* compare identify: AWINIC00 */ + ret = memcmp(fw_check_str, (char *)checkinfo_rd, 8); + if (ret != 0) { + CAM_ERR(CAM_OIS, "checkinfo not match!"); + return OIS_ERROR; + } + + info->checksum = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_CHECKSUM - + AW_FLASH_MOVE_LENGTH]); + info->app_checksum = + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_CHECKSUM - + AW_FLASH_MOVE_LENGTH]); + info->app_length = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_LENGTH - + AW_FLASH_MOVE_LENGTH]) + AW_FW_INFO_LENGTH; + info->app_version = + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_VERSION - + AW_FLASH_MOVE_LENGTH]); + info->app_id = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_ID - + AW_FLASH_MOVE_LENGTH]); + info->move_checksum = + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_CHECKSUM - + AW_FLASH_MOVE_LENGTH]); + info->move_version = + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_VERSION - + AW_FLASH_MOVE_LENGTH]); + info->move_length = + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_LENGTH - + AW_FLASH_MOVE_LENGTH]); + + CAM_INFO(CAM_OIS, "checkinfo app_length:0x%04X, app_version:0x%08X, app_id:0x%02X, move_version:0x%08X, move_length:0x%04X", + info->app_length, info->app_version, info->app_id, + info->move_version, info->move_length); + + /* info checksum check */ + check_ptr = (uint32_t *) &checkinfo_rd[AW_FW_SHIFT_CHECKSUM_ADDR - + AW_FLASH_MOVE_LENGTH]; + temp = 0; + for (i = 0; i < ((AW_FW_INFO_LENGTH - 8 - 4) / sizeof(uint32_t)); i++) + temp += check_ptr[i]; + if (temp != info->checksum) { + CAM_ERR(CAM_OIS, "checkinfo_rd checksum error:0x%08X != 0x%08X", + info->checksum, temp); + return OIS_ERROR; + } + CAM_INFO(CAM_OIS, "pass!"); + return OIS_SUCCESS; +} + +static int aw_get_standby_flag(struct cam_ois_ctrl_t *o_ctrl, uint8_t *pflag) +{ + int ret = 0; + uint8_t flag = 0; + uint8_t temp_addr = 0; + + temp_addr = o_ctrl->io_master_info.cci_client->sid; + o_ctrl->io_master_info.cci_client->sid = AW_SHUTDOWN_I2C_ADDR; + ret = ois_block_read_addr8_data8(o_ctrl, 0xFF11, + CAMERA_SENSOR_I2C_TYPE_WORD, &flag, 1); + o_ctrl->io_master_info.cci_client->sid = temp_addr; + if (ret < 0) { + CAM_ERR(CAM_OIS, "read standby flag error, ret: %d", ret); + return ret; + } + + *pflag = flag; + CAM_INFO(CAM_OIS, "standby flag: %d", flag); + + return OIS_SUCCESS; +} + +static int aw86006_mem_download(struct cam_ois_ctrl_t *o_ctrl, + const struct firmware *fw) +{ + struct aw86006_fw info_rd; + size_t all_buf_size = g_aw86006_info.fw.app_length + + AW_FLASH_MOVE_LENGTH; + size_t app_buf_size = g_aw86006_info.fw.app_length; + int i = 0; + int ret = OIS_ERROR; + uint8_t *all_buf_ptr = (uint8_t *) fw->data; + uint8_t *app_buf_ptr = (uint8_t *) fw->data + AW_FLASH_MOVE_LENGTH; + + if (fw == NULL) { + CAM_ERR(CAM_OIS, "FW Empty!!!"); + return OIS_ERROR; + } + + /* enter boot mode */ + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "jump boot failed!"); + return OIS_ERROR; + } +#ifdef AW_SOC_FLASH_READ_FLAG + /* get check_info data */ + ret = aw_soc_flash_read_check(o_ctrl, AW_FLASH_APP_ADDR, + &g_aw86006_info.checkinfo_rd[0], AW_FLASH_READ_LEN); + if (ret != OIS_SUCCESS) + CAM_ERR(CAM_OIS, "checkinfo read error!"); +#endif + g_aw86006_info.fw.update_flag = + g_aw86006_info.checkinfo_rd[AW_ARRAY_SHIFT_UPDATE_FLAG]; + + if (g_aw86006_info.fw.update_flag != 0x01) { + CAM_INFO(CAM_OIS, "update_flag not match, update all!"); + ret = aw_soc_flash_update(o_ctrl, AW_FLASH_BASE_ADDR, + all_buf_ptr, all_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update all failed!"); + return OIS_ERROR; + } + } else { + CAM_INFO(CAM_OIS, "update_flag match!"); + ret = memcmp(g_aw86006_info.checkinfo_rd, + g_aw86006_info.checkinfo_fw, AW_FW_INFO_LENGTH); + if (ret != 0) { + ret = aw_checkinfo_analyse(o_ctrl, + g_aw86006_info.checkinfo_rd, &info_rd); + if ((ret != OIS_SUCCESS) || (info_rd.move_version != + g_aw86006_info.fw.move_version)) { + CAM_ERR(CAM_OIS, + "checkinfo or move not match, update all!"); + ret = aw_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, + all_buf_ptr, all_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update all failed!"); + return OIS_ERROR; + } + } else if ((info_rd.app_version != + g_aw86006_info.fw.app_version) || + (info_rd.app_id != + g_aw86006_info.fw.app_id)) { + CAM_ERR(CAM_OIS, "app not match, update app!"); + ret = aw_soc_flash_update(o_ctrl, + AW_FLASH_APP_ADDR, + app_buf_ptr, app_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update app failed!"); + return OIS_ERROR; + } + } else { + CAM_ERR(CAM_OIS, "other error, update all!"); + ret = aw_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, + all_buf_ptr, all_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update all failed!"); + return OIS_ERROR; + } + } + } else { + ret = aw_jump_move_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, + "aw_jump_move_check fail, update all!"); + ret = aw_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, all_buf_ptr, + all_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update all failed!"); + return OIS_ERROR; + } + } else { + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_reset failed!"); + return OIS_ERROR; + } + msleep(AW_RESET_DELAY); + } + } + } + + for (i = 0; i <= AW_ERROR_LOOP; i++) { + ret = aw_runtime_check(o_ctrl); + if (ret == OIS_SUCCESS) { + CAM_INFO(CAM_OIS, + "runtime_check pass, no need to update fw!"); + break; + } + CAM_ERR(CAM_OIS, + "runtime_check failed, update app! loop:%d", i); + if (i == AW_ERROR_LOOP) + break; + + ret = aw_soc_flash_update(o_ctrl, AW_FLASH_APP_ADDR, app_buf_ptr, + app_buf_size); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "update app failed!"); + break; + } + } + + return ret; +} + +int aw_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw) +{ +// const struct firmware *fw; +// int loop = 0; + int ret = OIS_ERROR; + uint8_t standby_flag = 0; + + CAM_INFO(CAM_OIS, "start!"); + /* load firmware */ + /* + do { + ret = request_firmware(&fw, AW86006_FW_NAME, &o_ctrl->pdev->dev); + if (ret == 0) + break; + } while ((++loop) < AW_ERROR_LOOP); + if (loop >= AW_ERROR_LOOP) { + CAM_ERR(CAM_OIS, "request_firmware [%s] failed!", AW86006_FW_NAME); + return OIS_ERROR; + } + */ + /* fw check */ + CAM_INFO(CAM_OIS, "Load:%s size:%zu", AW86006_FW_NAME, fw->size); + ret = aw_firmware_check(o_ctrl, fw); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "fw check failed!"); + goto err_fw_check; + } + /* reset */ + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "reset failed"); + goto err_reset; + } + mdelay(AW_RESET_DELAY); /* run app after reset */ + /* Get standby flag */ + ret = aw_get_standby_flag(o_ctrl, &standby_flag); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "get standby flag failed"); + goto err_get_standby_flg; + } + if (standby_flag == AW_IC_STANDBY) { + ret = aw_runtime_check(o_ctrl); + if (ret == OIS_SUCCESS) + CAM_INFO(CAM_OIS, "runtime_check pass, no need to update fw!"); + } + /* update flash */ + if ((standby_flag != AW_IC_STANDBY) || (ret != OIS_SUCCESS)) { + ret = aw86006_mem_download(o_ctrl, fw); + if (ret == OIS_SUCCESS) + CAM_INFO(CAM_OIS, "fw update success!"); + else + CAM_ERR(CAM_OIS, "fw update failed, ret: %d", ret); + } + +err_get_standby_flg: +err_reset: +err_fw_check: + release_firmware(fw); + return ret; +} + +void aw_firmware_update_work_routine(struct work_struct *work) +{ + struct cam_ois_ctrl_t *o_ctrl = + container_of(work, struct cam_ois_ctrl_t, fw_update_work); + const struct firmware *fw = NULL; + int loop = 0; + int ret = 0; + + CAM_INFO(CAM_OIS, "enter"); + + // load firmware + do { + ret = request_firmware(&fw, AW86006_FW_NAME, &o_ctrl->pdev->dev); + if (ret == 0) + break; + } while ((++loop) < AW_ERROR_LOOP); + if (loop >= AW_ERROR_LOOP) { + CAM_ERR(CAM_OIS, "request_firmware [%s] failed! stop update firmware!", AW86006_FW_NAME); + } + else{ + mutex_lock(&o_ctrl->ois_mutex_aw); + aw_firmware_update(o_ctrl,fw); + mutex_unlock(&o_ctrl->ois_mutex_aw); + } +} + +/******************************************************************************* + * adb debug interface + ******************************************************************************/ +static ssize_t reg_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + uint8_t reg_val = 0; + ssize_t len = 0; + uint32_t i = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + mutex_lock(&o_ctrl->ois_mutex_aw); + for (i = 0; i < 20; i++) { + ois_block_read_addr8_data8(o_ctrl, i, CAMERA_SENSOR_I2C_TYPE_WORD, + ®_val, 1); + len += snprintf(buf + len, PAGE_SIZE - len, + "reg:0x%04X=0x%02X\n", i, reg_val); + } + mutex_unlock(&o_ctrl->ois_mutex_aw); + return len; +} + +static ssize_t reg_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) +{ + uint32_t databuf[2] = {0}; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { + mutex_lock(&o_ctrl->ois_mutex_aw); + ois_block_write_addr8_data8(o_ctrl, databuf[0], + CAMERA_SENSOR_I2C_TYPE_WORD, (uint8_t *) &databuf[1], + CAMERA_SENSOR_I2C_TYPE_BYTE); + mutex_unlock(&o_ctrl->ois_mutex_aw); + } + + return count; +} + +static ssize_t awrw_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int i = 0; + ssize_t len = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + if (o_ctrl->awrw_flag != AW_SEQ_READ) { + CAM_ERR(CAM_OIS, "not read mode"); + return -ERANGE; + } + if (o_ctrl->reg_data == NULL) { + CAM_ERR(CAM_OIS, "reg_data empty!"); + return -ERANGE; + } + for (i = 0; i < o_ctrl->reg_num; i++) { + len += snprintf(buf + len, PAGE_SIZE - len, + "0x%02x,", o_ctrl->reg_data[i]); + } + len += snprintf(buf + len - 1, PAGE_SIZE - len, "\n"); + return len; +} + +static ssize_t awrw_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) +{ + uint8_t value = 0; + char data_buf[5] = {0}; + int i = 0; + int rc = 0; + uint32_t flag = 0; + uint32_t reg_num = 0; + uint32_t reg_addr = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + if (sscanf(buf, "%x %x %x", &flag, ®_num, ®_addr) == 3) { + if (!reg_num) { + CAM_ERR(CAM_OIS, "reg_num param error"); + return -ERANGE; + } + mutex_lock(&o_ctrl->ois_mutex_aw); + o_ctrl->awrw_flag = flag; + o_ctrl->reg_num = reg_num; + if (o_ctrl->reg_data != NULL) + kfree(o_ctrl->reg_data); + o_ctrl->reg_data = kmalloc(reg_num, GFP_KERNEL); + if (flag == AW_SEQ_WRITE) { + for (i = 0; i < reg_num; i++) { + if ((i * 5 + 5) > (strlen(buf) - 2 * (4 + 1) - (6 + 1))) { + CAM_ERR(CAM_OIS, "buf length error"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return -ERANGE; + } + memcpy(data_buf, &buf[17 + i * 5], 4); + data_buf[4] = '\0'; + rc = kstrtou8(data_buf, 0, &value); + if (rc < 0) { + CAM_ERR(CAM_OIS, "input buf error"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return -ERANGE; + } + o_ctrl->reg_data[i] = value; + } + ois_block_write_addr8_data8(o_ctrl, reg_addr, + CAMERA_SENSOR_I2C_TYPE_WORD, o_ctrl->reg_data, reg_num); + } else if (flag == AW_SEQ_READ) { + ois_block_read_addr8_data8(o_ctrl, reg_addr, + CAMERA_SENSOR_I2C_TYPE_WORD, o_ctrl->reg_data, reg_num); + } + mutex_unlock(&o_ctrl->ois_mutex_aw); + } else { + CAM_ERR(CAM_OIS, "param error"); + } + return count; +} + +static ssize_t update_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, + "update ois: echo 1 > update\n"); + + return len; +} + +static ssize_t update_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + uint32_t databuf = 0; + int ret = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + ret = kstrtouint(buf, 0, &databuf); + if (ret < 0) { + CAM_ERR(CAM_OIS, "kstrtouint fail"); + return ret; + } + + /* fw update */ + if (databuf != 1) { + CAM_INFO(CAM_OIS, "flag error: %d", databuf); + return -EPERM; + } + + schedule_work(&o_ctrl->fw_update_work); + return count; +} + +static ssize_t erase_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, + "erase app flash: echo app > erase\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "erase all flash: echo all > erase\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "ois reset: echo reset > erase\n"); + + return len; +} + +static ssize_t erase_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + char databuf[10] = {0}; + char readbuf[64] = {0}; + int ret = OIS_ERROR; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + if (sscanf(buf, "%s", databuf) == 1) { + mutex_lock(&o_ctrl->ois_mutex_aw); + if (strcmp(databuf, "app") == 0) { + CAM_INFO(CAM_OIS, "aw86006 will erase app!"); + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + goto err_exit; + } + ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, + AW_FLASH_FULL_SIZE - + AW_FLASH_MOVE_LENGTH); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + goto err_exit; + } + } else if (strcmp(databuf, "all") == 0) { + CAM_INFO(CAM_OIS, "aw86006 will erase all!"); + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + goto err_exit; + } + ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_BASE_ADDR, + AW_FLASH_FULL_SIZE); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + goto err_exit; + } + } else if (strcmp(databuf, "read") == 0) { + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + goto err_exit; + } + ret = aw_soc_flash_read_check(o_ctrl, AW_FLASH_APP_ADDR, + readbuf, AW_FLASH_READ_LEN); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + goto err_exit; + } + } else if (strcmp(databuf, "reset") == 0) { + CAM_INFO(CAM_OIS, "aw86006 reset"); + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "aw_reset failed!"); + goto err_exit; + } + } else { + CAM_ERR(CAM_OIS, "Erase: %s is not support!", databuf); + } + + mutex_unlock(&o_ctrl->ois_mutex_aw); + } + + return count; + +err_exit: + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; +} + +static ssize_t mode_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, + "OIS_ON: echo 1 > mode\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "OIS_OFF: echo 0 > mode\n"); + + return len; +} + +static ssize_t mode_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) +{ + uint8_t temp = 0; + int ret = OIS_SUCCESS; + int loop = 0; + uint32_t ois_status = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + ret = kstrtou32(buf, 0, &ois_status); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Number of parameters error"); + return ret; + } + if ((ois_status != OIS_DISABLE) && (ois_status != OIS_ENABLE)) { + CAM_ERR(CAM_OIS, "ois_status error: %d", ois_status); + return -EPERM; + } + /* enable OIS mode */ + mutex_lock(&o_ctrl->ois_mutex_aw); + do { + temp = (uint8_t)ois_status; + CAM_INFO(CAM_OIS, "set ois status: %d", temp); + + ret = ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, + CAMERA_SENSOR_I2C_TYPE_WORD, &temp, 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Send OIS mode failed!"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; + } + /* 1000 us */ + usleep_range(1000, 1500); + + /* check OIS enable status */ + temp = 0; + ret = ois_block_read_addr8_data8(o_ctrl, REG_OIS_ENABLE, + CAMERA_SENSOR_I2C_TYPE_WORD, &temp, 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Read OIS mode error"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; + } + + if (temp == ois_status) { + CAM_INFO(CAM_OIS, "Set OIS mode success!"); + break; + } + CAM_ERR(CAM_OIS, "OIS mode check error! value: 0x%02x", temp); + } while ((++loop) < AW_ERROR_LOOP); + mutex_unlock(&o_ctrl->ois_mutex_aw); + if (loop >= AW_ERROR_LOOP) + return OIS_ERROR; + + return count; +} + +static ssize_t chipid_show(struct class *class, struct class_attribute *attr, + char *buf) +{ + uint8_t chipid = 0; + ssize_t len = 0; + int ret = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + mutex_lock(&o_ctrl->ois_mutex_aw); + ret = ois_block_read_addr8_data8(o_ctrl, REG_CHIPID, + CAMERA_SENSOR_I2C_TYPE_WORD, &chipid, 1); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read chipid error"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; + } + + len += snprintf(buf + len, PAGE_SIZE - len, "Chipid: 0x%02X\n", chipid); + mutex_unlock(&o_ctrl->ois_mutex_aw); + + return len; +} + +static ssize_t chipid_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +static ssize_t version_show(struct class *class, struct class_attribute *attr, + char *buf) +{ + uint8_t temp[4] = { 0 }; + uint32_t version = 0; + int ret = 0; + ssize_t len = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + mutex_lock(&o_ctrl->ois_mutex_aw); + ret = ois_block_read_addr8_data8(o_ctrl, REG_VERSION, + CAMERA_SENSOR_I2C_TYPE_WORD, temp, 4); + if (ret < 0) { + CAM_ERR(CAM_OIS, "read version error"); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; + } + + version = (temp[3] << 24) | (temp[2] << 16) | (temp[1] << 8) | temp[0]; + + len += snprintf(buf + len, PAGE_SIZE - len, "version: v%d.%d.%d.%d\n", + temp[3], temp[2], temp[1], temp[0]); + mutex_unlock(&o_ctrl->ois_mutex_aw); + + return len; +} + +static ssize_t version_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +static ssize_t checkinfo_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + int i; + + for (i = 0; i < 8; i++) { + len += snprintf(buf + len, PAGE_SIZE - len, + "checkinfo_rd_0x%x 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + i, g_aw86006_info.checkinfo_rd[i * 8 + 0], + g_aw86006_info.checkinfo_rd[i * 8 + 1], + g_aw86006_info.checkinfo_rd[i * 8 + 2], + g_aw86006_info.checkinfo_rd[i * 8 + 3], + g_aw86006_info.checkinfo_rd[i * 8 + 4], + g_aw86006_info.checkinfo_rd[i * 8 + 5], + g_aw86006_info.checkinfo_rd[i * 8 + 6], + g_aw86006_info.checkinfo_rd[i * 8 + 7]); + len += snprintf(buf + len, PAGE_SIZE - len, + "checkinfo_fw_0x%x 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + i, g_aw86006_info.checkinfo_fw[i * 8 + 0], + g_aw86006_info.checkinfo_fw[i * 8 + 1], + g_aw86006_info.checkinfo_fw[i * 8 + 2], + g_aw86006_info.checkinfo_fw[i * 8 + 3], + g_aw86006_info.checkinfo_fw[i * 8 + 4], + g_aw86006_info.checkinfo_fw[i * 8 + 5], + g_aw86006_info.checkinfo_fw[i * 8 + 6], + g_aw86006_info.checkinfo_fw[i * 8 + 7]); + } + + return len; +} + +static ssize_t checkinfo_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + uint32_t data[9] = {0}; + int i; + + if (sscanf(buf, "%x %x %x %x %x %x %x %x %x", &data[0], &data[1], + &data[2], &data[3], &data[4], &data[5], &data[6], &data[7], + &data[8]) == 9) { + if (data[0] > 7) { + CAM_ERR(CAM_OIS, "wrong data[0]:%d", data[0]); + return count; + } + for (i = 0; i < 8; i++) { + g_aw86006_info.checkinfo_rd[data[0] * 8 + i] = + (uint8_t) data[i + 1]; + } + } + return count; +} + +static ssize_t freq_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, + "g_cci_freq=%d\n", g_cci_freq); + + return len; +} + +static ssize_t freq_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) +{ + uint32_t databuf[1]; + + if (sscanf(buf, "%d", &databuf[0]) == 1) { + if (databuf[0] < I2C_MAX_MODES) + g_cci_freq = databuf[0]; + } + + return count; +} + +static ssize_t jump_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + + len += snprintf(buf + len, PAGE_SIZE - len, + "jump boot: echo boot > jump\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "jump move: echo move > jump\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "reset: echo reset > jump\n"); + + return len; +} + +static ssize_t jump_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + char databuf[10] = {0}; + int ret = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + if (sscanf(buf, "%s", databuf) == 1) { + mutex_lock(&o_ctrl->ois_mutex_aw); + if (strcmp(databuf, "boot") == 0) { + CAM_INFO(CAM_OIS, "aw86006 will jump boot!"); + ret = aw_jump_boot_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "jump boot failed!"); + goto err_exit; + } + } else if (strcmp(databuf, "move") == 0) { + CAM_INFO(CAM_OIS, "aw86006 will jump move!"); + ret = aw_jump_move_check(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "jump move failed!"); + goto err_exit; + } + } else if (strcmp(databuf, "reset") == 0) { + CAM_INFO(CAM_OIS, "aw86006 will reset!"); + ret = aw_reset(o_ctrl); + if (ret != OIS_SUCCESS) { + CAM_ERR(CAM_OIS, "reset failed!"); + goto err_exit; + } + } else { + CAM_ERR(CAM_OIS, "jump [%s] is not support!", databuf); + } + + mutex_unlock(&o_ctrl->ois_mutex_aw); + } + + return count; + +err_exit: + mutex_unlock(&o_ctrl->ois_mutex_aw); + return ret; +} + +static ssize_t gyro_offset_cali_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + ssize_t len = 0; + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + uint8_t val[6] = { 0 }; + int16_t offset_val; + + len += snprintf(buf + len, PAGE_SIZE - len, + "gyro_offset: echo 1 > gyro_offset_cali\n"); + + /* Gyro offset data */ + ois_block_read_addr8_data8(o_ctrl, 0xf84c, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 4); + offset_val = val[1]<<8 |val[0]; + len += snprintf(buf + len, PAGE_SIZE - len, + "gyro x offset = %d\n", offset_val); + + offset_val = val[3]<<8 |val[2]; + len += snprintf(buf + len, PAGE_SIZE - len, + "gyro y offset = %d\n", offset_val); + + return len; +} + +static ssize_t gyro_offset_cali_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + int i = 0; + uint8_t data_buf[5] = { 0 }; + uint8_t val[15] = { 0 }; + uint8_t ois_mode = 0; + int16_t offset_val = 0; + + if (sscanf(buf, "%d", &data_buf[0]) != 1) { + CAM_ERR(CAM_OIS, "input para error!"); + return OIS_ERROR; + } + CAM_INFO(CAM_OIS, "aw86006 gyro offset cali start!"); + + /* off OIS */ + ois_mode = OIS_DISABLE; + ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, + CAMERA_SENSOR_I2C_TYPE_WORD, &ois_mode, 1); + msleep(20); + + i = 0; + do { + val[0] = 0xa4; + ois_block_write_addr8_data8(o_ctrl, 0xf20f, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 1); + msleep(20); + ois_block_read_addr8_data8(o_ctrl, 0xf20f, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 1); + i++; + } while ((val[0] != 1) && (i < (50 * AW_ERROR_LOOP))); + if (val[0] != 1) { + CAM_ERR(CAM_OIS, "read reg[0xf20f] != 0x01, i=%d,val[0]=%d",i,val[0] ); + return OIS_ERROR; + } + + i = 0; + do { + val[1] = 0xac; + ois_block_write_addr8_data8(o_ctrl, 0xf8ff, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[1], 1); + msleep(20); + ois_block_read_addr8_data8(o_ctrl, 0xf8ff, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[1], 1); + i++; + } while ((val[1] != 1) && (i < (50 * AW_ERROR_LOOP))); + if (val[1] != 1) { + CAM_ERR(CAM_OIS, "read reg[0xf8ff] != 0x01, i=%d,val=%d",i,val[1] ); + return OIS_ERROR; + } + + val[2] = 0x01; + ois_block_write_addr8_data8(o_ctrl, 0xf8e4, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[2], 1); + msleep(5); /* delay 5ms at least */ + + val[3] = 0x02; + ois_block_write_addr8_data8(o_ctrl, 0xf200, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[3], 1); + val[4] = 0x01; + ois_block_write_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[4], 1); + val[5] = 0x01; + ois_block_write_addr8_data8(o_ctrl, 0xf202, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[5], 1); + msleep(2000); /* delay 2s at least */ + + i = 0; + do { + ois_block_read_addr8_data8(o_ctrl, 0xf201, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[5], 1); + msleep(20); + i++; + } while ((val[5] != 0x21) && (i < (50 * AW_ERROR_LOOP))); + if (val[5] != 0x21) { + CAM_ERR(CAM_OIS, "read reg[0xf201] != 0x21, i=%d,val=%d",i,val[5] ); + return OIS_ERROR; + } + + val[6] = 0x00; + ois_block_write_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[6], 1); + val[7] = 0x02; + ois_block_write_addr8_data8(o_ctrl, 0xf8e4, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[7], 1); + val[8] = 0xdc; + ois_block_write_addr8_data8(o_ctrl, 0xf8ff, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[8], 1); + val[9] = 0xd4; + ois_block_write_addr8_data8(o_ctrl, 0xf20f, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[9], 1); + + /* Gyro offset data */ + ois_block_read_addr8_data8(o_ctrl, 0xf84c, + CAMERA_SENSOR_I2C_TYPE_WORD, &val[10], 4); + offset_val = (val[11]<<8) |val[10]; + CAM_INFO(CAM_OIS, "aw86006 gyro x offset = %d!", offset_val); + + offset_val = (val[13]<<8) |val[12]; + CAM_INFO(CAM_OIS, "aw86006 gyro y offset = %d!", offset_val); + + CAM_INFO(CAM_OIS, "aw86006 gyro offset cali success!"); + return count; +} + +/******************************************************************************* + * Debug node + * Path: /sys/class/aw86006_ois + * ****************************************************************************/ +static CLASS_ATTR_RW(reg); +static CLASS_ATTR_RW(awrw); +static CLASS_ATTR_RW(update); +static CLASS_ATTR_RW(erase); +static CLASS_ATTR_RW(mode); +static CLASS_ATTR_RW(chipid); +static CLASS_ATTR_RW(version); +static CLASS_ATTR_RW(checkinfo); +static CLASS_ATTR_RW(freq); +static CLASS_ATTR_RW(jump); +static CLASS_ATTR_RW(gyro_offset_cali); + +int aw_create_sysfs(void) +{ + int ret = 0; + + if (!ois_debug_class) { + CAM_INFO(CAM_OIS, "create aw86006_result_class!"); + ois_debug_class = class_create(THIS_MODULE, "ois"); + + ret = class_create_file(ois_debug_class, &class_attr_reg); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file reg failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_awrw); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file awrw failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_update); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file update failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_erase); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file erase failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_mode); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file mode failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_chipid); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file chipid failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_version); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file version failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_checkinfo); + if (ret < 0) { + CAM_ERR(CAM_OIS, + "Create class file checkinfo failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_freq); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file freq failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_jump); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file jump failed, ret:%d", + ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_gyro_offset_cali); + if (ret < 0) { + CAM_ERR(CAM_OIS, "Create class file gyro offset failed, ret:%d", ret); + return ret; + } + } + + CAM_INFO(CAM_OIS, "Creat sysfs debug success."); + return 0; +} + +void aw_destroy_sysfs(void) +{ + if (ois_debug_class) { + class_remove_file(ois_debug_class, &class_attr_reg); + class_remove_file(ois_debug_class, &class_attr_update); + class_remove_file(ois_debug_class, &class_attr_erase); + class_remove_file(ois_debug_class, &class_attr_awrw); + class_remove_file(ois_debug_class, &class_attr_checkinfo); + class_remove_file(ois_debug_class, &class_attr_freq); + class_remove_file(ois_debug_class, &class_attr_jump); + class_remove_file(ois_debug_class, &class_attr_chipid); + class_remove_file(ois_debug_class, &class_attr_version); + class_remove_file(ois_debug_class, &class_attr_mode); + class_remove_file(ois_debug_class, &class_attr_gyro_offset_cali); + class_destroy(ois_debug_class); + ois_debug_class = NULL; + CAM_INFO(CAM_OIS, "delete ois_debug_class done!"); + } +} + + +/******************************************************************************* + * aw86006 ois init + ******************************************************************************/ +int aw_ois_init(struct cam_ois_ctrl_t *o_ctrl) +{ + int rc = 0; + + CAM_INFO(CAM_OIS, "enter, %s", AW86006_DRIVER_VERSION); + o_ctrl_g = o_ctrl; + INIT_WORK(&o_ctrl->fw_update_work, aw_firmware_update_work_routine); + mutex_init(&o_ctrl->ois_mutex_aw); + aw_create_sysfs(); + CAM_INFO(CAM_OIS, "exit"); + + return rc; +} + +int aw_ois_exit(struct cam_ois_ctrl_t *o_ctrl) +{ + int rc = 0; + + CAM_INFO(CAM_OIS, "enter"); + aw_destroy_sysfs(); + return rc; +} + +MODULE_DESCRIPTION("AWINIC OIS Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h new file mode 100644 index 000000000000..7565750f6fd1 --- /dev/null +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -0,0 +1,193 @@ +#ifndef AW86006_OIS_H +#define AW86006_OIS_H + +/* I2c address */ +#define AW_SHUTDOWN_I2C_ADDR (0xC2 >> 1) /* 0x61 */ +#define AW_WAKEUP_I2C_ADDR (0xD2 >> 1) /* 0x69 */ + +/* Register detail */ +#define REG_CHIPID (0x0000) +#define REG_OIS_ENABLE (0x0001) +#define REG_OIS_STATUS (0x0002) +#define REG_PACKING_RST (0x0003) +#define REG_DATA_READY (0x0004) +#define REG_SAMPLE_TIME (0x0005) +#define REG_PACK_DATA (0x0006) +#define REG_SPI_GYRO (0x0007) +#define REG_SPI_CFG (0x0008) +#define REG_AF_CODE_H (0x0009) +#define REG_AF_CODE_L (0x000A) +#define REG_AF_ARCT (0x000B) +#define REG_AF_CFG (0x000C) +#define REG_AF_BUSY (0x000D) +#define REG_VERSION (0x0010) +#define REG_STANDBY (0xFF11) + +/* Flag */ +#define OIS_ENABLE (0x01) +#define OIS_DISABLE (0x00) +#define OIS_ERROR (-1) +#define OIS_SUCCESS (0) +#define AW_IC_STANDBY (1) +#define AW_FLASH_WRITE_CONNECT + +/* Loop */ +#define AW_STAY_ON_MOVE_LOOP (20) +#define AW_STAY_ON_BOOT_LOOP (20) +#define AW_ERROR_LOOP (5) +#define AW_FLASH_WRITE_ERROR_LOOP (2) +#define AW_FLASH_READ_ERROR_LOOP (2) +#define AW_FLASH_ERASE_ERROR_LOOP (2) +#define AW_JUMP_BOOT_LOOP (6) +#define AW_JUMP_MOVE_LOOP (6) +#define AW_STOP_CMD_LOOP (10) + +/* Addr or data size */ +#define AW_DATA_SHIFT_0_BIT (0) +#define AW_DATA_SHIFT_8_BIT (8) +#define AW_DATA_SHIFT_16_BIT (16) +#define AW_DATA_SHIFT_24_BIT (24) +#define AW_I2C_WRITE_BYTE_ZERO (0x00) + +/* Delay */ +#define AW_RESET_DELAY (50) /* ms */ +#define AW_JUMP_MOVE_DELAY (9) /* ms */ +#define AW_JUMP_MOVE_DELAY_MAX (16) /* ms */ +#define AW_JUMP_BOOT_DELAY (2) /* ms */ +#define AW_JUMP_BOOT_DELAY_MAX (6) /* ms */ +#define AW_SHUTDOWN_DELAY (2000) /* us */ + +/* Flash and firmware */ +#define AW_FLASH_BASE_ADDR (0x01000000) +#define AW_FLASH_APP_ADDR (0x01002000) +#define AW_FLASH_MOVE_LENGTH (AW_FLASH_APP_ADDR - AW_FLASH_BASE_ADDR) +#define AW_FLASH_FULL_SIZE (0x10000) +#define AW_FLASH_TOP_ADDR (AW_FLASH_BASE_ADDR + AW_FLASH_FULL_SIZE) +#define AW_FLASH_ERASE_LEN (512) +#define AW_FLASH_WRITE_LEN (64) +#define AW_FLASH_READ_LEN (64) +#define AW_FW_INFO_LENGTH (64) +#define AW_FW_SHIFT_IDENTIFY (AW_FLASH_MOVE_LENGTH) +#define AW_FW_SHIFT_CHECKSUM (AW_FW_SHIFT_IDENTIFY + 8) +#define AW_FW_SHIFT_APP_CHECKSUM (AW_FW_SHIFT_CHECKSUM + 4) +#define AW_FW_SHIFT_CHECKSUM_ADDR (AW_FW_SHIFT_APP_CHECKSUM) +#define AW_FW_SHIFT_APP_LENGTH (AW_FW_SHIFT_APP_CHECKSUM + 4) +#define AW_FW_SHIFT_APP_VERSION (AW_FW_SHIFT_APP_LENGTH + 4) +#define AW_FW_SHIFT_APP_ID (AW_FW_SHIFT_APP_VERSION + 4) +#define AW_FW_SHIFT_MOVE_CHECKSUM (AW_FW_SHIFT_APP_ID + 4) +#define AW_FW_SHIFT_MOVE_VERSION (AW_FW_SHIFT_MOVE_CHECKSUM + 4) +#define AW_FW_SHIFT_MOVE_LENGTH (AW_FW_SHIFT_MOVE_VERSION + 4) +#define AW_FW_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_MOVE_LENGTH + 8) +#define AW_ARRAY_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_UPDATE_FLAG - AW_FLASH_MOVE_LENGTH) + + +/* SOC */ +enum soc_status { + SOC_OK = 0, + SOC_ADDR_ERROR, + SOC_PBUF_ERROR, + SOC_HANK_ERROR, + SOC_JUMP_ERROR, + SOC_FLASH_ERROR, + SOC_SPACE_ERROR, +}; + +enum soc_module { + SOC_HANK = 0x01, + SOC_SRAM = 0x02, + SOC_FLASH = 0x03, + SOC_END = 0x04, +}; + +enum soc_enum { + SOC_VERSION = 0x01, + SOC_CTL = 0x00, + SOC_ACK = 0x01, + SOC_ADDR = 0x84, + SOC_READ_ADDR = 0x48, + SOC_ERASE_STRUCT_LEN = 6, + SOC_READ_STRUCT_LEN = 6, + SOC_PROTOCAL_HEAD = 9, + SOC_CONNECT_WRITE_LEN = 9, + SOC_ERASE_WRITE_LEN = 15, + SOC_READ_WRITE_LEN = 15, + SOC_ERASE_BLOCK_DELAY = 8, + SOC_WRITE_BLOCK_HEAD = 13, + SOC_WRITE_BLOCK_DELAY = 1000, /* us */ + SOC_READ_BLOCK_DELAY = 2000, /* us */ + SOC_CONNECT_DELAY = 2000, /* us */ +}; + +enum soc_flash_event { + SOC_FLASH_WRITE = 0x01, + SOC_FLASH_WRITE_ACK = 0x02, + SOC_FLASH_READ = 0x11, + SOC_FLASH_READ_ACK = 0x12, + SOC_FLASH_ERASE_BLOCK = 0x21, + SOC_FLASH_ERASE_BLOCK_ACK = 0x22, + SOC_FLASH_ERASE_CHIP = 0x23, + SOC_FLASH_ERASE_CHIP_ACK = 0x24, +}; + +enum soc_hank_event { + SOC_HANK_CONNECT = 0x01, + SOC_HANK_CONNECT_ACK = 0x02, + SOC_HANK_PROTICOL = 0x11, + SOC_HANK_PROTICOL_ACK = 0x12, + SOC_HANK_VERSION = 0x21, + SOC_HANK_VERSION_ACK = 0x22, + SOC_HANK_ID = 0x31, + SOC_HANK_ID_ACK = 0x32, + SOC_HANK_DATE = 0x33, + SOC_HANK_DATA_ACK = 0x34, +}; + +enum isp_enum { + ISP_READ_VERSION_DELAY = 500, /* us */ + ISP_VERS_CONNECT_ACK = 0x01, + ISP_VERSION_ACK_LEN = 5, + ISP_EVENT_OK = 0x01, +}; + +enum awrw_flag { + AW_SEQ_WRITE = 0, + AW_SEQ_READ = 1, +}; + +/* Struct */ +struct soc_protocol { + uint8_t checksum; + uint8_t protocol_ver; + uint8_t addr; + uint8_t module; + uint8_t event; + uint8_t len[2]; + uint8_t ack; + uint8_t sum; + uint8_t reserved[3]; + uint8_t ack_juge; + uint8_t *p_data; +}; + +struct aw86006_fw { + uint32_t checksum; + uint32_t app_checksum; + uint32_t app_length; + uint32_t app_version; + uint32_t app_id; + uint32_t move_checksum; + uint32_t move_version; + uint32_t move_length; + uint32_t update_flag; + uint32_t size; + uint8_t *data_p; +}; + +struct aw86006_info { + uint8_t already_update; + uint8_t checkinfo_fw[64]; + uint8_t checkinfo_rd[64]; + struct aw86006_fw fw; +}; + +#endif 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 318b8d692030..ef94e34cdf4d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -17,6 +17,7 @@ extern int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); extern void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); +extern int aw_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw); int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -413,6 +414,12 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) } CAM_INFO(CAM_OIS, "Firmware download started."); } + else if (strstr(o_ctrl->ois_name, "aw86006")) { + mutex_lock(&o_ctrl->ois_mutex_aw); + rc = aw_firmware_update(o_ctrl, fw); + mutex_unlock(&o_ctrl->ois_mutex_aw); + return rc; + } total_bytes = fw->size; if(o_ctrl->ois_fw_txn_data_sz == 0) @@ -509,8 +516,8 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) return -EINVAL; } - if (strstr(o_ctrl->ois_name, "dw9781")) { - CAM_DBG(CAM_OIS, "not need download coeff fw!"); + if (strstr(o_ctrl->ois_name, "dw9781") || strstr(o_ctrl->ois_name, "aw86006")) { + CAM_DBG(CAM_OIS, "not need download coeff fw for %s.", o_ctrl->ois_name); return 0; } diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 95414b9a0976..f54d44e3e864 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -10,6 +10,9 @@ #include "cam_debug_util.h" #include "camera_main.h" +extern int aw_ois_init(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ +extern int aw_ois_exit(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ + static int cam_ois_clear_data_ready(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}; @@ -511,6 +514,9 @@ static int cam_ois_component_bind(struct device *dev, mutex_init(&(o_ctrl->vsync_mutex)); init_completion(&o_ctrl->ois_data_complete); + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) + aw_ois_init(o_ctrl); + if (o_ctrl->is_ois_vsync_irq_supported) { o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); @@ -564,6 +570,9 @@ static void cam_ois_component_unbind(struct device *dev, } CAM_INFO(CAM_OIS, "platform driver remove invoked"); + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) + aw_ois_exit(o_ctrl); + soc_info = &o_ctrl->soc_info; for (i = 0; i < soc_info->num_clk; i++) devm_clk_put(soc_info->dev, soc_info->clk[i]); 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 227c0e8377c6..b06872bb53ae 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -166,6 +166,13 @@ struct cam_ois_ctrl_t { int ois_data_size; uint16_t q_timer_cnt; uint64_t mono_timestamp; + /* awinic_add */ + const char *ic_name; + struct work_struct fw_update_work; + uint32_t awrw_flag; + uint32_t reg_num; + uint8_t *reg_data; + struct mutex ois_mutex_aw; }; /** diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c index f8f1eefe5f0b..5b9619a1ead8 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_soc.c @@ -41,6 +41,12 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl) o_ctrl->is_ois_vsync_irq_supported = true; } + rc = of_property_read_string(of_node, "ois-name", &o_ctrl->ic_name); + if (rc) { + CAM_DBG(CAM_OIS, "ois-name is not available in the node: %d", rc); + o_ctrl->ic_name = NULL; + } + #ifdef CONFIG_CAMERA_DISABLE_VSYNC_IRQ o_ctrl->is_ois_vsync_irq_supported = false; CAM_WARN(CAM_OIS, "disable ois vsync irq in factory build"); From bf34dbc9732c06904d6a635b066e4b85aca84f3d Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Mon, 11 Apr 2022 14:31:01 +0800 Subject: [PATCH 53/86] camera: ois: update aw86006 driver to v0.5.0.4 [detail] update aw86006 driver to v0.5.0.4 Change-Id: Id31babd182095932606ddfec1a4ed1e45c6be32b Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2238334 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Shuo Wang Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_ois/cam_ois_aw86006.c | 1444 ++++++++++------- .../cam_ois/cam_ois_aw86006.h | 119 +- .../cam_sensor_module/cam_ois/cam_ois_core.c | 8 +- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 8 +- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 15 +- 5 files changed, 915 insertions(+), 679 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index c1acd5227d70..73a603c23ecb 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -47,14 +47,14 @@ #include "cam_packet_util.h" #include "cam_ois_aw86006.h" -#define AW86006_DRIVER_VERSION "v0.4.7" +#define AW86006_DRIVER_VERSION "v0.5.0.4" #define AW86006_FW_NAME "mot_aw86006.prog" const char fw_check_str[] = { 'A', 'W', 'I', 'N', 'I', 'C', 0, 0 }; -uint8_t g_cci_freq = I2C_FAST_PLUS_MODE; -struct cam_ois_ctrl_t *o_ctrl_g; +struct cam_ois_ctrl_t *g_o_ctrl; static struct class *ois_debug_class; struct aw86006_info g_aw86006_info = { + .already_update = 0, .checkinfo_fw = { 0 }, .checkinfo_rd = { 0 }, .fw = { 0 }, @@ -64,17 +64,15 @@ static int ois_block_read_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, uint32_t addr_type, uint8_t *data, uint32_t num_byte) { enum i2c_freq_mode temp_freq; - int ret = -1; - + int ret = OIS_ERROR; if (o_ctrl == NULL || data == NULL) { - CAM_ERR(CAM_OIS, "Invalid Args o_ctrl: %pK, data: %pK", - o_ctrl, data); + AW_LOGE("Invalid Args o_ctrl: %pK, data: %pK", o_ctrl, data); return -EINVAL; } if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { - CAM_ERR(CAM_OIS, "Not in right state to start soc reads: %d", - o_ctrl->cam_ois_state); + AW_LOGE("Not in right state to start soc reads: %d", + o_ctrl->cam_ois_state); return -EINVAL; } temp_freq = o_ctrl->io_master_info.cci_client->i2c_freq_mode; @@ -83,7 +81,7 @@ static int ois_block_read_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, ret = camera_io_dev_read_seq(&(o_ctrl->io_master_info), addr, data, addr_type, CAMERA_SENSOR_I2C_TYPE_BYTE, num_byte); if (ret < 0) - CAM_ERR(CAM_OIS, "err! ret:%d", ret); + AW_LOGE("err! ret:%d", ret); o_ctrl->io_master_info.cci_client->i2c_freq_mode = temp_freq; return ret; @@ -92,34 +90,32 @@ static int ois_block_read_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, static int ois_block_write_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, uint32_t addr_type, uint8_t *data, uint32_t num_byte) { - int ret = -1; + int ret = OIS_ERROR; int cnt; enum i2c_freq_mode temp_freq; struct cam_sensor_i2c_reg_setting i2c_reg_setting; if (o_ctrl == NULL || data == NULL) { - CAM_ERR(CAM_OIS, "Invalid Args o_ctrl: %pK, data: %pK", - o_ctrl, data); + AW_LOGE("Invalid Args o_ctrl: %pK, data: %pK", o_ctrl, data); return -EINVAL; } if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { - CAM_ERR(CAM_OIS, "Not in right state to start soc writes: %d", - o_ctrl->cam_ois_state); + AW_LOGE("Not in right state to start soc writes: %d", + o_ctrl->cam_ois_state); return -EINVAL; } temp_freq = o_ctrl->io_master_info.cci_client->i2c_freq_mode; - o_ctrl->io_master_info.cci_client->i2c_freq_mode = g_cci_freq; + o_ctrl->io_master_info.cci_client->i2c_freq_mode = I2C_FAST_PLUS_MODE; i2c_reg_setting.addr_type = addr_type; i2c_reg_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; i2c_reg_setting.size = num_byte; i2c_reg_setting.delay = 0; - i2c_reg_setting.reg_setting = - (struct cam_sensor_i2c_reg_array *) - kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * num_byte, - GFP_KERNEL); + i2c_reg_setting.reg_setting = (struct cam_sensor_i2c_reg_array *) + kzalloc(sizeof(struct cam_sensor_i2c_reg_array) * + num_byte, GFP_KERNEL); if (i2c_reg_setting.reg_setting == NULL) { - CAM_ERR(CAM_OIS, "kzalloc failed"); + AW_LOGE("kzalloc failed"); return OIS_ERROR; } i2c_reg_setting.reg_setting[0].reg_addr = addr; @@ -135,25 +131,25 @@ static int ois_block_write_addr8_data8(struct cam_ois_ctrl_t *o_ctrl, ret = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), &i2c_reg_setting, 0); if (ret < 0) - CAM_ERR(CAM_OIS, "err! ret:%d", ret); + AW_LOGE("err! ret:%d", ret); o_ctrl->io_master_info.cci_client->i2c_freq_mode = temp_freq; kfree(i2c_reg_setting.reg_setting); - return ret; } -static int aw_reset(struct cam_ois_ctrl_t *o_ctrl) +static int aw86006_reset(struct cam_ois_ctrl_t *o_ctrl) { int ret = OIS_ERROR; - uint16_t temp_addr = 0; + uint16_t temp_addr; uint8_t boot_cmd_1[] = { 0xFF, 0xF0, 0x20, 0x20, 0x02, 0x02, 0x19, 0x29, 0x19, 0x29 }; uint8_t boot_cmd_2[] = { 0xFF, 0xC4, 0xC4 }; uint8_t boot_cmd_3[] = { 0xFF, 0xC4, 0x00 }; uint8_t boot_cmd_4[] = { 0xFF, 0x10, 0xC3 }; - CAM_INFO(CAM_OIS, "enter"); + AW_LOGI("enter"); + /* first: shutdown */ temp_addr = o_ctrl->io_master_info.cci_client->sid; o_ctrl->io_master_info.cci_client->sid = AW_SHUTDOWN_I2C_ADDR; @@ -161,14 +157,14 @@ static int aw_reset(struct cam_ois_ctrl_t *o_ctrl) CAMERA_SENSOR_I2C_TYPE_BYTE, &boot_cmd_1[1], sizeof(boot_cmd_1) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "boot_cmd_1 write error!"); + AW_LOGE("boot_cmd_1 write error!"); goto err_exit; } ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_2[0], CAMERA_SENSOR_I2C_TYPE_BYTE, &boot_cmd_2[1], sizeof(boot_cmd_2) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "boot_cmd_2 write error!"); + AW_LOGE("boot_cmd_2 write error!"); goto err_exit; } usleep_range(AW_SHUTDOWN_DELAY, AW_SHUTDOWN_DELAY + 50); /* 2 ms */ @@ -178,66 +174,73 @@ static int aw_reset(struct cam_ois_ctrl_t *o_ctrl) CAMERA_SENSOR_I2C_TYPE_BYTE, &boot_cmd_3[1], sizeof(boot_cmd_3) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "boot_cmd_3 write error!"); + AW_LOGE("boot_cmd_3 write error!"); goto err_exit; } ret = ois_block_write_addr8_data8(o_ctrl, boot_cmd_4[0], CAMERA_SENSOR_I2C_TYPE_BYTE, &boot_cmd_4[1], sizeof(boot_cmd_4) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "boot_cmd_4 write error!"); + AW_LOGE("boot_cmd_4 write error!"); goto err_exit; } o_ctrl->io_master_info.cci_client->sid = temp_addr; + + AW_LOGD("end"); + return OIS_SUCCESS; + err_exit: o_ctrl->io_master_info.cci_client->sid = temp_addr; return OIS_ERROR; } -static int aw_runtime_check(struct cam_ois_ctrl_t *o_ctrl) +static int aw86006_runtime_check(struct cam_ois_ctrl_t *o_ctrl) { int ret = OIS_ERROR; uint32_t version = 0; uint8_t reg_val[4] = { 0 }; uint8_t chip_id = 0; + AW_LOGI("enter"); + ret = ois_block_read_addr8_data8(o_ctrl, REG_CHIPID, CAMERA_SENSOR_I2C_TYPE_WORD, &chip_id, 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "read chipid error!"); + AW_LOGE("read chipid error!"); return ret; } ret = ois_block_read_addr8_data8(o_ctrl, REG_VERSION, CAMERA_SENSOR_I2C_TYPE_WORD, ®_val[0], 4); if (ret < 0) { - CAM_ERR(CAM_OIS, "read version error!"); + AW_LOGE("read version error!"); return ret; } version = (reg_val[3] << AW_DATA_SHIFT_24_BIT) | (reg_val[2] << AW_DATA_SHIFT_16_BIT) | (reg_val[1] << AW_DATA_SHIFT_8_BIT) | (reg_val[0] << AW_DATA_SHIFT_0_BIT); - CAM_INFO(CAM_OIS, "Chip_ID: 0x%02X, Version: v%d.%d.%d.%d", chip_id, - reg_val[3], reg_val[2], reg_val[1], reg_val[0]); - if ((chip_id != g_aw86006_info.fw.app_id) - || (version != g_aw86006_info.fw.app_version)) { - CAM_ERR(CAM_OIS, "Chip_ID or Version not match!"); + AW_LOGI("Chip_ID: 0x%02X, Version: v%d.%d.%d.%d", chip_id, reg_val[3], + reg_val[2], reg_val[1], reg_val[0]); + + if ((chip_id != g_aw86006_info.fw.app_id) || + (version != g_aw86006_info.fw.app_version)) { + AW_LOGE("Chip_ID or Version not match!"); return OIS_ERROR; } - CAM_INFO(CAM_OIS, "pass!"); + AW_LOGI("pass!"); return OIS_SUCCESS; } -static int aw_soc_buf_build(struct cam_ois_ctrl_t *o_ctrl, uint8_t *buf, - struct soc_protocol *soc_struct) +static int aw86006_soc_buf_build(struct cam_ois_ctrl_t *o_ctrl, uint8_t *buf, + struct soc_protocol *soc_struct) { int i = 0; - uint8_t *p_head = (uint8_t *)soc_struct; + uint8_t *p_head = (uint8_t *) soc_struct; uint8_t checksum = 0; uint8_t data_sum = 0; @@ -264,7 +267,7 @@ static int aw_soc_buf_build(struct cam_ois_ctrl_t *o_ctrl, uint8_t *buf, return OIS_SUCCESS; } -static int aw_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) +static int aw86006_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) { struct soc_protocol soc_struct = { 0 }; int ret = OIS_ERROR; @@ -280,12 +283,12 @@ static int aw_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) soc_struct.ack_juge = SOC_CTL; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], SOC_CONNECT_WRITE_LEN - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "write connect w_buf error!"); + AW_LOGE("write connect w_buf error!"); return ret; } @@ -295,7 +298,7 @@ static int aw_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 14); if (ret < 0) { - CAM_ERR(CAM_OIS, "read connect r_buf error!"); + AW_LOGE("read connect r_buf error!"); return ret; } /* regroup w_buf */ @@ -305,18 +308,19 @@ static int aw_soc_connect_check(struct cam_ois_ctrl_t *o_ctrl) soc_struct.p_data = cmp_buf; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); + ret = memcmp(w_buf, r_buf, sizeof(r_buf)); if (ret != 0) { - CAM_ERR(CAM_OIS, "connect memcmp error!"); + AW_LOGE("connect memcmp error!"); return OIS_ERROR; } return OIS_SUCCESS; } -static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, - uint32_t addr, uint8_t *bin_buf, uint32_t len) +static int aw86006_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint8_t *bin_buf, uint32_t len) { struct soc_protocol soc_struct = { 0 }; int i = 0; @@ -337,13 +341,15 @@ static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, soc_struct.event = SOC_FLASH_READ; soc_struct.len[0] = SOC_READ_STRUCT_LEN; soc_struct.p_data = temp_buf; + soc_struct.ack_juge = SOC_CTL; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], - CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], sizeof(w_buf) - 1); + CAMERA_SENSOR_I2C_TYPE_BYTE, + &w_buf[1], sizeof(w_buf) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + AW_LOGE("i2c write w_buf error, loop: %d", loop); continue; } usleep_range(SOC_READ_BLOCK_DELAY, SOC_READ_BLOCK_DELAY + 50); @@ -352,13 +358,12 @@ static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 14 + len); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + AW_LOGE("i2c read r_buf error, loop: %d", loop); continue; } /* check error flag */ if (r_buf[9] != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "error flag wrong: %d, loop: %d", - r_buf[10], loop); + AW_LOGE("flag error: %d, loop: %d", r_buf[10], loop); continue; } checksum = 0; @@ -366,8 +371,8 @@ static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, for (i = 0; i < len + 5; i++) checksum += r_buf[9 + i]; if (checksum != r_buf[8]) { - CAM_ERR(CAM_OIS, "data checksum error:0x%02x != 0x%02x, loop:%d", - checksum, r_buf[8], loop); + AW_LOGE("data checksum error: 0x%02x != 0x%02x", + checksum, r_buf[8]); continue; } checksum = 0; @@ -375,8 +380,8 @@ static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, for (i = 1; i < 9; i++) checksum += r_buf[i]; if (checksum != r_buf[0]) { - CAM_ERR(CAM_OIS, "head checksum error:0x%02x != 0x%02x, loop:%d", - checksum, r_buf[0], loop); + AW_LOGE("head checksum error: 0x%02x != 0x%02x", + checksum, r_buf[0]); continue; } memcpy(bin_buf, (uint8_t *)&r_buf[14], len); @@ -388,8 +393,9 @@ static int aw_soc_flash_read_check(struct cam_ois_ctrl_t *o_ctrl, return OIS_SUCCESS; } -static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, - uint32_t addr, uint32_t block_num, uint8_t *bin_buf, uint32_t len) +static int aw86006_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint32_t block_num, + uint8_t *bin_buf, uint32_t len) { struct soc_protocol soc_struct = { 0 }; int i = 0; @@ -415,11 +421,11 @@ static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, #ifdef AW_FLASH_WRITE_CONNECT do { - ret = aw_soc_connect_check(o_ctrl); + ret = aw86006_soc_connect_check(o_ctrl); if (ret == OIS_SUCCESS) break; - CAM_ERR(CAM_OIS, "connect_loop error ret: %d, connect_loop: %d", - ret, connect_loop); + AW_LOGE("connect_loop error ret: %d, connect_loop: %d", ret, + connect_loop); } while ((++connect_loop) < AW_ERROR_LOOP); if (connect_loop >= AW_ERROR_LOOP) return OIS_ERROR; @@ -432,12 +438,12 @@ static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, soc_struct.ack_juge = SOC_CTL; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], SOC_WRITE_BLOCK_HEAD - 1 + len); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + AW_LOGE("i2c write w_buf error, loop: %d", loop); continue; } usleep_range(SOC_WRITE_BLOCK_DELAY, SOC_WRITE_BLOCK_DELAY + 50); @@ -446,7 +452,7 @@ static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 10); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + AW_LOGE("i2c read r_buf error, loop: %d", loop); continue; } /* regroup w_buf */ @@ -456,11 +462,12 @@ static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, soc_struct.ack_juge = SOC_ACK; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = memcmp(w_buf, r_buf, sizeof(r_buf)); if (ret == 0) break; - CAM_ERR(CAM_OIS, "memcmp error! ret=%d, loop: %d",ret , loop); + + AW_LOGE("memcmp error!, loop: %d", loop); } while ((++loop) < AW_FLASH_WRITE_ERROR_LOOP); if (loop >= AW_FLASH_WRITE_ERROR_LOOP) return OIS_ERROR; @@ -468,7 +475,7 @@ static int aw_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, return OIS_SUCCESS; } -static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, +static int aw86006_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, uint32_t len) { struct soc_protocol soc_struct = { 0 }; @@ -483,6 +490,7 @@ static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, erase_block = len / AW_FLASH_ERASE_LEN + ((len % AW_FLASH_ERASE_LEN) ? 1 : 0); + temp_buf[0] = (uint8_t) erase_block; temp_buf[1] = 0x00; for (i = 0; i < 4; i++) @@ -497,12 +505,12 @@ static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, soc_struct.ack_juge = SOC_CTL; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = ois_block_write_addr8_data8(o_ctrl, w_buf[0], CAMERA_SENSOR_I2C_TYPE_BYTE, &w_buf[1], SOC_ERASE_WRITE_LEN - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c write w_buf error, loop: %d", loop); + AW_LOGE("i2c write w_buf error, loop: %d", loop); continue; } msleep(erase_block * SOC_ERASE_BLOCK_DELAY); @@ -511,7 +519,7 @@ static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, ret = ois_block_read_addr8_data8(o_ctrl, AW_I2C_WRITE_BYTE_ZERO, CAMERA_SENSOR_I2C_TYPE_BYTE, &r_buf[0], 10); if (ret < 0) { - CAM_ERR(CAM_OIS, "i2c read r_buf error, loop: %d", loop); + AW_LOGE("i2c read r_buf error, loop: %d", loop); continue; } soc_struct.event = SOC_FLASH_ERASE_BLOCK_ACK; @@ -520,21 +528,22 @@ static int aw_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, soc_struct.p_data = cmp_buf; memset(w_buf, 0, sizeof(w_buf)); - aw_soc_buf_build(o_ctrl, w_buf, &soc_struct); + aw86006_soc_buf_build(o_ctrl, w_buf, &soc_struct); ret = memcmp(w_buf, r_buf, sizeof(r_buf)); if (ret == 0) break; - CAM_ERR(CAM_OIS, "memcmp error!, loop: %d", loop); + + AW_LOGE("memcmp error!, loop: %d", loop); } while ((++loop) < AW_FLASH_ERASE_ERROR_LOOP); if (loop >= AW_FLASH_ERASE_ERROR_LOOP) return OIS_ERROR; - CAM_INFO(CAM_OIS, "flash erase success!, addr: 0x%08x, len: 0x%08x", - addr, len); + AW_LOGI("flash erase success!, addr: 0x%08x, len: 0x%08x", addr, len); + return OIS_SUCCESS; } -static int aw_soc_flash_download_check(struct cam_ois_ctrl_t *o_ctrl, +static int aw86006_soc_flash_download_check(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, uint8_t *bin_buf, size_t len) { uint32_t flash_block = 0; @@ -549,90 +558,91 @@ static int aw_soc_flash_download_check(struct cam_ois_ctrl_t *o_ctrl, if (addr == AW_FLASH_BASE_ADDR) { flash_checkinfo = AW_FLASH_MOVE_LENGTH / AW_FLASH_WRITE_LEN; /* first erase app+info data */ - ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, + ret = aw86006_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, len - AW_FLASH_MOVE_LENGTH); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to erase app+checkinfo!"); - return ret; + AW_LOGE("Failed to erase app+checkinfo"); + return OIS_ERROR; } /* then erase move data */ - ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_BASE_ADDR, - AW_FLASH_MOVE_LENGTH); + ret = aw86006_soc_flash_erase_check(o_ctrl, AW_FLASH_BASE_ADDR, + AW_FLASH_MOVE_LENGTH); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to erase move!"); - return ret; + AW_LOGE("Failed to erase move"); + return OIS_ERROR; } /* write move data */ for (i = 0; i < flash_checkinfo; i++) { - ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, - AW_FLASH_WRITE_LEN); + ret = aw86006_soc_flash_write_check(o_ctrl, addr, i, + bin_buf, AW_FLASH_WRITE_LEN); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); - return ret; + AW_LOGE("Failed to write flash block: %d", i); + return OIS_ERROR; } } /* write app block data */ for (i = flash_checkinfo + 1; i < flash_block; i++) { - ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, - AW_FLASH_WRITE_LEN); + ret = aw86006_soc_flash_write_check(o_ctrl, addr, i, + bin_buf, AW_FLASH_WRITE_LEN); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); - return ret; + AW_LOGE("Failed to write flash block: %d", i); + return OIS_ERROR; } } /* write app tail data */ if ((flash_tail != 0) && (len > AW_FLASH_MOVE_LENGTH)) { - ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, - flash_tail); + ret = aw86006_soc_flash_write_check(o_ctrl, addr, i, + bin_buf, flash_tail); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write flash app tail"); - return ret; + AW_LOGE("Failed to write flash app tail"); + return OIS_ERROR; } } } else if (addr == AW_FLASH_APP_ADDR) { flash_checkinfo = 0; /* erase app+info data */ - ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, len); + ret = aw86006_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, + len); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to erase app+checkinfo!"); - return ret; + AW_LOGE("Failed to erase app+checkinfo!"); + return OIS_ERROR; } /* write app block data */ for (i = 1; i < flash_block; i++) { - ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, - AW_FLASH_WRITE_LEN); + ret = aw86006_soc_flash_write_check(o_ctrl, addr, i, + bin_buf, AW_FLASH_WRITE_LEN); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write flash block: %d", i); - return ret; + AW_LOGE("Failed to write flash block: %d", i); + return OIS_ERROR; } } /* write app tail data */ if (flash_tail != 0) { - ret = aw_soc_flash_write_check(o_ctrl, addr, i, bin_buf, - flash_tail); + ret = aw86006_soc_flash_write_check(o_ctrl, addr, i, + bin_buf, flash_tail); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write flash tail"); - return ret; + AW_LOGE("Failed to write flash tail"); + return OIS_ERROR; } } } else { - CAM_ERR(CAM_OIS, "wrong addr!"); + AW_LOGE("wrong addr!"); return OIS_ERROR; } /* Write checkinfo data */ - ret = aw_soc_flash_write_check(o_ctrl, AW_FLASH_APP_ADDR, 0, + ret = aw86006_soc_flash_write_check(o_ctrl, AW_FLASH_APP_ADDR, 0, g_aw86006_info.checkinfo_fw, AW_FLASH_WRITE_LEN); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "Failed to write checkinfo!"); - return ret; + AW_LOGE("Failed to write checkinfo!"); + return OIS_ERROR; } return OIS_SUCCESS; } -static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) +static int aw86006_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) { ktime_t kstart; ktime_t kend; @@ -648,10 +658,10 @@ static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) uint8_t version_ack[5] = {0x00}; do { - ret = aw_reset(o_ctrl); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_reset error, ret: %d, loop: %d", - ret, jump_loop); + AW_LOGE("aw86006_reset error, ret: %d, loop: %d", ret, + jump_loop); continue; } /* delay: 9ms */ @@ -664,7 +674,7 @@ static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) break; } if (ms_count_reset >= AW_JUMP_MOVE_DELAY_MAX) { - CAM_ERR(CAM_OIS, "ms_count_reset timeout: %d, loop: %d", + AW_LOGE("ms_count_reset timeout: %d, loop: %d", ms_count_reset, jump_loop); continue; } @@ -682,11 +692,11 @@ static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) kend = ktime_get(); ms_count_stop = ktime_to_ms(ktime_sub(kend, kstart)); - CAM_INFO(CAM_OIS, "ms_count_reset: %u, ms_count_stop: %u", - ms_count_reset, ms_count_stop); + AW_LOGD("ms_count_reset: %u, ms_count_stop: %u", ms_count_reset, + ms_count_stop); if (ms_first_f0 > AW_JUMP_MOVE_DELAY_MAX) { - CAM_INFO(CAM_OIS, "first 0xF0: %d ms", ms_first_f0); + AW_LOGI("first 0xF0: %d ms", ms_first_f0); continue; } @@ -695,7 +705,7 @@ static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) CAMERA_SENSOR_I2C_TYPE_BYTE, &version_cmd[1], sizeof(version_cmd) - 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "write version_cmd, loop: %d", jump_loop); + AW_LOGE("write version_cmd failed! loop:%d", jump_loop); continue; } usleep_range(ISP_READ_VERSION_DELAY, @@ -704,36 +714,35 @@ static int aw_jump_move_check(struct cam_ois_ctrl_t *o_ctrl) CAMERA_SENSOR_I2C_TYPE_BYTE, &version_ack[0], ISP_VERSION_ACK_LEN); if (ret < 0) { - CAM_ERR(CAM_OIS, "read version error, loop:%d", jump_loop); + AW_LOGE("read version error, loop: %d", jump_loop); continue; } if (version_ack[0] != ISP_EVENT_OK) { - CAM_ERR(CAM_OIS, "wrong version_ack: %d, loop: %d", + AW_LOGE("wrong version_ack: %d, loop: %d", version_ack[0], jump_loop); continue; } move_version = (version_ack[4] << AW_DATA_SHIFT_24_BIT) | - (version_ack[3] << AW_DATA_SHIFT_16_BIT) | - (version_ack[2] << AW_DATA_SHIFT_8_BIT) | - (version_ack[1] << AW_DATA_SHIFT_0_BIT); + (version_ack[3] << AW_DATA_SHIFT_16_BIT) | + (version_ack[2] << AW_DATA_SHIFT_8_BIT) | + (version_ack[1] << AW_DATA_SHIFT_0_BIT); if (move_version == g_aw86006_info.fw.move_version) break; - CAM_ERR(CAM_OIS, "move_version not match: 0x%08X != 0x%08X, loop:%d", + AW_LOGE("move_version not match: 0x%08X != 0x%08X, loop: %d", move_version, g_aw86006_info.fw.move_version, jump_loop); } while ((++jump_loop) < AW_JUMP_MOVE_LOOP); if (jump_loop >= AW_JUMP_MOVE_LOOP) return OIS_ERROR; - CAM_INFO(CAM_OIS, "Success! move_version: 0x%08X", move_version); - + AW_LOGI("Jump move success! move_version: 0x%08X", move_version); return OIS_SUCCESS; } -static int aw_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) +static int aw86006_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) { ktime_t kend; ktime_t kstart; @@ -746,10 +755,10 @@ static int aw_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) uint8_t boot_cmd[] = {0xAC, 0xAC, 0xAC}; do { - ret = aw_reset(o_ctrl); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_reset error, ret: %d, loop: %d", - ret, jump_loop); + AW_LOGE("aw86006_reset error, ret: %d, loop: %d", ret, + jump_loop); continue; } /* delay: 2ms */ @@ -762,8 +771,8 @@ static int aw_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) break; } if (ms_count_reset >= AW_JUMP_BOOT_DELAY_MAX) { - CAM_ERR(CAM_OIS, "ms_count_reset timeout: %d, loop: %d", - ms_count_reset, jump_loop); + AW_LOGE("ms_count_reset timeout: %d, loop: %d", + ms_count_reset, jump_loop); continue; } /* send jump boot cmd */ @@ -780,82 +789,83 @@ static int aw_jump_boot_check(struct cam_ois_ctrl_t *o_ctrl) /* get the end time of send boot cmd */ kend = ktime_get(); ms_count_stop = ktime_to_ms(ktime_sub(kend, kstart)); - CAM_INFO(CAM_OIS, "ms_count_reset: %u, ms_count_stop: %u", - ms_count_reset, ms_count_stop); + AW_LOGD("ms_count_reset: %u, ms_count_stop: %u", + ms_count_reset, ms_count_stop); if (ms_first_ac > AW_JUMP_BOOT_DELAY_MAX) { - CAM_INFO(CAM_OIS, "first 0xAC: %d ms", ms_first_ac); + AW_LOGI("first 0xAC: %d ms", ms_first_ac); continue; } - ret = aw_soc_connect_check(o_ctrl); + ret = aw86006_soc_connect_check(o_ctrl); if (ret == OIS_SUCCESS) break; - CAM_ERR(CAM_OIS, "soc connect failed! loop:%d", jump_loop); + AW_LOGE("soc connect failed, ret:%d, loop: %d", ret, jump_loop); } while ((++jump_loop) < AW_JUMP_BOOT_LOOP); if (jump_loop >= AW_JUMP_BOOT_LOOP) return OIS_ERROR; - CAM_INFO(CAM_OIS, "success"); + AW_LOGI("success"); return OIS_SUCCESS; } -static int aw_soc_flash_update(struct cam_ois_ctrl_t *o_ctrl, uint32_t addr, - uint8_t *data_p, size_t fw_size) +static int aw86006_soc_flash_update(struct cam_ois_ctrl_t *o_ctrl, + uint32_t addr, uint8_t *data_p, size_t fw_size) { int ret = OIS_ERROR; int loop = 0; if (!data_p) { - CAM_ERR(CAM_OIS, "data_p is NULL"); + AW_LOGE("data_p is NULL"); return OIS_ERROR; } /* enter boot mode */ - ret = aw_jump_boot_check(o_ctrl); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "jump boot failed!"); + AW_LOGE("jump boot failed!"); return OIS_ERROR; } /* update flash */ do { - ret = aw_soc_flash_download_check(o_ctrl, addr, data_p, fw_size); + ret = aw86006_soc_flash_download_check(o_ctrl, addr, data_p, + fw_size); if (ret == OIS_SUCCESS) break; - CAM_ERR(CAM_OIS, "aw_soc_flash_download_check failed! loop:%d", loop); + AW_LOGE("soc_flash_download_check failed! loop: %d", loop); } while ((++loop) < AW_ERROR_LOOP); if (loop >= AW_ERROR_LOOP) return OIS_ERROR; - ret = aw_reset(o_ctrl); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_reset failed!"); - return ret; + AW_LOGE("aw86006_reset failed!"); + return OIS_ERROR; } msleep(AW_RESET_DELAY); - CAM_INFO(CAM_OIS, "success!"); + AW_LOGI("success!"); return OIS_SUCCESS; } -static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, - const struct firmware *fw) +static int aw86006_firmware_check(struct cam_ois_ctrl_t *o_ctrl, + const struct firmware *fw) { uint32_t temp = 0; uint32_t *check_ptr = NULL; int i = 0; - int ret = 0; + int ret = OIS_ERROR; char *identify = (char *)fw->data + AW_FW_SHIFT_IDENTIFY; if (fw == NULL) { - CAM_ERR(CAM_OIS, "FW Empty!!!"); + AW_LOGE("FW Empty!!!"); return OIS_ERROR; } ret = memcmp(fw_check_str, identify, 8); /* AWINIC00 8bytes */ if (ret != 0) { - CAM_ERR(CAM_OIS, "loaded wrong firmware!"); + AW_LOGE("loaded wrong firmware!"); return OIS_ERROR; } @@ -880,16 +890,20 @@ static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, g_aw86006_info.fw.move_length = *(uint32_t *) (&fw->data[AW_FW_SHIFT_MOVE_LENGTH]); - CAM_INFO(CAM_OIS, "fw->size:0x%04X, app_length:0x%04X, app_version:0x%08X, app_id:0x%02X, move_version:0x%08X, move_length:0x%04X", - g_aw86006_info.fw.size, g_aw86006_info.fw.app_length, - g_aw86006_info.fw.app_version, g_aw86006_info.fw.app_id, - g_aw86006_info.fw.move_version, g_aw86006_info.fw.move_length); + AW_LOGI("fw->size:0x%04X, app_length:0x%04X, app_version:0x%08X", + g_aw86006_info.fw.size, + g_aw86006_info.fw.app_length, + g_aw86006_info.fw.app_version); + AW_LOGI("app_id:0x%02X, move_version:0x%08X, move_length:0x%04X", + g_aw86006_info.fw.app_id, + g_aw86006_info.fw.move_version, + g_aw86006_info.fw.move_length); /* length check */ temp = g_aw86006_info.fw.move_length + g_aw86006_info.fw.app_length; if (g_aw86006_info.fw.size != temp) { - CAM_ERR(CAM_OIS, "fw->size error: 0x%X != 0x%X", - g_aw86006_info.fw.size, temp); + AW_LOGE("fw->size error: 0x%X != 0x%X", g_aw86006_info.fw.size, + temp); return OIS_ERROR; } @@ -899,7 +913,7 @@ static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, for (i = 0; i < (g_aw86006_info.fw.move_length / sizeof(uint32_t)); i++) temp += check_ptr[i]; if (temp != g_aw86006_info.fw.move_checksum) { - CAM_ERR(CAM_OIS, "move checksum error:0x%08X != 0x%08X", + AW_LOGE("move checksum error:0x%08X != 0x%08X", g_aw86006_info.fw.move_checksum, temp); return OIS_ERROR; } @@ -911,8 +925,8 @@ static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, for (i = 0; i < ((AW_FW_INFO_LENGTH - 8 - 4) / sizeof(uint32_t)); i++) temp += check_ptr[i]; if (temp != g_aw86006_info.fw.checksum) { - CAM_ERR(CAM_OIS, "check_info checksum error:0x%08X != 0x%08X", - g_aw86006_info.fw.checksum, temp); + AW_LOGE("check_info checksum error:0x%08X != 0x%08X", + g_aw86006_info.fw.checksum, temp); return OIS_ERROR; } @@ -925,63 +939,66 @@ static int aw_firmware_check(struct cam_ois_ctrl_t *o_ctrl, temp += check_ptr[i]; if (temp != g_aw86006_info.fw.app_checksum) { - CAM_ERR(CAM_OIS, "app checksum error:0x%08X != 0x%08X", - g_aw86006_info.fw.app_checksum, temp); + AW_LOGE("app checksum error:0x%08X != 0x%08X", + g_aw86006_info.fw.app_checksum, temp); return OIS_ERROR; } /* Save firmware checkinfo */ memcpy(&g_aw86006_info.checkinfo_fw[0], fw->data + AW_FLASH_MOVE_LENGTH, AW_FW_INFO_LENGTH); - CAM_INFO(CAM_OIS, "pass!"); + AW_LOGI("Pass!"); return OIS_SUCCESS; } -static int aw_checkinfo_analyse(struct cam_ois_ctrl_t *o_ctrl, +static int aw86006_checkinfo_analyse(struct cam_ois_ctrl_t *o_ctrl, uint8_t *checkinfo_rd, struct aw86006_fw *info) { uint32_t temp = 0; uint32_t *check_ptr = NULL; int i = 0; - int ret = 0; + int ret = OIS_ERROR; if ((checkinfo_rd == NULL) || (info == NULL)) { - CAM_ERR(CAM_OIS, "checkinfo empty!"); + AW_LOGE("checkinfo empty!"); return OIS_ERROR; } /* compare identify: AWINIC00 */ ret = memcmp(fw_check_str, (char *)checkinfo_rd, 8); if (ret != 0) { - CAM_ERR(CAM_OIS, "checkinfo not match!"); + AW_LOGE("checkinfo not match!"); return OIS_ERROR; } info->checksum = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_CHECKSUM - AW_FLASH_MOVE_LENGTH]); info->app_checksum = - *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_CHECKSUM - + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_CHECKSUM - AW_FLASH_MOVE_LENGTH]); info->app_length = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_LENGTH - AW_FLASH_MOVE_LENGTH]) + AW_FW_INFO_LENGTH; info->app_version = - *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_VERSION - + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_VERSION - AW_FLASH_MOVE_LENGTH]); info->app_id = *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_APP_ID - AW_FLASH_MOVE_LENGTH]); info->move_checksum = - *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_CHECKSUM - + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_CHECKSUM - AW_FLASH_MOVE_LENGTH]); info->move_version = - *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_VERSION - + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_VERSION - AW_FLASH_MOVE_LENGTH]); info->move_length = - *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_LENGTH - + *(uint32_t *) (&checkinfo_rd[AW_FW_SHIFT_MOVE_LENGTH - AW_FLASH_MOVE_LENGTH]); - CAM_INFO(CAM_OIS, "checkinfo app_length:0x%04X, app_version:0x%08X, app_id:0x%02X, move_version:0x%08X, move_length:0x%04X", - info->app_length, info->app_version, info->app_id, - info->move_version, info->move_length); + AW_LOGI("app_length: 0x%04X, app_version: 0x%08X, app_id: 0x%02X", + info->app_length, + info->app_version, + info->app_id); + AW_LOGI("move_version:0x%08X, move_length:0x%04X", info->move_version, + info->move_length); /* info checksum check */ check_ptr = (uint32_t *) &checkinfo_rd[AW_FW_SHIFT_CHECKSUM_ADDR - @@ -990,38 +1007,42 @@ static int aw_checkinfo_analyse(struct cam_ois_ctrl_t *o_ctrl, for (i = 0; i < ((AW_FW_INFO_LENGTH - 8 - 4) / sizeof(uint32_t)); i++) temp += check_ptr[i]; if (temp != info->checksum) { - CAM_ERR(CAM_OIS, "checkinfo_rd checksum error:0x%08X != 0x%08X", + AW_LOGE("checkinfo_rd checksum error:0x%08X != 0x%08X", info->checksum, temp); return OIS_ERROR; } - CAM_INFO(CAM_OIS, "pass!"); + AW_LOGI("pass!"); return OIS_SUCCESS; } -static int aw_get_standby_flag(struct cam_ois_ctrl_t *o_ctrl, uint8_t *pflag) +static int aw86006_get_standby_flag(struct cam_ois_ctrl_t *o_ctrl, + uint8_t *pflag) { - int ret = 0; + int ret = OIS_ERROR; uint8_t flag = 0; uint8_t temp_addr = 0; + AW_LOGI("enter"); + temp_addr = o_ctrl->io_master_info.cci_client->sid; o_ctrl->io_master_info.cci_client->sid = AW_SHUTDOWN_I2C_ADDR; ret = ois_block_read_addr8_data8(o_ctrl, 0xFF11, CAMERA_SENSOR_I2C_TYPE_WORD, &flag, 1); o_ctrl->io_master_info.cci_client->sid = temp_addr; if (ret < 0) { - CAM_ERR(CAM_OIS, "read standby flag error, ret: %d", ret); + AW_LOGE("read standby flag error, ret: %d", ret); return ret; } *pflag = flag; - CAM_INFO(CAM_OIS, "standby flag: %d", flag); + + AW_LOGI("standby flag: %d", flag); return OIS_SUCCESS; } static int aw86006_mem_download(struct cam_ois_ctrl_t *o_ctrl, - const struct firmware *fw) + const struct firmware *fw) { struct aw86006_fw info_rd; size_t all_buf_size = g_aw86006_info.fw.app_length + @@ -1032,91 +1053,93 @@ static int aw86006_mem_download(struct cam_ois_ctrl_t *o_ctrl, uint8_t *all_buf_ptr = (uint8_t *) fw->data; uint8_t *app_buf_ptr = (uint8_t *) fw->data + AW_FLASH_MOVE_LENGTH; + AW_LOGI("enter"); + if (fw == NULL) { - CAM_ERR(CAM_OIS, "FW Empty!!!"); + AW_LOGE("error, FW Empty!!!"); return OIS_ERROR; } /* enter boot mode */ - ret = aw_jump_boot_check(o_ctrl); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "jump boot failed!"); + AW_LOGE("jump boot failed!"); return OIS_ERROR; } + #ifdef AW_SOC_FLASH_READ_FLAG /* get check_info data */ - ret = aw_soc_flash_read_check(o_ctrl, AW_FLASH_APP_ADDR, - &g_aw86006_info.checkinfo_rd[0], AW_FLASH_READ_LEN); + ret = aw86006_soc_flash_read_check(o_ctrl, AW_FLASH_APP_ADDR, + &g_aw86006_info.checkinfo_rd[0], AW_FLASH_READ_LEN); if (ret != OIS_SUCCESS) - CAM_ERR(CAM_OIS, "checkinfo read error!"); + AW_LOGE("read checkinfo error!"); #endif + g_aw86006_info.fw.update_flag = - g_aw86006_info.checkinfo_rd[AW_ARRAY_SHIFT_UPDATE_FLAG]; + g_aw86006_info.checkinfo_rd[AW_ARRAY_SHIFT_UPDATE_FLAG]; if (g_aw86006_info.fw.update_flag != 0x01) { - CAM_INFO(CAM_OIS, "update_flag not match, update all!"); - ret = aw_soc_flash_update(o_ctrl, AW_FLASH_BASE_ADDR, - all_buf_ptr, all_buf_size); + AW_LOGI("update_flag not match, update all!"); + ret = aw86006_soc_flash_update(o_ctrl, AW_FLASH_BASE_ADDR, + all_buf_ptr, all_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update all failed!"); + AW_LOGE("update all failed!"); return OIS_ERROR; } } else { - CAM_INFO(CAM_OIS, "update_flag match!"); + AW_LOGI("update_flag match!"); ret = memcmp(g_aw86006_info.checkinfo_rd, - g_aw86006_info.checkinfo_fw, AW_FW_INFO_LENGTH); + g_aw86006_info.checkinfo_fw, AW_FW_INFO_LENGTH); if (ret != 0) { - ret = aw_checkinfo_analyse(o_ctrl, + ret = aw86006_checkinfo_analyse(o_ctrl, g_aw86006_info.checkinfo_rd, &info_rd); if ((ret != OIS_SUCCESS) || (info_rd.move_version != g_aw86006_info.fw.move_version)) { - CAM_ERR(CAM_OIS, - "checkinfo or move not match, update all!"); - ret = aw_soc_flash_update(o_ctrl, - AW_FLASH_BASE_ADDR, - all_buf_ptr, all_buf_size); + AW_LOGE("checkinfo/move not match, update all"); + ret = aw86006_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, all_buf_ptr, + all_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update all failed!"); + AW_LOGE("update all failed!"); return OIS_ERROR; } } else if ((info_rd.app_version != g_aw86006_info.fw.app_version) || (info_rd.app_id != g_aw86006_info.fw.app_id)) { - CAM_ERR(CAM_OIS, "app not match, update app!"); - ret = aw_soc_flash_update(o_ctrl, - AW_FLASH_APP_ADDR, - app_buf_ptr, app_buf_size); + AW_LOGE("app not match, update app!"); + ret = aw86006_soc_flash_update(o_ctrl, + AW_FLASH_APP_ADDR, app_buf_ptr, + app_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update app failed!"); + AW_LOGE("update app failed!"); return OIS_ERROR; } } else { - CAM_ERR(CAM_OIS, "other error, update all!"); - ret = aw_soc_flash_update(o_ctrl, - AW_FLASH_BASE_ADDR, - all_buf_ptr, all_buf_size); + AW_LOGE("other error, update all!"); + ret = aw86006_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, all_buf_ptr, + all_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update all failed!"); + AW_LOGE("update all failed!"); return OIS_ERROR; } } } else { - ret = aw_jump_move_check(o_ctrl); + ret = aw86006_jump_move_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, - "aw_jump_move_check fail, update all!"); - ret = aw_soc_flash_update(o_ctrl, - AW_FLASH_BASE_ADDR, all_buf_ptr, - all_buf_size); + AW_LOGE("jump_move_check fail, update all!"); + ret = aw86006_soc_flash_update(o_ctrl, + AW_FLASH_BASE_ADDR, all_buf_ptr, + all_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update all failed!"); + AW_LOGE("update all failed!"); return OIS_ERROR; } } else { - ret = aw_reset(o_ctrl); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_reset failed!"); + AW_LOGE("reset failed!"); return OIS_ERROR; } msleep(AW_RESET_DELAY); @@ -1125,21 +1148,19 @@ static int aw86006_mem_download(struct cam_ois_ctrl_t *o_ctrl, } for (i = 0; i <= AW_ERROR_LOOP; i++) { - ret = aw_runtime_check(o_ctrl); + ret = aw86006_runtime_check(o_ctrl); if (ret == OIS_SUCCESS) { - CAM_INFO(CAM_OIS, - "runtime_check pass, no need to update fw!"); + AW_LOGI("runtime_check pass, no need to update fw!"); break; } - CAM_ERR(CAM_OIS, - "runtime_check failed, update app! loop:%d", i); + AW_LOGE("runtime_check failed, update app! loop: %d", i); if (i == AW_ERROR_LOOP) break; - ret = aw_soc_flash_update(o_ctrl, AW_FLASH_APP_ADDR, app_buf_ptr, - app_buf_size); + ret = aw86006_soc_flash_update(o_ctrl, AW_FLASH_APP_ADDR, + app_buf_ptr, app_buf_size); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "update app failed!"); + AW_LOGE("update app failed!"); break; } } @@ -1147,58 +1168,48 @@ static int aw86006_mem_download(struct cam_ois_ctrl_t *o_ctrl, return ret; } -int aw_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw) +int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, + const struct firmware *fw) { -// const struct firmware *fw; -// int loop = 0; int ret = OIS_ERROR; uint8_t standby_flag = 0; - CAM_INFO(CAM_OIS, "start!"); - /* load firmware */ - /* - do { - ret = request_firmware(&fw, AW86006_FW_NAME, &o_ctrl->pdev->dev); - if (ret == 0) - break; - } while ((++loop) < AW_ERROR_LOOP); - if (loop >= AW_ERROR_LOOP) { - CAM_ERR(CAM_OIS, "request_firmware [%s] failed!", AW86006_FW_NAME); - return OIS_ERROR; - } - */ + AW_LOGI("enter"); + /* fw check */ - CAM_INFO(CAM_OIS, "Load:%s size:%zu", AW86006_FW_NAME, fw->size); - ret = aw_firmware_check(o_ctrl, fw); + AW_LOGI("Load:%s size:%zu", AW86006_FW_NAME, fw->size); + ret = aw86006_firmware_check(o_ctrl, fw); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "fw check failed!"); + AW_LOGE("fw check failed!"); goto err_fw_check; } /* reset */ - ret = aw_reset(o_ctrl); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "reset failed"); + AW_LOGE("reset failed"); goto err_reset; } mdelay(AW_RESET_DELAY); /* run app after reset */ /* Get standby flag */ - ret = aw_get_standby_flag(o_ctrl, &standby_flag); + ret = aw86006_get_standby_flag(o_ctrl, &standby_flag); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "get standby flag failed"); + AW_LOGE("get standby flag failed"); goto err_get_standby_flg; } + if (standby_flag == AW_IC_STANDBY) { - ret = aw_runtime_check(o_ctrl); + ret = aw86006_runtime_check(o_ctrl); if (ret == OIS_SUCCESS) - CAM_INFO(CAM_OIS, "runtime_check pass, no need to update fw!"); + AW_LOGI("runtime_check pass, no need to update fw!"); } /* update flash */ if ((standby_flag != AW_IC_STANDBY) || (ret != OIS_SUCCESS)) { + /* update flash */ ret = aw86006_mem_download(o_ctrl, fw); if (ret == OIS_SUCCESS) - CAM_INFO(CAM_OIS, "fw update success!"); + AW_LOGI("fw update success!"); else - CAM_ERR(CAM_OIS, "fw update failed, ret: %d", ret); + AW_LOGE("fw update failed, ret: %d", ret); } err_get_standby_flg: @@ -1208,269 +1219,344 @@ err_fw_check: return ret; } -void aw_firmware_update_work_routine(struct work_struct *work) +static void aw86006_firmware_update_work_routine(struct work_struct *work) { - struct cam_ois_ctrl_t *o_ctrl = - container_of(work, struct cam_ois_ctrl_t, fw_update_work); - const struct firmware *fw = NULL; - int loop = 0; - int ret = 0; + struct cam_ois_ctrl_t *o_ctrl = container_of(work, + struct cam_ois_ctrl_t, aw_fw_update_work); + const struct firmware *fw = NULL; + int loop = 0; + int ret = OIS_ERROR; - CAM_INFO(CAM_OIS, "enter"); + AW_LOGI("enter"); - // load firmware - do { - ret = request_firmware(&fw, AW86006_FW_NAME, &o_ctrl->pdev->dev); - if (ret == 0) - break; - } while ((++loop) < AW_ERROR_LOOP); - if (loop >= AW_ERROR_LOOP) { - CAM_ERR(CAM_OIS, "request_firmware [%s] failed! stop update firmware!", AW86006_FW_NAME); - } - else{ - mutex_lock(&o_ctrl->ois_mutex_aw); - aw_firmware_update(o_ctrl,fw); - mutex_unlock(&o_ctrl->ois_mutex_aw); - } + /* load firmware */ + do { + ret = request_firmware(&fw, AW86006_FW_NAME, + &o_ctrl->pdev->dev); + if (ret == 0) + break; + } while ((++loop) < AW_ERROR_LOOP); + if (loop >= AW_ERROR_LOOP) { + AW_LOGE("request_firmware [%s] failed!", AW86006_FW_NAME); + return; + } + mutex_lock(&o_ctrl->aw_ois_mutex); + aw86006_firmware_update(o_ctrl, fw); + mutex_unlock(&o_ctrl->aw_ois_mutex); + + AW_LOGI("End"); } /******************************************************************************* * adb debug interface ******************************************************************************/ -static ssize_t reg_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t reg_show(struct class *class, struct class_attribute *attr, + char *buf) { - uint8_t reg_val = 0; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; ssize_t len = 0; - uint32_t i = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + int i = 0; + uint8_t reg_val[20] = { 0 }; - mutex_lock(&o_ctrl->ois_mutex_aw); + AW_LOGI("Start"); + + mutex_lock(&o_ctrl->aw_ois_mutex); for (i = 0; i < 20; i++) { ois_block_read_addr8_data8(o_ctrl, i, CAMERA_SENSOR_I2C_TYPE_WORD, - ®_val, 1); + ®_val[i], 1); len += snprintf(buf + len, PAGE_SIZE - len, - "reg:0x%04X=0x%02X\n", i, reg_val); + "reg[0x%04X]:0x%02X\n", i, reg_val[i]); + AW_LOGD("reg[0x%04X]:0x%02X", i, reg_val[i]); } - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); + + AW_LOGI("End"); + return len; } -static ssize_t reg_store(struct class *class, - struct class_attribute *attr, - const char *buf, size_t count) +static ssize_t reg_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { - uint32_t databuf[2] = {0}; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + uint32_t databuf[2] = { 0 }; + + AW_LOGI("Start"); + + mutex_lock(&o_ctrl->aw_ois_mutex); if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { - mutex_lock(&o_ctrl->ois_mutex_aw); + AW_LOGD("reg[0x%04X]:0x%02X", databuf[0], databuf[1]); ois_block_write_addr8_data8(o_ctrl, databuf[0], CAMERA_SENSOR_I2C_TYPE_WORD, (uint8_t *) &databuf[1], CAMERA_SENSOR_I2C_TYPE_BYTE); - mutex_unlock(&o_ctrl->ois_mutex_aw); + } else { + AW_LOGE("Number of parameters"); + mutex_unlock(&o_ctrl->aw_ois_mutex); + return -EPERM; } + mutex_unlock(&o_ctrl->aw_ois_mutex); + + AW_LOGI("End"); return count; } -static ssize_t awrw_show(struct class *class, - struct class_attribute *attr, char *buf) +static int aw86006_parse_reg_data(struct awrw_ctrl *awrw_ctrl, const char *buf) { + int ret = OIS_ERROR; + int i = 0; + char data_buf[5] = { 0 }; + uint8_t temp = 0; + + AW_LOGI("Start"); + + for (i = 0; i < awrw_ctrl->reg_num; i++) { + if ((i * 5 + 5) > (strlen(buf) - 2 * (4 + 1) - (6 + 1))) { + AW_LOGE("buf length error"); + return -ERANGE; + } + memcpy(data_buf, &buf[17 + i * 5], 4); + data_buf[4] = '\0'; + /* char convert to unsigned char */ + ret = kstrtou8(data_buf, 0, &temp); + if (ret < 0) { + AW_LOGE("Parse reg_data[%d] error", i); + return ret; + } + awrw_ctrl->reg_data[i] = temp; + + AW_LOGD("reg_data[%d]: 0x%02x", i, awrw_ctrl->reg_data[i]); + } + + return 0; +} + +static ssize_t awrw_show(struct class *class, struct class_attribute *attr, + char *buf) +{ + struct awrw_ctrl *awrw_ctrl = g_o_ctrl->awrw_ctrl; int i = 0; ssize_t len = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + uint16_t reg_num = awrw_ctrl->reg_num; + uint8_t flag = awrw_ctrl->flag; + uint8_t *reg_data = awrw_ctrl->reg_data; - if (o_ctrl->awrw_flag != AW_SEQ_READ) { - CAM_ERR(CAM_OIS, "not read mode"); + AW_LOGI("Start"); + + if (!reg_num) { + AW_LOGE("Reg_nums parameter error"); return -ERANGE; } - if (o_ctrl->reg_data == NULL) { - CAM_ERR(CAM_OIS, "reg_data empty!"); + + if (reg_data == NULL) { + AW_LOGE("reg_data empty!"); return -ERANGE; } - for (i = 0; i < o_ctrl->reg_num; i++) { - len += snprintf(buf + len, PAGE_SIZE - len, - "0x%02x,", o_ctrl->reg_data[i]); + + if (flag == AW_SEQ_READ) { + for (i = 0; i < reg_num; i++) { + AW_LOGD("reg_data[%d]: 0x%02x", i, reg_data[i]); + len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,", + reg_data[i]); + } + len += snprintf(buf + len - 1, PAGE_SIZE - len, "\n"); + } else { + AW_LOGE("Need to read awrw before show"); + return -EPERM; } - len += snprintf(buf + len - 1, PAGE_SIZE - len, "\n"); + + AW_LOGI("End"); + return len; } static ssize_t awrw_store(struct class *class, struct class_attribute *attr, - const char *buf, size_t count) + const char *buf, size_t count) { - uint8_t value = 0; - char data_buf[5] = {0}; - int i = 0; - int rc = 0; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + struct awrw_ctrl *awrw_ctrl = g_o_ctrl->awrw_ctrl; + int ret = OIS_ERROR; uint32_t flag = 0; uint32_t reg_num = 0; uint32_t reg_addr = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + + AW_LOGI("Start"); if (sscanf(buf, "%x %x %x", &flag, ®_num, ®_addr) == 3) { if (!reg_num) { - CAM_ERR(CAM_OIS, "reg_num param error"); + AW_LOGE("awrw parameter error"); return -ERANGE; } - mutex_lock(&o_ctrl->ois_mutex_aw); - o_ctrl->awrw_flag = flag; - o_ctrl->reg_num = reg_num; - if (o_ctrl->reg_data != NULL) - kfree(o_ctrl->reg_data); - o_ctrl->reg_data = kmalloc(reg_num, GFP_KERNEL); - if (flag == AW_SEQ_WRITE) { - for (i = 0; i < reg_num; i++) { - if ((i * 5 + 5) > (strlen(buf) - 2 * (4 + 1) - (6 + 1))) { - CAM_ERR(CAM_OIS, "buf length error"); - mutex_unlock(&o_ctrl->ois_mutex_aw); - return -ERANGE; - } - memcpy(data_buf, &buf[17 + i * 5], 4); - data_buf[4] = '\0'; - rc = kstrtou8(data_buf, 0, &value); - if (rc < 0) { - CAM_ERR(CAM_OIS, "input buf error"); - mutex_unlock(&o_ctrl->ois_mutex_aw); - return -ERANGE; - } - o_ctrl->reg_data[i] = value; + mutex_lock(&o_ctrl->aw_ois_mutex); + awrw_ctrl->flag = (uint8_t)flag; + awrw_ctrl->reg_num = (uint16_t)reg_num; + /* clear old reg_data */ + if (awrw_ctrl->reg_data != NULL) + kfree(awrw_ctrl->reg_data); + /* Request memory space for reg_data; Unit: byte */ + awrw_ctrl->reg_data = kzalloc(reg_num, GFP_KERNEL); + + if (awrw_ctrl->flag == AW_SEQ_WRITE) { + /* parse reg data */ + ret = aw86006_parse_reg_data(awrw_ctrl, buf); + if (ret < 0) { + AW_LOGE("Parse reg_data error"); + mutex_unlock(&o_ctrl->aw_ois_mutex); + return ret; } + AW_LOGD("Parse reg_data OK"); + /* writes reg_data */ ois_block_write_addr8_data8(o_ctrl, reg_addr, - CAMERA_SENSOR_I2C_TYPE_WORD, o_ctrl->reg_data, reg_num); - } else if (flag == AW_SEQ_READ) { + CAMERA_SENSOR_I2C_TYPE_WORD, + awrw_ctrl->reg_data, + awrw_ctrl->reg_num); + } else if (awrw_ctrl->flag == AW_SEQ_READ) /* read data */ ois_block_read_addr8_data8(o_ctrl, reg_addr, - CAMERA_SENSOR_I2C_TYPE_WORD, o_ctrl->reg_data, reg_num); - } - mutex_unlock(&o_ctrl->ois_mutex_aw); + CAMERA_SENSOR_I2C_TYPE_WORD, + awrw_ctrl->reg_data, + awrw_ctrl->reg_num); + + mutex_unlock(&o_ctrl->aw_ois_mutex); } else { - CAM_ERR(CAM_OIS, "param error"); + AW_LOGE("Number of parameters"); } + + AW_LOGI("End"); + return count; } -static ssize_t update_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t update_show(struct class *class, struct class_attribute *attr, + char *buf) { ssize_t len = 0; len += snprintf(buf + len, PAGE_SIZE - len, - "update ois: echo 1 > update\n"); + "update ois: echo 1 > update\n"); return len; } -static ssize_t update_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) +static ssize_t update_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; uint32_t databuf = 0; - int ret = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + int ret = OIS_ERROR; + + AW_LOGI("Start"); ret = kstrtouint(buf, 0, &databuf); if (ret < 0) { - CAM_ERR(CAM_OIS, "kstrtouint fail"); + AW_LOGE("Number of parameters error"); return ret; } /* fw update */ if (databuf != 1) { - CAM_INFO(CAM_OIS, "flag error: %d", databuf); + AW_LOGE("flag error: %d", databuf); return -EPERM; } - schedule_work(&o_ctrl->fw_update_work); + schedule_work(&o_ctrl->aw_fw_update_work); + + AW_LOGI("End"); + return count; } -static ssize_t erase_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t erase_show(struct class *class, struct class_attribute *attr, + char *buf) { ssize_t len = 0; len += snprintf(buf + len, PAGE_SIZE - len, - "erase app flash: echo app > erase\n"); + "erase app flash: echo app > erase\n"); len += snprintf(buf + len, PAGE_SIZE - len, - "erase all flash: echo all > erase\n"); + "erase all flash: echo all > erase\n"); len += snprintf(buf + len, PAGE_SIZE - len, - "ois reset: echo reset > erase\n"); + "read checkinfo: echo read > erase\n"); + len += snprintf(buf + len, PAGE_SIZE - len, + "ois reset: echo reset > erase\n"); return len; } -static ssize_t erase_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) +static ssize_t erase_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + int ret = OIS_ERROR; char databuf[10] = {0}; char readbuf[64] = {0}; - int ret = OIS_ERROR; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; if (sscanf(buf, "%s", databuf) == 1) { - mutex_lock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); if (strcmp(databuf, "app") == 0) { - CAM_INFO(CAM_OIS, "aw86006 will erase app!"); - ret = aw_jump_boot_check(o_ctrl); + AW_LOGI("aw86006 will erase app!"); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + AW_LOGE("Jump boot failed"); goto err_exit; } - ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_APP_ADDR, - AW_FLASH_FULL_SIZE - - AW_FLASH_MOVE_LENGTH); + ret = aw86006_soc_flash_erase_check(o_ctrl, + AW_FLASH_APP_ADDR, AW_FLASH_FULL_SIZE - + AW_FLASH_MOVE_LENGTH); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + AW_LOGE("Erase app failed"); goto err_exit; } } else if (strcmp(databuf, "all") == 0) { - CAM_INFO(CAM_OIS, "aw86006 will erase all!"); - ret = aw_jump_boot_check(o_ctrl); + AW_LOGI("aw86006 will erase all!"); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + AW_LOGE("Jump boot failed"); goto err_exit; } - ret = aw_soc_flash_erase_check(o_ctrl, AW_FLASH_BASE_ADDR, - AW_FLASH_FULL_SIZE); + ret = aw86006_soc_flash_erase_check(o_ctrl, + AW_FLASH_BASE_ADDR, + AW_FLASH_FULL_SIZE); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + AW_LOGE("Erase all failed"); goto err_exit; } } else if (strcmp(databuf, "read") == 0) { - ret = aw_jump_boot_check(o_ctrl); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_jump_boot_check error!"); + AW_LOGE("Jump boot failed"); goto err_exit; } - ret = aw_soc_flash_read_check(o_ctrl, AW_FLASH_APP_ADDR, - readbuf, AW_FLASH_READ_LEN); + ret = aw86006_soc_flash_read_check(o_ctrl, + AW_FLASH_APP_ADDR, readbuf, + AW_FLASH_READ_LEN); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_soc_flash_erase_check error!"); + AW_LOGE("Read checkinfo failed"); goto err_exit; } } else if (strcmp(databuf, "reset") == 0) { - CAM_INFO(CAM_OIS, "aw86006 reset"); - ret = aw_reset(o_ctrl); + AW_LOGI("aw86006 reset"); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "aw_reset failed!"); + AW_LOGE("Reset failed"); goto err_exit; } } else { - CAM_ERR(CAM_OIS, "Erase: %s is not support!", databuf); + AW_LOGE("Erase: %s is not support!", databuf); } - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); } return count; err_exit: - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } -static ssize_t mode_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t mode_show(struct class *class, struct class_attribute *attr, + char *buf) { ssize_t len = 0; @@ -1482,36 +1568,37 @@ static ssize_t mode_show(struct class *class, return len; } -static ssize_t mode_store(struct class *class, - struct class_attribute *attr, +static ssize_t mode_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { - uint8_t temp = 0; - int ret = OIS_SUCCESS; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + int ret = OIS_ERROR; int loop = 0; uint32_t ois_status = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + uint8_t temp = 0; + + AW_LOGI("enter"); ret = kstrtou32(buf, 0, &ois_status); if (ret < 0) { - CAM_ERR(CAM_OIS, "Number of parameters error"); + AW_LOGE("Number of parameters error"); return ret; } if ((ois_status != OIS_DISABLE) && (ois_status != OIS_ENABLE)) { - CAM_ERR(CAM_OIS, "ois_status error: %d", ois_status); + AW_LOGE("ois_status error: %d", ois_status); return -EPERM; } /* enable OIS mode */ - mutex_lock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); do { temp = (uint8_t)ois_status; - CAM_INFO(CAM_OIS, "set ois status: %d", temp); + AW_LOGD("set ois status: %d", temp); ret = ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, CAMERA_SENSOR_I2C_TYPE_WORD, &temp, 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "Send OIS mode failed!"); - mutex_unlock(&o_ctrl->ois_mutex_aw); + AW_LOGE("Send OIS mode error"); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } /* 1000 us */ @@ -1522,18 +1609,19 @@ static ssize_t mode_store(struct class *class, ret = ois_block_read_addr8_data8(o_ctrl, REG_OIS_ENABLE, CAMERA_SENSOR_I2C_TYPE_WORD, &temp, 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "Read OIS mode error"); - mutex_unlock(&o_ctrl->ois_mutex_aw); + AW_LOGE("Read OIS mode error"); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } + AW_LOGD("OIS enable value: 0x%02x", temp); if (temp == ois_status) { - CAM_INFO(CAM_OIS, "Set OIS mode success!"); + AW_LOGI("Set OIS mode success!"); break; } - CAM_ERR(CAM_OIS, "OIS mode check error! value: 0x%02x", temp); + AW_LOGE("OIS mode check error! value: 0x%02x", temp); } while ((++loop) < AW_ERROR_LOOP); - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); if (loop >= AW_ERROR_LOOP) return OIS_ERROR; @@ -1543,22 +1631,24 @@ static ssize_t mode_store(struct class *class, static ssize_t chipid_show(struct class *class, struct class_attribute *attr, char *buf) { - uint8_t chipid = 0; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; ssize_t len = 0; - int ret = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + int ret = OIS_ERROR; + uint8_t chipid = 0; - mutex_lock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); ret = ois_block_read_addr8_data8(o_ctrl, REG_CHIPID, CAMERA_SENSOR_I2C_TYPE_WORD, &chipid, 1); if (ret < 0) { - CAM_ERR(CAM_OIS, "read chipid error"); - mutex_unlock(&o_ctrl->ois_mutex_aw); + AW_LOGE("read chipid error"); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } + AW_LOGD("Chipid: 0x%02X", chipid); + len += snprintf(buf + len, PAGE_SIZE - len, "Chipid: 0x%02X\n", chipid); - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); return len; } @@ -1572,26 +1662,27 @@ static ssize_t chipid_store(struct class *class, struct class_attribute *attr, static ssize_t version_show(struct class *class, struct class_attribute *attr, char *buf) { - uint8_t temp[4] = { 0 }; - uint32_t version = 0; - int ret = 0; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; ssize_t len = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + uint32_t version = 0; + int ret = OIS_ERROR; + uint8_t temp[4] = { 0 }; - mutex_lock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); ret = ois_block_read_addr8_data8(o_ctrl, REG_VERSION, CAMERA_SENSOR_I2C_TYPE_WORD, temp, 4); if (ret < 0) { - CAM_ERR(CAM_OIS, "read version error"); - mutex_unlock(&o_ctrl->ois_mutex_aw); + AW_LOGE("read version error"); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } version = (temp[3] << 24) | (temp[2] << 16) | (temp[1] << 8) | temp[0]; + AW_LOGD("version:v%d.%d.%d.%d", temp[3], temp[2], temp[1], temp[0]); len += snprintf(buf + len, PAGE_SIZE - len, "version: v%d.%d.%d.%d\n", temp[3], temp[2], temp[1], temp[0]); - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); return len; } @@ -1602,86 +1693,88 @@ static ssize_t version_store(struct class *class, struct class_attribute *attr, return count; } -static ssize_t checkinfo_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t checkinfo_show(struct class *class, struct class_attribute *attr, + char *buf) { ssize_t len = 0; - int i; + int i = 0; for (i = 0; i < 8; i++) { len += snprintf(buf + len, PAGE_SIZE - len, - "checkinfo_rd_0x%x 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", - i, g_aw86006_info.checkinfo_rd[i * 8 + 0], - g_aw86006_info.checkinfo_rd[i * 8 + 1], - g_aw86006_info.checkinfo_rd[i * 8 + 2], - g_aw86006_info.checkinfo_rd[i * 8 + 3], - g_aw86006_info.checkinfo_rd[i * 8 + 4], - g_aw86006_info.checkinfo_rd[i * 8 + 5], - g_aw86006_info.checkinfo_rd[i * 8 + 6], - g_aw86006_info.checkinfo_rd[i * 8 + 7]); + "checkinfo_rd_0x%x 0x%02X 0x%02X 0x%02X ", + i, g_aw86006_info.checkinfo_rd[i * 8 + 0], + g_aw86006_info.checkinfo_rd[i * 8 + 1], + g_aw86006_info.checkinfo_rd[i * 8 + 2]); len += snprintf(buf + len, PAGE_SIZE - len, - "checkinfo_fw_0x%x 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", - i, g_aw86006_info.checkinfo_fw[i * 8 + 0], - g_aw86006_info.checkinfo_fw[i * 8 + 1], - g_aw86006_info.checkinfo_fw[i * 8 + 2], - g_aw86006_info.checkinfo_fw[i * 8 + 3], - g_aw86006_info.checkinfo_fw[i * 8 + 4], - g_aw86006_info.checkinfo_fw[i * 8 + 5], - g_aw86006_info.checkinfo_fw[i * 8 + 6], - g_aw86006_info.checkinfo_fw[i * 8 + 7]); + "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + g_aw86006_info.checkinfo_rd[i * 8 + 3], + g_aw86006_info.checkinfo_rd[i * 8 + 4], + g_aw86006_info.checkinfo_rd[i * 8 + 5], + g_aw86006_info.checkinfo_rd[i * 8 + 6], + g_aw86006_info.checkinfo_rd[i * 8 + 7]); + len += snprintf(buf + len, PAGE_SIZE - len, + "checkinfo_fw_0x%x 0x%02X 0x%02X 0x%02X ", + i, g_aw86006_info.checkinfo_fw[i * 8 + 0], + g_aw86006_info.checkinfo_fw[i * 8 + 1], + g_aw86006_info.checkinfo_fw[i * 8 + 2]); + len += snprintf(buf + len, PAGE_SIZE - len, + "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + g_aw86006_info.checkinfo_fw[i * 8 + 3], + g_aw86006_info.checkinfo_fw[i * 8 + 4], + g_aw86006_info.checkinfo_fw[i * 8 + 5], + g_aw86006_info.checkinfo_fw[i * 8 + 6], + g_aw86006_info.checkinfo_fw[i * 8 + 7]); } return len; } static ssize_t checkinfo_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) + struct class_attribute *attr, + const char *buf, size_t count) { - uint32_t data[9] = {0}; - int i; - - if (sscanf(buf, "%x %x %x %x %x %x %x %x %x", &data[0], &data[1], - &data[2], &data[3], &data[4], &data[5], &data[6], &data[7], - &data[8]) == 9) { - if (data[0] > 7) { - CAM_ERR(CAM_OIS, "wrong data[0]:%d", data[0]); - return count; - } - for (i = 0; i < 8; i++) { - g_aw86006_info.checkinfo_rd[data[0] * 8 + i] = - (uint8_t) data[i + 1]; - } - } return count; } -static ssize_t freq_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t standby_show(struct class *class, struct class_attribute *attr, + char *buf) { + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; ssize_t len = 0; + int ret = OIS_ERROR; + uint8_t standby_flag = 0; - len += snprintf(buf + len, PAGE_SIZE - len, - "g_cci_freq=%d\n", g_cci_freq); + mutex_lock(&o_ctrl->aw_ois_mutex); + ret = aw86006_get_standby_flag(o_ctrl, &standby_flag); + if (ret != OIS_SUCCESS) + len += snprintf(buf + len, PAGE_SIZE - len, + "aw_read_standby error!\n"); + else + len += snprintf(buf + len, PAGE_SIZE - len, + "standby_flag: %d\n", standby_flag); + mutex_unlock(&o_ctrl->aw_ois_mutex); return len; } -static ssize_t freq_store(struct class *class, - struct class_attribute *attr, - const char *buf, size_t count) +static ssize_t standby_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { - uint32_t databuf[1]; + /* struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; */ + uint32_t databuf = 0; + int ret = OIS_ERROR; - if (sscanf(buf, "%d", &databuf[0]) == 1) { - if (databuf[0] < I2C_MAX_MODES) - g_cci_freq = databuf[0]; + ret = kstrtouint(buf, 0, &databuf); + if (ret < 0) { + AW_LOGE("kstrtouint fail"); + return ret; } return count; } -static ssize_t jump_show(struct class *class, - struct class_attribute *attr, char *buf) +static ssize_t jump_show(struct class *class, struct class_attribute *attr, + char *buf) { ssize_t len = 0; @@ -1695,178 +1788,264 @@ static ssize_t jump_show(struct class *class, return len; } -static ssize_t jump_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) +static ssize_t jump_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; char databuf[10] = {0}; - int ret = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + int ret = OIS_ERROR; if (sscanf(buf, "%s", databuf) == 1) { - mutex_lock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); if (strcmp(databuf, "boot") == 0) { - CAM_INFO(CAM_OIS, "aw86006 will jump boot!"); - ret = aw_jump_boot_check(o_ctrl); + AW_LOGI("aw86006 will jump boot!"); + ret = aw86006_jump_boot_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "jump boot failed!"); + AW_LOGE("Jump boot failed"); goto err_exit; } } else if (strcmp(databuf, "move") == 0) { - CAM_INFO(CAM_OIS, "aw86006 will jump move!"); - ret = aw_jump_move_check(o_ctrl); + AW_LOGI("aw86006 will jump move!"); + ret = aw86006_jump_move_check(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "jump move failed!"); + AW_LOGE("Jump boot failed"); goto err_exit; } } else if (strcmp(databuf, "reset") == 0) { - CAM_INFO(CAM_OIS, "aw86006 will reset!"); - ret = aw_reset(o_ctrl); + AW_LOGI("aw86006 will reset!"); + ret = aw86006_reset(o_ctrl); if (ret != OIS_SUCCESS) { - CAM_ERR(CAM_OIS, "reset failed!"); + AW_LOGE("Jump boot failed"); goto err_exit; } } else { - CAM_ERR(CAM_OIS, "jump [%s] is not support!", databuf); + AW_LOGE("jump [%s] is not support!", databuf); } - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); } return count; err_exit: - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_unlock(&o_ctrl->aw_ois_mutex); return ret; } -static ssize_t gyro_offset_cali_show(struct class *class, - struct class_attribute *attr, char *buf) +static int aw86006_get_accelgyro_dift(struct cam_ois_ctrl_t *o_ctrl, + struct accelgyro_dift ag_dift) { + uint8_t dift_val[12] = { 0 }; + + ois_block_read_addr8_data8(o_ctrl, 0xf84c, CAMERA_SENSOR_I2C_TYPE_WORD, + dift_val, 12); + + ag_dift.gyro_dift[AXIS_X] = (dift_val[1] << 8) | dift_val[0]; + ag_dift.gyro_dift[AXIS_Y] = (dift_val[3] << 8) | dift_val[2]; + ag_dift.gyro_dift[AXIS_Z] = (dift_val[5] << 8) | dift_val[4]; + + ag_dift.accel_dift[AXIS_X] = (dift_val[7] << 8) | dift_val[6]; + ag_dift.accel_dift[AXIS_Y] = (dift_val[9] << 8) | dift_val[8]; + ag_dift.accel_dift[AXIS_Z] = (dift_val[11] << 8) | dift_val[10]; + + AW_LOGI("gyro_dift: 0x%04x 0x%04x 0x%04x", ag_dift.gyro_dift[AXIS_X], + ag_dift.gyro_dift[AXIS_Y], + ag_dift.gyro_dift[AXIS_Z]); + + AW_LOGI("accel_dift: 0x%04x 0x%04x 0x%04x", ag_dift.accel_dift[AXIS_X], + ag_dift.accel_dift[AXIS_Y], + ag_dift.accel_dift[AXIS_Z]); + return 0; +} + +static ssize_t gyro_offset_cali_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + struct accelgyro_dift ag_dift = {0}; ssize_t len = 0; - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; - uint8_t val[6] = { 0 }; - int16_t offset_val; + + aw86006_get_accelgyro_dift(o_ctrl, ag_dift); len += snprintf(buf + len, PAGE_SIZE - len, - "gyro_offset: echo 1 > gyro_offset_cali\n"); - - /* Gyro offset data */ - ois_block_read_addr8_data8(o_ctrl, 0xf84c, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 4); - offset_val = val[1]<<8 |val[0]; + "gyro_dift: 0x%04x 0x%04x 0x%04x\n", + ag_dift.gyro_dift[AXIS_X], + ag_dift.gyro_dift[AXIS_Y], + ag_dift.gyro_dift[AXIS_Z]); len += snprintf(buf + len, PAGE_SIZE - len, - "gyro x offset = %d\n", offset_val); - - offset_val = val[3]<<8 |val[2]; - len += snprintf(buf + len, PAGE_SIZE - len, - "gyro y offset = %d\n", offset_val); + "accel_dift: 0x%04x 0x%04x 0x%04x\n", + ag_dift.accel_dift[AXIS_X], + ag_dift.accel_dift[AXIS_Y], + ag_dift.accel_dift[AXIS_Z]); return len; } static ssize_t gyro_offset_cali_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) + struct class_attribute *attr, + const char *buf, size_t count) { - struct cam_ois_ctrl_t *o_ctrl = o_ctrl_g; + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + struct accelgyro_dift ag_dift = {0}; int i = 0; - uint8_t data_buf[5] = { 0 }; - uint8_t val[15] = { 0 }; + int ret = OIS_ERROR; + uint32_t flag = 0; uint8_t ois_mode = 0; - int16_t offset_val = 0; + uint8_t unlock_val[2] = { 0xa4, 0xac }; + uint8_t lock_val[2] = { 0xdc, 0xd4 }; + uint8_t trigger_cmd[4] = { 0x01, 0x02, 0x01, 0x01 }; + uint8_t exit_cmd[4] = { 0x00, 0x00, 0x00, 0x02 }; + uint8_t check_val = 0; - if (sscanf(buf, "%d", &data_buf[0]) != 1) { - CAM_ERR(CAM_OIS, "input para error!"); + AW_LOGI("start!"); + + ret = kstrtouint(buf, 0, &flag); + if (ret < 0) { + AW_LOGE("input para error!"); return OIS_ERROR; } - CAM_INFO(CAM_OIS, "aw86006 gyro offset cali start!"); - /* off OIS */ + /* OIS off */ ois_mode = OIS_DISABLE; ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, CAMERA_SENSOR_I2C_TYPE_WORD, &ois_mode, 1); msleep(20); - i = 0; + /* unlock register */ do { - val[0] = 0xa4; ois_block_write_addr8_data8(o_ctrl, 0xf20f, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 1); + CAMERA_SENSOR_I2C_TYPE_WORD, &unlock_val[0], 1); msleep(20); ois_block_read_addr8_data8(o_ctrl, 0xf20f, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[0], 1); + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); i++; - } while ((val[0] != 1) && (i < (50 * AW_ERROR_LOOP))); - if (val[0] != 1) { - CAM_ERR(CAM_OIS, "read reg[0xf20f] != 0x01, i=%d,val[0]=%d",i,val[0] ); + } while ((check_val != 1) && (i < (50 * AW_ERROR_LOOP))); + if (check_val != 1) { + AW_LOGE("reg[f20f]:0x%x != 0x01, i: %d", check_val, i); return OIS_ERROR; } - + /* unlock register */ i = 0; do { - val[1] = 0xac; ois_block_write_addr8_data8(o_ctrl, 0xf8ff, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[1], 1); + CAMERA_SENSOR_I2C_TYPE_WORD, &unlock_val[1], 1); msleep(20); ois_block_read_addr8_data8(o_ctrl, 0xf8ff, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[1], 1); + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); i++; - } while ((val[1] != 1) && (i < (50 * AW_ERROR_LOOP))); - if (val[1] != 1) { - CAM_ERR(CAM_OIS, "read reg[0xf8ff] != 0x01, i=%d,val=%d",i,val[1] ); + } while ((check_val != 1) && (i < (50 * AW_ERROR_LOOP))); + if (check_val != 1) { + AW_LOGE("reg[f8ff]:0x%x != 0x01, i: %d", check_val, i); return OIS_ERROR; } - - val[2] = 0x01; - ois_block_write_addr8_data8(o_ctrl, 0xf8e4, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[2], 1); + /* Read the data in the flash into the register */ + ois_block_write_addr8_data8(o_ctrl, 0xf8e4, CAMERA_SENSOR_I2C_TYPE_WORD, + &trigger_cmd[0], 1); msleep(5); /* delay 5ms at least */ - val[3] = 0x02; - ois_block_write_addr8_data8(o_ctrl, 0xf200, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[3], 1); - val[4] = 0x01; - ois_block_write_addr8_data8(o_ctrl, 0xf203, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[4], 1); - val[5] = 0x01; - ois_block_write_addr8_data8(o_ctrl, 0xf202, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[5], 1); + /* Select the gyroscope zero drift calibration function */ + ois_block_write_addr8_data8(o_ctrl, 0xf200, CAMERA_SENSOR_I2C_TYPE_WORD, + &trigger_cmd[1], 1); + /* Enter mass production test mode */ + ois_block_write_addr8_data8(o_ctrl, 0xf203, CAMERA_SENSOR_I2C_TYPE_WORD, + &trigger_cmd[2], 1); + /* Trigger zero drift calibration of gyroscope */ + ois_block_write_addr8_data8(o_ctrl, 0xf202, CAMERA_SENSOR_I2C_TYPE_WORD, + &trigger_cmd[3], 1); msleep(2000); /* delay 2s at least */ + /* Check if the calibration is complete */ i = 0; do { ois_block_read_addr8_data8(o_ctrl, 0xf201, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[5], 1); + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); msleep(20); i++; - } while ((val[5] != 0x21) && (i < (50 * AW_ERROR_LOOP))); - if (val[5] != 0x21) { - CAM_ERR(CAM_OIS, "read reg[0xf201] != 0x21, i=%d,val=%d",i,val[5] ); + } while ((check_val != 0x21) && (i < (50 * AW_ERROR_LOOP))); + if (check_val != 0x21) { + AW_LOGE("reg[f201]:0x%x != 0x21, i: %d", check_val, i); return OIS_ERROR; } + /* Exit calibration mode */ + ois_block_write_addr8_data8(o_ctrl, 0xf200, CAMERA_SENSOR_I2C_TYPE_WORD, + &exit_cmd[0], 1); + ois_block_write_addr8_data8(o_ctrl, 0xf202, CAMERA_SENSOR_I2C_TYPE_WORD, + &exit_cmd[1], 1); + ois_block_write_addr8_data8(o_ctrl, 0xf203, CAMERA_SENSOR_I2C_TYPE_WORD, + &exit_cmd[2], 1); + /* Data update to flash */ + ois_block_write_addr8_data8(o_ctrl, 0xf8e4, CAMERA_SENSOR_I2C_TYPE_WORD, + &exit_cmd[3], 1); + /* Lock register */ + ois_block_write_addr8_data8(o_ctrl, 0xf8ff, CAMERA_SENSOR_I2C_TYPE_WORD, + &lock_val[0], 1); + ois_block_write_addr8_data8(o_ctrl, 0xf20f, CAMERA_SENSOR_I2C_TYPE_WORD, + &lock_val[1], 1); - val[6] = 0x00; - ois_block_write_addr8_data8(o_ctrl, 0xf203, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[6], 1); - val[7] = 0x02; - ois_block_write_addr8_data8(o_ctrl, 0xf8e4, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[7], 1); - val[8] = 0xdc; - ois_block_write_addr8_data8(o_ctrl, 0xf8ff, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[8], 1); - val[9] = 0xd4; - ois_block_write_addr8_data8(o_ctrl, 0xf20f, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[9], 1); + /* Read the zero drift value of the three-axis angular velocity and + * acceleration of the gyroscope + */ + aw86006_get_accelgyro_dift(o_ctrl, ag_dift); - /* Gyro offset data */ - ois_block_read_addr8_data8(o_ctrl, 0xf84c, - CAMERA_SENSOR_I2C_TYPE_WORD, &val[10], 4); - offset_val = (val[11]<<8) |val[10]; - CAM_INFO(CAM_OIS, "aw86006 gyro x offset = %d!", offset_val); + AW_LOGI("aw86006 gyro offset cali success!"); - offset_val = (val[13]<<8) |val[12]; - CAM_INFO(CAM_OIS, "aw86006 gyro y offset = %d!", offset_val); + return count; +} + +static ssize_t slave_var_show(struct class *class, struct class_attribute *attr, + char *buf) +{ + ssize_t len = 0; + return len; +} + +static ssize_t slave_var_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) +{ + struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; + uint32_t databuf[5] = { 0 }; + uint16_t temp_addr = 0; + uint32_t addr_type = 1; + + AW_LOGI("enter"); + + temp_addr = o_ctrl->io_master_info.cci_client->sid; + + if (sscanf(buf, "%x %x %x %x %x", &databuf[0], &databuf[1], &databuf[2], + &databuf[3], &databuf[4]) == 5) { + AW_LOGI("1.slave: 0x%02x, flag: 0x%02x, addr_type: 0x%02x", + databuf[0], databuf[1], databuf[2]); + AW_LOGI("reg: 0x%04x, val: 0x%02x", databuf[3], databuf[4]); + + o_ctrl->io_master_info.cci_client->sid = databuf[0]; + if (databuf[2] == 0x01) + addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + else if (databuf[2] == 0x02) + addr_type = CAMERA_SENSOR_I2C_TYPE_WORD; + + if (databuf[1] == AW_SEQ_WRITE) { + ois_block_write_addr8_data8(o_ctrl, databuf[3], + addr_type, (uint8_t *) &databuf[4], + CAMERA_SENSOR_I2C_TYPE_BYTE); + /* callback read */ + databuf[4] = 0; + ois_block_read_addr8_data8(o_ctrl, databuf[3], + addr_type, (uint8_t *) &databuf[4], + CAMERA_SENSOR_I2C_TYPE_BYTE); + } else if (databuf[1] == AW_SEQ_READ) { + databuf[4] = 0; + ois_block_read_addr8_data8(o_ctrl, databuf[3], + addr_type, (uint8_t *) &databuf[4], + CAMERA_SENSOR_I2C_TYPE_BYTE); + } + AW_LOGI("2.slave: 0x%02x, flag: 0x%02x, addr_type: 0x%02x", + databuf[0], databuf[1], databuf[2]); + AW_LOGI("reg: 0x%04x, val: 0x%02x", databuf[3], databuf[4]); + } + + o_ctrl->io_master_info.cci_client->sid = temp_addr; - CAM_INFO(CAM_OIS, "aw86006 gyro offset cali success!"); return count; } @@ -1882,136 +2061,161 @@ static CLASS_ATTR_RW(mode); static CLASS_ATTR_RW(chipid); static CLASS_ATTR_RW(version); static CLASS_ATTR_RW(checkinfo); -static CLASS_ATTR_RW(freq); +static CLASS_ATTR_RW(standby); static CLASS_ATTR_RW(jump); static CLASS_ATTR_RW(gyro_offset_cali); +static CLASS_ATTR_RW(slave_var); -int aw_create_sysfs(void) +static int aw86006_create_sysfs(void) { - int ret = 0; + int ret = OIS_ERROR; + + AW_LOGI("Start"); if (!ois_debug_class) { - CAM_INFO(CAM_OIS, "create aw86006_result_class!"); - ois_debug_class = class_create(THIS_MODULE, "ois"); + AW_LOGI("create aw86006_result_class!"); + ois_debug_class = class_create(THIS_MODULE, "aw86006_ois"); ret = class_create_file(ois_debug_class, &class_attr_reg); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file reg failed, ret:%d", - ret); + AW_LOGE("Create reg failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_awrw); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file awrw failed, ret:%d", - ret); + AW_LOGE("Create awrw failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_update); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file update failed, ret:%d", - ret); + AW_LOGE("Create update failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_erase); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file erase failed, ret:%d", - ret); + AW_LOGE("Create erase failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_mode); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file mode failed, ret:%d", - ret); + AW_LOGE("Create mode failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_chipid); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file chipid failed, ret:%d", - ret); + AW_LOGE("Create chipid failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_version); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file version failed, ret:%d", - ret); + AW_LOGE("Create version failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_checkinfo); if (ret < 0) { - CAM_ERR(CAM_OIS, - "Create class file checkinfo failed, ret:%d", - ret); + AW_LOGE("Create checkinfo failed, ret: %d", ret); return ret; } - ret = class_create_file(ois_debug_class, &class_attr_freq); + ret = class_create_file(ois_debug_class, &class_attr_standby); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file freq failed, ret:%d", - ret); + AW_LOGE("Create standby failed, ret: %d", ret); return ret; } ret = class_create_file(ois_debug_class, &class_attr_jump); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file jump failed, ret:%d", - ret); + AW_LOGE("Create jump failed, ret: %d", ret); return ret; } - ret = class_create_file(ois_debug_class, &class_attr_gyro_offset_cali); + ret = class_create_file(ois_debug_class, + &class_attr_gyro_offset_cali); if (ret < 0) { - CAM_ERR(CAM_OIS, "Create class file gyro offset failed, ret:%d", ret); - return ret; + AW_LOGE("Create gyro_offset_cali failed, ret: %d", ret); + return ret; + } + ret = class_create_file(ois_debug_class, &class_attr_slave_var); + if (ret < 0) { + AW_LOGE("Create slave_var failed, ret: %d", ret); + return ret; } } - CAM_INFO(CAM_OIS, "Creat sysfs debug success."); + AW_LOGI("Creat sysfs debug success."); + return 0; } -void aw_destroy_sysfs(void) +static void aw86006_destroy_sysfs(void) { + AW_LOGI("Start"); + if (ois_debug_class) { class_remove_file(ois_debug_class, &class_attr_reg); + class_remove_file(ois_debug_class, &class_attr_awrw); class_remove_file(ois_debug_class, &class_attr_update); class_remove_file(ois_debug_class, &class_attr_erase); - class_remove_file(ois_debug_class, &class_attr_awrw); - class_remove_file(ois_debug_class, &class_attr_checkinfo); - class_remove_file(ois_debug_class, &class_attr_freq); - class_remove_file(ois_debug_class, &class_attr_jump); + class_remove_file(ois_debug_class, &class_attr_mode); class_remove_file(ois_debug_class, &class_attr_chipid); class_remove_file(ois_debug_class, &class_attr_version); - class_remove_file(ois_debug_class, &class_attr_mode); - class_remove_file(ois_debug_class, &class_attr_gyro_offset_cali); + class_remove_file(ois_debug_class, &class_attr_checkinfo); + class_remove_file(ois_debug_class, &class_attr_standby); + class_remove_file(ois_debug_class, &class_attr_jump); + class_remove_file(ois_debug_class, + &class_attr_gyro_offset_cali); + class_remove_file(ois_debug_class, &class_attr_slave_var); class_destroy(ois_debug_class); ois_debug_class = NULL; - CAM_INFO(CAM_OIS, "delete ois_debug_class done!"); + AW_LOGD("destroy ois_debug_class done!"); } -} + AW_LOGI("End"); +} /******************************************************************************* * aw86006 ois init + * Callback: Path: function ******************************************************************************/ -int aw_ois_init(struct cam_ois_ctrl_t *o_ctrl) +int aw86006_ois_init(struct cam_ois_ctrl_t *o_ctrl) { - int rc = 0; + int loop = 0; - CAM_INFO(CAM_OIS, "enter, %s", AW86006_DRIVER_VERSION); - o_ctrl_g = o_ctrl; - INIT_WORK(&o_ctrl->fw_update_work, aw_firmware_update_work_routine); - mutex_init(&o_ctrl->ois_mutex_aw); - aw_create_sysfs(); - CAM_INFO(CAM_OIS, "exit"); + AW_LOGI("enter, %s", AW86006_DRIVER_VERSION); - return rc; + /* awrw_ctrl: debug node awrw */ + do { + o_ctrl->awrw_ctrl = kzalloc(sizeof(struct awrw_ctrl), + GFP_KERNEL); + if (!o_ctrl->awrw_ctrl) { + AW_LOGE("Request memory for awrw_ctrl error"); + continue; + } + break; + } while ((++loop) < AW_ERROR_LOOP); + if (loop >= AW_ERROR_LOOP) + return -ENOMEM; + + INIT_WORK(&o_ctrl->aw_fw_update_work, + aw86006_firmware_update_work_routine); + mutex_init(&o_ctrl->aw_ois_mutex); + aw86006_create_sysfs(); /* adb debug node */ + + g_o_ctrl = o_ctrl; + + AW_LOGI("exit"); + + return OIS_SUCCESS; } -int aw_ois_exit(struct cam_ois_ctrl_t *o_ctrl) +int aw86006_ois_exit(struct cam_ois_ctrl_t *o_ctrl) { - int rc = 0; + AW_LOGI("enter"); - CAM_INFO(CAM_OIS, "enter"); - aw_destroy_sysfs(); - return rc; + aw86006_destroy_sysfs(); + + kfree(o_ctrl->awrw_ctrl); + + return OIS_SUCCESS; } +MODULE_AUTHOR(""); MODULE_DESCRIPTION("AWINIC OIS Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index 7565750f6fd1..b5cc9b2bef02 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -1,6 +1,14 @@ #ifndef AW86006_OIS_H #define AW86006_OIS_H +/* Log Format */ +#define AW_LOGI(format, ...) \ + CAM_INFO(CAM_OIS, format, ##__VA_ARGS__) +#define AW_LOGD(format, ...) \ + CAM_DBG(CAM_OIS, format, ##__VA_ARGS__) +#define AW_LOGE(format, ...) \ + CAM_ERR(CAM_OIS, format, ##__VA_ARGS__) + /* I2c address */ #define AW_SHUTDOWN_I2C_ADDR (0xC2 >> 1) /* 0x61 */ #define AW_WAKEUP_I2C_ADDR (0xD2 >> 1) /* 0x69 */ @@ -30,6 +38,7 @@ #define OIS_SUCCESS (0) #define AW_IC_STANDBY (1) #define AW_FLASH_WRITE_CONNECT +/* #define AW_SOC_FLASH_READ_FLAG */ /* Loop */ #define AW_STAY_ON_MOVE_LOOP (20) @@ -40,9 +49,16 @@ #define AW_FLASH_ERASE_ERROR_LOOP (2) #define AW_JUMP_BOOT_LOOP (6) #define AW_JUMP_MOVE_LOOP (6) -#define AW_STOP_CMD_LOOP (10) /* Addr or data size */ +#define AW_SIZE_BYTE_0 (0) +#define AW_SIZE_BYTE_1 (1) +#define AW_SIZE_BYTE_2 (2) +#define AW_SIZE_BYTE_3 (3) +#define AW_SIZE_BYTE_4 (4) +#define AW_SIZE_BYTE_12 (12) +#define AW_SIZE_BYTE_20 (20) +#define AW_PROTOCOL_SIZE (14) #define AW_DATA_SHIFT_0_BIT (0) #define AW_DATA_SHIFT_8_BIT (8) #define AW_DATA_SHIFT_16_BIT (16) @@ -80,7 +96,6 @@ #define AW_FW_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_MOVE_LENGTH + 8) #define AW_ARRAY_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_UPDATE_FLAG - AW_FLASH_MOVE_LENGTH) - /* SOC */ enum soc_status { SOC_OK = 0, @@ -93,65 +108,77 @@ enum soc_status { }; enum soc_module { - SOC_HANK = 0x01, - SOC_SRAM = 0x02, - SOC_FLASH = 0x03, - SOC_END = 0x04, + SOC_HANK = 0x01, + SOC_SRAM = 0x02, + SOC_FLASH = 0x03, + SOC_END = 0x04, }; enum soc_enum { - SOC_VERSION = 0x01, - SOC_CTL = 0x00, - SOC_ACK = 0x01, - SOC_ADDR = 0x84, - SOC_READ_ADDR = 0x48, - SOC_ERASE_STRUCT_LEN = 6, - SOC_READ_STRUCT_LEN = 6, - SOC_PROTOCAL_HEAD = 9, - SOC_CONNECT_WRITE_LEN = 9, - SOC_ERASE_WRITE_LEN = 15, - SOC_READ_WRITE_LEN = 15, - SOC_ERASE_BLOCK_DELAY = 8, - SOC_WRITE_BLOCK_HEAD = 13, - SOC_WRITE_BLOCK_DELAY = 1000, /* us */ - SOC_READ_BLOCK_DELAY = 2000, /* us */ - SOC_CONNECT_DELAY = 2000, /* us */ + SOC_VERSION = 0x01, + SOC_CTL = 0x00, + SOC_ACK = 0x01, + SOC_ADDR = 0x84, + SOC_READ_ADDR = 0x48, + SOC_ERASE_STRUCT_LEN = 6, + SOC_READ_STRUCT_LEN = 6, + SOC_PROTOCAL_HEAD = 9, + SOC_CONNECT_WRITE_LEN = 9, + SOC_ERASE_WRITE_LEN = 15, + SOC_READ_WRITE_LEN = 15, + SOC_ERASE_BLOCK_DELAY = 8, + SOC_WRITE_BLOCK_HEAD = 13, + SOC_WRITE_BLOCK_DELAY = 1000, /* us */ + SOC_READ_BLOCK_DELAY = 2000, /* us */ + SOC_CONNECT_DELAY = 2000, /* us */ }; enum soc_flash_event { - SOC_FLASH_WRITE = 0x01, - SOC_FLASH_WRITE_ACK = 0x02, - SOC_FLASH_READ = 0x11, - SOC_FLASH_READ_ACK = 0x12, - SOC_FLASH_ERASE_BLOCK = 0x21, - SOC_FLASH_ERASE_BLOCK_ACK = 0x22, - SOC_FLASH_ERASE_CHIP = 0x23, - SOC_FLASH_ERASE_CHIP_ACK = 0x24, + SOC_FLASH_WRITE = 0x01, + SOC_FLASH_WRITE_ACK = 0x02, + SOC_FLASH_READ = 0x11, + SOC_FLASH_READ_ACK = 0x12, + SOC_FLASH_ERASE_BLOCK = 0x21, + SOC_FLASH_ERASE_BLOCK_ACK = 0x22, + SOC_FLASH_ERASE_CHIP = 0x23, + SOC_FLASH_ERASE_CHIP_ACK = 0x24, }; enum soc_hank_event { - SOC_HANK_CONNECT = 0x01, - SOC_HANK_CONNECT_ACK = 0x02, - SOC_HANK_PROTICOL = 0x11, - SOC_HANK_PROTICOL_ACK = 0x12, - SOC_HANK_VERSION = 0x21, - SOC_HANK_VERSION_ACK = 0x22, - SOC_HANK_ID = 0x31, - SOC_HANK_ID_ACK = 0x32, - SOC_HANK_DATE = 0x33, - SOC_HANK_DATA_ACK = 0x34, + SOC_HANK_CONNECT = 0x01, + SOC_HANK_CONNECT_ACK = 0x02, + SOC_HANK_PROTICOL = 0x11, + SOC_HANK_PROTICOL_ACK = 0x12, + SOC_HANK_VERSION = 0x21, + SOC_HANK_VERSION_ACK = 0x22, + SOC_HANK_ID = 0x31, + SOC_HANK_ID_ACK = 0x32, + SOC_HANK_DATE = 0x33, + SOC_HANK_DATA_ACK = 0x34, }; +/* ISP */ enum isp_enum { - ISP_READ_VERSION_DELAY = 500, /* us */ - ISP_VERS_CONNECT_ACK = 0x01, - ISP_VERSION_ACK_LEN = 5, - ISP_EVENT_OK = 0x01, + ISP_READ_VERSION_DELAY = 500, /* us */ + ISP_VERS_CONNECT_ACK = 0x01, + ISP_VERSION_ACK_LEN = 5, + ISP_EVENT_OK = 0x01, }; enum awrw_flag { - AW_SEQ_WRITE = 0, - AW_SEQ_READ = 1, + AW_SEQ_WRITE = 0, + AW_SEQ_READ = 1, +}; + +enum axis_info { + AXIS_X, + AXIS_Y, + AXIS_Z, +}; + +struct accelgyro_dift { + int16_t gyro_dift[3]; + int16_t accel_dift[3]; }; /* Struct */ 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 ef94e34cdf4d..fe3a50356011 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -17,7 +17,7 @@ extern int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); extern void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); -extern int aw_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw); +extern int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw); int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -415,9 +415,9 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) CAM_INFO(CAM_OIS, "Firmware download started."); } else if (strstr(o_ctrl->ois_name, "aw86006")) { - mutex_lock(&o_ctrl->ois_mutex_aw); - rc = aw_firmware_update(o_ctrl, fw); - mutex_unlock(&o_ctrl->ois_mutex_aw); + mutex_lock(&o_ctrl->aw_ois_mutex); + rc = aw86006_firmware_update(o_ctrl, fw); + mutex_unlock(&o_ctrl->aw_ois_mutex); return rc; } diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index f54d44e3e864..689fd492ae47 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -10,8 +10,8 @@ #include "cam_debug_util.h" #include "camera_main.h" -extern int aw_ois_init(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ -extern int aw_ois_exit(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ +extern int aw86006_ois_init(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ +extern int aw86006_ois_exit(struct cam_ois_ctrl_t *o_ctrl); /* awinic add */ static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl) { @@ -515,7 +515,7 @@ static int cam_ois_component_bind(struct device *dev, init_completion(&o_ctrl->ois_data_complete); if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) - aw_ois_init(o_ctrl); + aw86006_ois_init(o_ctrl); if (o_ctrl->is_ois_vsync_irq_supported) { o_ctrl->vsync_irq = platform_get_irq_optional(pdev, 0); @@ -571,7 +571,7 @@ static void cam_ois_component_unbind(struct device *dev, CAM_INFO(CAM_OIS, "platform driver remove invoked"); if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) - aw_ois_exit(o_ctrl); + aw86006_ois_exit(o_ctrl); soc_info = &o_ctrl->soc_info; for (i = 0; i < soc_info->num_clk; i++) 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 b06872bb53ae..61abd92b9222 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -94,6 +94,13 @@ struct cam_ois_intf_params { struct cam_req_mgr_crm_cb *crm_cb; }; +struct awrw_ctrl { + uint32_t addr[4]; + uint16_t reg_num; + uint8_t flag; + uint8_t *reg_data; +}; + /** * struct cam_ois_ctrl_t - OIS ctrl private data * @device_name : ois device_name @@ -168,11 +175,9 @@ struct cam_ois_ctrl_t { uint64_t mono_timestamp; /* awinic_add */ const char *ic_name; - struct work_struct fw_update_work; - uint32_t awrw_flag; - uint32_t reg_num; - uint8_t *reg_data; - struct mutex ois_mutex_aw; + struct work_struct aw_fw_update_work; + struct mutex aw_ois_mutex; + struct awrw_ctrl *awrw_ctrl; }; /** From f724450d83363b464b7055682570278247343529 Mon Sep 17 00:00:00 2001 From: huqian4 Date: Fri, 15 Apr 2022 17:29:35 +0800 Subject: [PATCH 54/86] dubai: read sensorid failed,but return success detail: Returns error after five retry Change-Id: I526bcf3ea22c838280ffd0d6d3a7d055d7c764d7 Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2243930 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Pengfei Qiao Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 5bcd6bb6f1ad..5cec714779c4 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -718,7 +718,7 @@ int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl) if (!matched && !retries) { CAM_ERR(CAM_SENSOR, "Failed read id: 0x%x expected id 0x%x:", chipid, slave_info->sensor_id); - + return -ENODEV; } } #else From aacc836319b68dc0edf8c9fecf48debfd92bd23f Mon Sep 17 00:00:00 2001 From: chenlj26 Date: Tue, 19 Apr 2022 18:37:14 +0800 Subject: [PATCH 55/86] camera-kernel: miami: front camera ov32c4c and ov32b40 compatible details: front camera ov32c4c and ov32b40 compatible front camera ov32c4c bring up on 8350 baseline Change-Id: Ibbab62bdfb9784bc302222d7794137d3ccfb2d5b Signed-off-by: chenlj26 Reviewed-on: https://gerrit.mot.com/2246392 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Shuo Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 82 ++++++++++++++++++- .../cam_sensor/cam_sensor_dev.h | 7 ++ include/uapi/camera/media/cam_sensor.h | 7 ++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 5cec714779c4..9e32a73719bd 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -454,16 +454,80 @@ int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info, s_ctrl->sub_device_cci_master = probe_info->sub_device_cci_master; s_ctrl->sub_device_cci_device = probe_info->sub_device_cci_device; s_ctrl->sub_device_i2c_freq_mode = probe_info->sub_device_i2c_freq_mode; +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH + s_ctrl->i2c_addr_switch = probe_info->i2c_addr_switch; + s_ctrl->second_i2c_address = probe_info->second_i2c_address; + s_ctrl->i2c_switch_reg_addr_Type = probe_info->i2c_switch_reg_addr_Type; + s_ctrl->i2c_switch_reg_data_Type = probe_info->i2c_switch_reg_data_Type; + s_ctrl->i2c_switch_reg_addr = probe_info->i2c_switch_reg_addr; + s_ctrl->i2c_switch_reg_data = probe_info->i2c_switch_reg_data; + s_ctrl->i2c_switch_reg_delayMs = probe_info->i2c_switch_reg_delayMs; CAM_DBG(CAM_SENSOR, - "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x", + "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x sensor_pipeline_delay:0x%x i2c_addr_switch: 0x%x second_i2c_address: 0x%x i2c_switch_reg_addr: 0x%x", s_ctrl->sensordata->slave_info.sensor_id_reg_addr, s_ctrl->sensordata->slave_info.sensor_id, s_ctrl->sensordata->slave_info.sensor_id_mask, - s_ctrl->pipeline_delay); + s_ctrl->pipeline_delay, + s_ctrl->i2c_addr_switch , + s_ctrl->second_i2c_address , + s_ctrl->i2c_switch_reg_addr); +#endif return rc; } +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH +int cam_sensor_set_i2c_addr_switch_reg(struct cam_sensor_ctrl_t *s_ctrl) +{ + int rc = 0; + uint16_t sensor_address = 0; + struct cam_sensor_i2c_reg_setting wr_setting; + struct cam_sensor_i2c_reg_array reg_setting; + + /* if hal doesn't config i2c_addr_switch parameter in sensor xml, return success immediately */ + if (!s_ctrl->i2c_addr_switch) { + return 0; + } + + /* save sensor i2c address */ + sensor_address = s_ctrl->io_master_info.cci_client->sid; + + /* set sub-device i2c address */ + if (s_ctrl->second_i2c_address) { + s_ctrl->io_master_info.cci_client->sid = s_ctrl->second_i2c_address >> 1; + } + + reg_setting.reg_addr = s_ctrl->i2c_switch_reg_addr; + reg_setting.reg_data = s_ctrl->i2c_switch_reg_data; + reg_setting.delay = s_ctrl->i2c_switch_reg_delayMs; /* delay after switch iic addr */ + reg_setting.data_mask = 0; + wr_setting.addr_type = s_ctrl->i2c_switch_reg_addr_Type; + wr_setting.data_type = s_ctrl->i2c_switch_reg_data_Type; + wr_setting.reg_setting = ®_setting; + wr_setting.size = 1; + wr_setting.delay = 0; + rc = camera_io_dev_write(&s_ctrl->io_master_info, &wr_setting); +CAM_ERR(CAM_SENSOR, + "cam_sensor_set_i2c_addr_switch_reg slot:%d, slave_addr:0x%x, sensor_id:0x%x, sensor_address:0x%x", + s_ctrl->soc_info.index, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensordata->slave_info.sensor_id, + sensor_address); + /* restore sensor i2c address */ + s_ctrl->io_master_info.cci_client->sid = sensor_address; + + if (rc == 0) { + CAM_ERR(CAM_SENSOR, "write i2c addr switch reg success"); + } + else { + CAM_ERR(CAM_SENSOR, "write i2c addr switch reg fail"); + rc = -EINVAL; + } + + return rc; +} +#endif + int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf, struct cam_sensor_ctrl_t *s_ctrl, int32_t cmd_buf_num, uint32_t cmd_buf_length, size_t remain_len) @@ -922,6 +986,20 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, goto free_power_settings; } +#ifdef CONFIG_CAMERA_CCI_ADDR_SWITCH + /* load probe setting before read sensorID */ + rc = cam_sensor_set_i2c_addr_switch_reg(s_ctrl); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "set i2c addr switch reg failed ! slot:%d, slave_addr:0x%x, sensor_id:0x%x", + s_ctrl->soc_info.index, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensordata->slave_info.sensor_id); + cam_sensor_power_down(s_ctrl); + msleep(20); + goto free_power_settings; + } +#endif /* Match sensor ID */ rc = cam_sensor_match_id(s_ctrl); if (rc < 0) { diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index faf8fc8c8eab..96c1cf9bc6fd 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -121,6 +121,13 @@ struct cam_sensor_ctrl_t { uint8_t sub_device_cci_device; uint8_t sub_device_i2c_freq_mode; bool need_change_cci_master; + uint8_t i2c_addr_switch; + uint16_t second_i2c_address; + uint8_t i2c_switch_reg_addr_Type; + uint8_t i2c_switch_reg_data_Type; + uint16_t i2c_switch_reg_addr; + uint16_t i2c_switch_reg_data; + uint16_t i2c_switch_reg_delayMs; }; /** diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 3df242f29044..7f52004c4f85 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -181,6 +181,13 @@ struct cam_cmd_probe { __u8 sub_device_cci_master; __u8 sub_device_cci_device; __u8 sub_device_i2c_freq_mode; + __u8 i2c_addr_switch; + __u32 second_i2c_address; + __u8 i2c_switch_reg_addr_Type; + __u8 i2c_switch_reg_data_Type; + __u32 i2c_switch_reg_addr; + __u32 i2c_switch_reg_data; + __u32 i2c_switch_reg_delayMs; } __attribute__((packed)); /** From c5923c96a5815f83d4004e4f6bfc6eab47846f74 Mon Sep 17 00:00:00 2001 From: huqian4 Date: Mon, 18 Apr 2022 12:50:42 +0800 Subject: [PATCH 56/86] Tundra: support 2nd gyro compatible detail: Dongwoon OIS compatible 2nd gyro kernel. Change-Id: I9cc4918032534a1fa56037a46ccedbff19dc8a6c Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2244554 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Long Cheng Reviewed-by: Wang Liu Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 41 +++++++++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 1 + .../cam_sensor_module/cam_ois/cam_ois_dev.h | 1 + .../cam_sensor_utils/cam_sensor_cmn_header.h | 3 +- 4 files changed, 45 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 fe3a50356011..8154c7695d67 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -965,6 +965,41 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) return rc; } break; + case CAM_OIS_PACKET_OPCODE_OIS_GYRO_OFFSET: + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + rc = -EINVAL; + CAM_WARN(CAM_OIS, + "Not in right state to control OIS: %d", + o_ctrl->cam_ois_state); + 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); + i2c_reg_settings = &(o_ctrl->i2c_gyro_data); + i2c_reg_settings->is_settings_valid = 1; + i2c_reg_settings->request_id = 0; + rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info, + i2c_reg_settings, + cmd_desc, 1, NULL); + if (rc < 0) { + CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc); + return rc; + } + + rc = cam_ois_apply_settings(o_ctrl, i2c_reg_settings); + if (rc < 0) { + CAM_ERR(CAM_OIS, "Cannot apply gyro offset settings"); + return rc; + } + + rc = delete_request(i2c_reg_settings); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "Fail deleting gyro offset data: rc: %d", rc); + return rc; + } + break; case CAM_OIS_PACKET_OPCODE_READ: { struct cam_buf_io_cfg *io_cfg; struct i2c_settings_array i2c_read_settings; @@ -1541,6 +1576,9 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl) if (o_ctrl->i2c_mode_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_mode_data); + if (o_ctrl->i2c_gyro_data.is_settings_valid == 1) + delete_request(&o_ctrl->i2c_gyro_data); + if (o_ctrl->i2c_calib_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_calib_data); @@ -1668,6 +1706,9 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (o_ctrl->i2c_mode_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_mode_data); + if (o_ctrl->i2c_gyro_data.is_settings_valid == 1) + delete_request(&o_ctrl->i2c_gyro_data); + if (o_ctrl->i2c_calib_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_calib_data); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 689fd492ae47..f19832eaa824 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -490,6 +490,7 @@ static int cam_ois_component_bind(struct device *dev, INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head)); INIT_LIST_HEAD(&(o_ctrl->i2c_postcalib_data.list_head)); INIT_LIST_HEAD(&(o_ctrl->i2c_mode_data.list_head)); + INIT_LIST_HEAD(&(o_ctrl->i2c_gyro_data.list_head)); mutex_init(&(o_ctrl->ois_mutex)); rc = cam_ois_driver_soc_init(o_ctrl); if (rc) { 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 61abd92b9222..45ec896baa48 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -148,6 +148,7 @@ struct cam_ois_ctrl_t { struct i2c_settings_array i2c_calib_data; struct i2c_settings_array i2c_postcalib_data; struct i2c_settings_array i2c_mode_data; + struct i2c_settings_array i2c_gyro_data; struct i2c_settings_array i2c_time_data; enum msm_camera_device_type_t ois_device_type; enum cam_ois_state cam_ois_state; 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 863991792102..b6678389397e 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 @@ -177,7 +177,8 @@ enum cam_ois_packet_opcodes { 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_QTIMER + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON_QTIMER, + CAM_OIS_PACKET_OPCODE_OIS_GYRO_OFFSET }; enum msm_bus_perf_setting { From 8ee27a6541d1056cff736aa943fe651e7773e3e3 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 26 Apr 2022 11:38:33 +0800 Subject: [PATCH 57/86] camera: ois: change aw86006 log output [detail] It is not fatal error log, change to info log. Change-Id: I0327774eb2de7a0115b6de3cde00584e25208aa4 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2252851 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Shuo Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index 73a603c23ecb..b54e2ea63cf6 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -467,7 +467,7 @@ static int aw86006_soc_flash_write_check(struct cam_ois_ctrl_t *o_ctrl, if (ret == 0) break; - AW_LOGE("memcmp error!, loop: %d", loop); + AW_LOGI("memcmp error, try again, loop: %d", loop); } while ((++loop) < AW_FLASH_WRITE_ERROR_LOOP); if (loop >= AW_FLASH_WRITE_ERROR_LOOP) return OIS_ERROR; @@ -533,7 +533,7 @@ static int aw86006_soc_flash_erase_check(struct cam_ois_ctrl_t *o_ctrl, if (ret == 0) break; - AW_LOGE("memcmp error!, loop: %d", loop); + AW_LOGI("memcmp error, try again, loop: %d", loop); } while ((++loop) < AW_FLASH_ERASE_ERROR_LOOP); if (loop >= AW_FLASH_ERASE_ERROR_LOOP) return OIS_ERROR; From 89e10ac423069dca3e5d399ba2692e0675be03ce Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Fri, 29 Apr 2022 18:15:05 +0800 Subject: [PATCH 58/86] camera: ois: modify flash erase len reduce flash erase len. avoid gyro gain is erased when use erase node. Change-Id: Ie2b684bacfda850723ca309d5bd534ffde8e9ff0 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2256883 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index b5cc9b2bef02..fd732b6a0fc4 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -77,7 +77,7 @@ #define AW_FLASH_BASE_ADDR (0x01000000) #define AW_FLASH_APP_ADDR (0x01002000) #define AW_FLASH_MOVE_LENGTH (AW_FLASH_APP_ADDR - AW_FLASH_BASE_ADDR) -#define AW_FLASH_FULL_SIZE (0x10000) +#define AW_FLASH_FULL_SIZE (0xB000) #define AW_FLASH_TOP_ADDR (AW_FLASH_BASE_ADDR + AW_FLASH_FULL_SIZE) #define AW_FLASH_ERASE_LEN (512) #define AW_FLASH_WRITE_LEN (64) From eb0fb12d7fc0d0ab330393dd122cba4cca650c3d Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Thu, 28 Apr 2022 14:28:31 +0800 Subject: [PATCH 59/86] modify gyro test in kernel test cmd: gyro test: echo 1 >/sys/class/aw86006_ois/gyro_offset_cali Change-Id: I3bec3a586bc71d79fe41d732d043b78585e3930c Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2255285 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_ois/cam_ois_aw86006.c | 275 ++++++++++++++---- .../cam_ois/cam_ois_aw86006.h | 4 + 2 files changed, 218 insertions(+), 61 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index b54e2ea63cf6..b4e47d1afb4d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -1832,30 +1832,123 @@ err_exit: return ret; } +static int aw86006_raw_data_check(uint8_t *pdata, uint8_t size) +{ + uint8_t cnt = 0; + + while (cnt < size) { + if (pdata != NULL && *pdata != 0xff) + break; + + pdata++; + cnt++; + } + + if (cnt == size) + return OIS_ERROR; + + return OIS_SUCCESS; +} + +static int aw86006_accelgyro_dift_raw_data_check(struct cam_ois_ctrl_t *o_ctrl) +{ + uint8_t dift_val[12] = { 0 }; + int ret = 0; + + ois_block_read_addr8_data8(o_ctrl, 0xf84c, CAMERA_SENSOR_I2C_TYPE_WORD, + dift_val, 12); + ret = aw86006_raw_data_check(dift_val, + sizeof(dift_val)/sizeof(dift_val[0])); + if (ret < 0) { + AW_LOGE("accelgyro_dift raw data is all 0xff\n"); + return OIS_ERROR; + } + + return OIS_SUCCESS; +} + static int aw86006_get_accelgyro_dift(struct cam_ois_ctrl_t *o_ctrl, - struct accelgyro_dift ag_dift) + struct accelgyro_dift *ag_dift) { uint8_t dift_val[12] = { 0 }; ois_block_read_addr8_data8(o_ctrl, 0xf84c, CAMERA_SENSOR_I2C_TYPE_WORD, dift_val, 12); - ag_dift.gyro_dift[AXIS_X] = (dift_val[1] << 8) | dift_val[0]; - ag_dift.gyro_dift[AXIS_Y] = (dift_val[3] << 8) | dift_val[2]; - ag_dift.gyro_dift[AXIS_Z] = (dift_val[5] << 8) | dift_val[4]; + ag_dift->gyro_dift[AXIS_X] = (int16_t)((dift_val[1] << 8) | dift_val[0]); + ag_dift->gyro_dift[AXIS_Y] = (int16_t)((dift_val[3] << 8) | dift_val[2]); + ag_dift->gyro_dift[AXIS_Z] = (int16_t)((dift_val[5] << 8) | dift_val[4]); - ag_dift.accel_dift[AXIS_X] = (dift_val[7] << 8) | dift_val[6]; - ag_dift.accel_dift[AXIS_Y] = (dift_val[9] << 8) | dift_val[8]; - ag_dift.accel_dift[AXIS_Z] = (dift_val[11] << 8) | dift_val[10]; + ag_dift->accel_dift[AXIS_X] = (int16_t)((dift_val[7] << 8) | dift_val[6]); + ag_dift->accel_dift[AXIS_Y] = (int16_t)((dift_val[9] << 8) | dift_val[8]); + ag_dift->accel_dift[AXIS_Z] = (int16_t)((dift_val[11] << 8) | dift_val[10]); - AW_LOGI("gyro_dift: 0x%04x 0x%04x 0x%04x", ag_dift.gyro_dift[AXIS_X], - ag_dift.gyro_dift[AXIS_Y], - ag_dift.gyro_dift[AXIS_Z]); + AW_LOGI("gyro_dift: 0x%hx(%d) 0x%hx(%d) 0x%hx(%d)", + ag_dift->gyro_dift[AXIS_X], ag_dift->gyro_dift[AXIS_X], + ag_dift->gyro_dift[AXIS_Y], ag_dift->gyro_dift[AXIS_Y], + ag_dift->gyro_dift[AXIS_Z], ag_dift->gyro_dift[AXIS_Z]); - AW_LOGI("accel_dift: 0x%04x 0x%04x 0x%04x", ag_dift.accel_dift[AXIS_X], - ag_dift.accel_dift[AXIS_Y], - ag_dift.accel_dift[AXIS_Z]); - return 0; + AW_LOGI("accel_dift: 0x%hx(%d) 0x%hx(%d) 0x%hx(%d)", + ag_dift->accel_dift[AXIS_X], ag_dift->accel_dift[AXIS_X], + ag_dift->accel_dift[AXIS_Y], ag_dift->accel_dift[AXIS_Y], + ag_dift->accel_dift[AXIS_Z], ag_dift->accel_dift[AXIS_Z]); + + /* check gyro x/y dift */ + if(CHECK_DIFF(ag_dift->gyro_dift[AXIS_X], AW_GYROACCEL_DIFT_LIMIT) > 0) { + AW_LOGE("gyro_dift_x error!!"); + return OIS_ERROR; + } + if(CHECK_DIFF(ag_dift->gyro_dift[AXIS_Y], AW_GYROACCEL_DIFT_LIMIT) > 0) { + AW_LOGE("gyro_dift_y error!!"); + return OIS_ERROR; + } + /* check accel x/y dift */ + if(CHECK_DIFF(ag_dift->accel_dift[AXIS_X], AW_GYROACCEL_DIFT_LIMIT) > 0) { + AW_LOGE("accel_dift_x error!!"); + return OIS_ERROR; + } + if(CHECK_DIFF(ag_dift->accel_dift[AXIS_Y], AW_GYROACCEL_DIFT_LIMIT) > 0) { + AW_LOGE("accel_dift_y error!!"); + return OIS_ERROR; + } + + return OIS_SUCCESS; +} + +static int aw86006_set_normal_mode(struct cam_ois_ctrl_t *o_ctrl) +{ + int i = 0; + uint8_t send_cmd[2] = { 0xae, 0x02 }; + uint8_t check_val = 0; + + /*unlock */ + do { + ois_block_write_addr8_data8(o_ctrl, 0xff1f, + CAMERA_SENSOR_I2C_TYPE_WORD, &send_cmd[0], 1); + ois_block_read_addr8_data8(o_ctrl, 0xff1f, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0x01) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x01) { + AW_LOGE("unlock error:, check_val: 0x%02x", check_val); + return OIS_ERROR; + } + + /* set normal mode */ + do { + ois_block_write_addr8_data8(o_ctrl, 0xff11, + CAMERA_SENSOR_I2C_TYPE_WORD, &send_cmd[1], 1); + msleep(2); + ois_block_read_addr8_data8(o_ctrl, 0xff10, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0) { + AW_LOGE("enter normal error:, check_val: 0x%02x", check_val); + return OIS_ERROR; + } + + return OIS_SUCCESS; } static ssize_t gyro_offset_cali_show(struct class *class, @@ -1865,18 +1958,19 @@ static ssize_t gyro_offset_cali_show(struct class *class, struct accelgyro_dift ag_dift = {0}; ssize_t len = 0; - aw86006_get_accelgyro_dift(o_ctrl, ag_dift); + aw86006_get_accelgyro_dift(o_ctrl, &ag_dift); len += snprintf(buf + len, PAGE_SIZE - len, - "gyro_dift: 0x%04x 0x%04x 0x%04x\n", - ag_dift.gyro_dift[AXIS_X], - ag_dift.gyro_dift[AXIS_Y], - ag_dift.gyro_dift[AXIS_Z]); + "gyro_dift: 0x%hx(%d) 0x%hx(%d) 0x%hx(%d)\n", + ag_dift.gyro_dift[AXIS_X], ag_dift.gyro_dift[AXIS_X], + ag_dift.gyro_dift[AXIS_Y], ag_dift.gyro_dift[AXIS_Y], + ag_dift.gyro_dift[AXIS_Z], ag_dift.gyro_dift[AXIS_Z]); + len += snprintf(buf + len, PAGE_SIZE - len, - "accel_dift: 0x%04x 0x%04x 0x%04x\n", - ag_dift.accel_dift[AXIS_X], - ag_dift.accel_dift[AXIS_Y], - ag_dift.accel_dift[AXIS_Z]); + "accel_dift: 0x%hx(%d) 0x%hx(%d) 0x%hx(%d)\n", + ag_dift.accel_dift[AXIS_X], ag_dift.accel_dift[AXIS_X], + ag_dift.accel_dift[AXIS_Y], ag_dift.accel_dift[AXIS_Y], + ag_dift.accel_dift[AXIS_Z], ag_dift.accel_dift[AXIS_Z]); return len; } @@ -1886,10 +1980,10 @@ static ssize_t gyro_offset_cali_store(struct class *class, const char *buf, size_t count) { struct cam_ois_ctrl_t *o_ctrl = g_o_ctrl; - struct accelgyro_dift ag_dift = {0}; + struct accelgyro_dift ag_dift; int i = 0; - int ret = OIS_ERROR; - uint32_t flag = 0; + int ret = 0; + uint8_t data_buf[5] = { 0 }; uint8_t ois_mode = 0; uint8_t unlock_val[2] = { 0xa4, 0xac }; uint8_t lock_val[2] = { 0xdc, 0xd4 }; @@ -1897,62 +1991,105 @@ static ssize_t gyro_offset_cali_store(struct class *class, uint8_t exit_cmd[4] = { 0x00, 0x00, 0x00, 0x02 }; uint8_t check_val = 0; - AW_LOGI("start!"); - - ret = kstrtouint(buf, 0, &flag); - if (ret < 0) { + if (sscanf(buf, "%d", &data_buf[0]) != 1) { AW_LOGE("input para error!"); return OIS_ERROR; } + AW_LOGI("aw86006 gyro offset cali start!"); + + /* check accelgyro_diff */ + ret = aw86006_accelgyro_dift_raw_data_check(o_ctrl); + if (ret < 0) { + AW_LOGE("accelgyro_dift raw data error"); + return OIS_ERROR; + } + /* OIS off */ ois_mode = OIS_DISABLE; - ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, + do { + ois_block_write_addr8_data8(o_ctrl, REG_OIS_ENABLE, CAMERA_SENSOR_I2C_TYPE_WORD, &ois_mode, 1); - msleep(20); + ois_block_read_addr8_data8(o_ctrl, REG_OIS_ENABLE, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0x00) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x00) { + AW_LOGE("reg[0001]:0x%x != 0x00, i: %d", check_val, i); + return OIS_ERROR; + } + + /* enter normal mode */ + ret = aw86006_set_normal_mode(o_ctrl); + if (ret < 0) + return OIS_ERROR; /* unlock register */ + i = 0; do { ois_block_write_addr8_data8(o_ctrl, 0xf20f, CAMERA_SENSOR_I2C_TYPE_WORD, &unlock_val[0], 1); - msleep(20); ois_block_read_addr8_data8(o_ctrl, 0xf20f, CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); - i++; - } while ((check_val != 1) && (i < (50 * AW_ERROR_LOOP))); - if (check_val != 1) { + } while ((check_val != 0x01) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x01) { AW_LOGE("reg[f20f]:0x%x != 0x01, i: %d", check_val, i); return OIS_ERROR; } + /* unlock register */ i = 0; do { ois_block_write_addr8_data8(o_ctrl, 0xf8ff, CAMERA_SENSOR_I2C_TYPE_WORD, &unlock_val[1], 1); - msleep(20); ois_block_read_addr8_data8(o_ctrl, 0xf8ff, CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); - i++; - } while ((check_val != 1) && (i < (50 * AW_ERROR_LOOP))); - if (check_val != 1) { + } while ((check_val != 0x01) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x01) { AW_LOGE("reg[f8ff]:0x%x != 0x01, i: %d", check_val, i); return OIS_ERROR; } - /* Read the data in the flash into the register */ + + /* Read the data in the flash into the register, trigger_cmd[0]: 0x01 */ ois_block_write_addr8_data8(o_ctrl, 0xf8e4, CAMERA_SENSOR_I2C_TYPE_WORD, &trigger_cmd[0], 1); msleep(5); /* delay 5ms at least */ - /* Select the gyroscope zero drift calibration function */ + /* Select the gyroscope zero drift calibration function, trigger_cmd[1]: 0x02 */ ois_block_write_addr8_data8(o_ctrl, 0xf200, CAMERA_SENSOR_I2C_TYPE_WORD, &trigger_cmd[1], 1); - /* Enter mass production test mode */ - ois_block_write_addr8_data8(o_ctrl, 0xf203, CAMERA_SENSOR_I2C_TYPE_WORD, - &trigger_cmd[2], 1); - /* Trigger zero drift calibration of gyroscope */ - ois_block_write_addr8_data8(o_ctrl, 0xf202, CAMERA_SENSOR_I2C_TYPE_WORD, - &trigger_cmd[3], 1); - msleep(2000); /* delay 2s at least */ + + /* Enter mass production test mode, trigger_cmd[2]: 0x01 */ + i = 0; + do { + ois_block_write_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &trigger_cmd[2], 1); + ois_block_read_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0x01) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x01) { + AW_LOGE("reg[f203]:0x%x != 0x01, i: %d", check_val, i); + return OIS_ERROR; + } + + /* Trigger zero drift calibration of gyroscope, trigger_cmd[3]:0x01 */ + i = 0; + do { + ois_block_write_addr8_data8(o_ctrl, 0xf202, + CAMERA_SENSOR_I2C_TYPE_WORD, &trigger_cmd[3], 1); + ois_block_read_addr8_data8(o_ctrl, 0xf201, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0x11) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x11) { + AW_LOGE("reg[f201]:0x%x != 0x11, i: %d", check_val, i); + return OIS_ERROR; + } + + msleep(1000); /* delay 1s at least */ /* Check if the calibration is complete */ i = 0; @@ -1960,22 +2097,37 @@ static ssize_t gyro_offset_cali_store(struct class *class, ois_block_read_addr8_data8(o_ctrl, 0xf201, CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); msleep(20); - i++; - } while ((check_val != 0x21) && (i < (50 * AW_ERROR_LOOP))); + } while ((check_val != 0x21) && (i++ < AW_ERROR_LOOP)); + if (check_val != 0x21) { AW_LOGE("reg[f201]:0x%x != 0x21, i: %d", check_val, i); return OIS_ERROR; } + /* Exit calibration mode */ ois_block_write_addr8_data8(o_ctrl, 0xf200, CAMERA_SENSOR_I2C_TYPE_WORD, &exit_cmd[0], 1); - ois_block_write_addr8_data8(o_ctrl, 0xf202, CAMERA_SENSOR_I2C_TYPE_WORD, - &exit_cmd[1], 1); - ois_block_write_addr8_data8(o_ctrl, 0xf203, CAMERA_SENSOR_I2C_TYPE_WORD, - &exit_cmd[2], 1); - /* Data update to flash */ + + i = 0; + do { + /* exit_cmd[2]:0x00 */ + ois_block_write_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &exit_cmd[2], 1); + ois_block_read_addr8_data8(o_ctrl, 0xf203, + CAMERA_SENSOR_I2C_TYPE_WORD, &check_val, 1); + } while ((check_val != 0x00) && (i++ < AW_ERROR_LOOP)); + + if (check_val != 0x00) { + AW_LOGE("reg[f203]:0x%x != 0, i: %d", check_val, i); + return OIS_ERROR; + } + + /* Data update to flash, exit_cmd[3]: 0x02 */ ois_block_write_addr8_data8(o_ctrl, 0xf8e4, CAMERA_SENSOR_I2C_TYPE_WORD, &exit_cmd[3], 1); + + msleep(20 * 2); /* 2: two sector */ + /* Lock register */ ois_block_write_addr8_data8(o_ctrl, 0xf8ff, CAMERA_SENSOR_I2C_TYPE_WORD, &lock_val[0], 1); @@ -1983,11 +2135,12 @@ static ssize_t gyro_offset_cali_store(struct class *class, &lock_val[1], 1); /* Read the zero drift value of the three-axis angular velocity and - * acceleration of the gyroscope - */ - aw86006_get_accelgyro_dift(o_ctrl, ag_dift); - - AW_LOGI("aw86006 gyro offset cali success!"); + * acceleration of the gyroscope */ + ret = aw86006_get_accelgyro_dift(o_ctrl, &ag_dift); + if (ret < 0) + AW_LOGE("aw86006 gyro offset cali error!"); + else + AW_LOGI("aw86006 gyro offset cali ok!"); return count; } diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index fd732b6a0fc4..5e5128e47fe2 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -96,6 +96,10 @@ #define AW_FW_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_MOVE_LENGTH + 8) #define AW_ARRAY_SHIFT_UPDATE_FLAG (AW_FW_SHIFT_UPDATE_FLAG - AW_FLASH_MOVE_LENGTH) +/* gyro and hall test */ +#define AW_GYROACCEL_DIFT_LIMIT 5000 +#define CHECK_DIFF(x, y) ((x > 0) ? (x - y) : (-x - y)) + /* SOC */ enum soc_status { SOC_OK = 0, From 38d2fda173205c10c5ed30427f3a17f1d3e7ead5 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Mon, 9 May 2022 18:09:20 +0800 Subject: [PATCH 60/86] camera: ois: add aw86006 active eis [detail] aw86006 add active eis Change-Id: I80b988becb9a47910251f9e80ebf0e40dbd856ac Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2263679 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Reviewed-by: XiaoFeng Wang Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 137 ++++++++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 136 +++++++++++++++-- .../cam_sensor_module/cam_ois/cam_ois_dev.h | 11 ++ .../cam_sensor_utils/cam_sensor_cmn_header.h | 1 + 4 files changed, 276 insertions(+), 9 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 8154c7695d67..2c5b66db9e67 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -116,6 +116,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->is_video_mode = false; + o_ctrl->is_need_eis_data = false; o_ctrl->q_timer_cnt = QTIMER_SAMPLE_TIME*10*2; o_ctrl->mono_timestamp = 0; @@ -289,6 +291,13 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, "Failed in Applying i2c wrt settings"); return rc; } + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) { + if (i2c_list->i2c_settings.reg_setting[0].reg_addr == AW86006_PACKET_ENABLE && + i2c_list->i2c_settings.reg_setting[0].reg_data == 0x01) + o_ctrl->is_video_mode = true; + else + o_ctrl->is_video_mode = false; + } } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) { rc = camera_io_dev_write_continuous( &(o_ctrl->io_master_info), @@ -938,6 +947,9 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) o_ctrl->cam_ois_state); return rc; } + + o_ctrl->is_need_eis_data = false; + offset = (uint32_t *)&csl_packet->payload; offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t)); cmd_desc = (struct cam_cmd_buf_desc *)(offset); @@ -1361,6 +1373,131 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) } break; } + case CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_AW86006: { + 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; + uint32_t read_length = 0; + unsigned long rem_jiffies = 0; + + o_ctrl->is_need_eis_data = true; + + 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_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 (read_length > buff_length || buff_length < RING_BUFFER_LEN) { + 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; + } + + rem_jiffies = wait_for_completion_timeout(&o_ctrl->ois_data_complete, + msecs_to_jiffies(120)); + if (rem_jiffies == 0) { + CAM_ERR(CAM_OIS, "Wait ois data completion timeout 120 ms"); + delete_request(&i2c_read_settings); + return -ETIMEDOUT; + } + + mutex_lock(&(o_ctrl->vsync_mutex)); + memcpy((void *)timestampBuf, (void *)&o_ctrl->prev_timestamp, sizeof(uint64_t)); + + if (o_ctrl->ring_buff_size <= buff_length) + memcpy((void *)read_buff, (void *)o_ctrl->ring_buff, o_ctrl->ring_buff_size); + else + memcpy((void *)read_buff, (void *)o_ctrl->ring_buff, buff_length); + + mutex_unlock(&(o_ctrl->vsync_mutex)); + } + } + rc = delete_request(&i2c_read_settings); + if (rc < 0) { + CAM_ERR(CAM_OIS, + "Failed in deleting the read settings"); + return rc; + } + 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; diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index f19832eaa824..63c507a2993d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -296,6 +296,105 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client) return 0; } +static irqreturn_t cam_aw86006_ois_vsync_irq_thread(int irq, void *data) +{ + struct cam_ois_ctrl_t *o_ctrl = data; + int rc = -EINVAL, handled = IRQ_NONE, sample_cnt = 0, delay_time = 0; + uint64_t mono_time_ns; + struct timespec64 ts; + uint8_t *read_buff; + uint32_t k, read_len; + + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "Invalid Args"); + return IRQ_NONE; + } + + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + CAM_WARN(CAM_OIS, "Not in right state to read Eis data: %d", o_ctrl->cam_ois_state); + return IRQ_NONE; + } + + if (o_ctrl->is_video_mode == false || + o_ctrl->is_need_eis_data == false) { + CAM_DBG(CAM_OIS, "No need to read Eis data: %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data); + return IRQ_NONE; + } + + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { + CAM_WARN(CAM_OIS, "try to get mutex fail, skip this irq"); + return IRQ_NONE; + } + + ktime_get_boottime_ts64(&ts); + mono_time_ns = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec); + + CAM_DBG(CAM_OIS, "aw86006 ois vsync sof mono timestamp is %lld", mono_time_ns); + + o_ctrl->prev_timestamp = o_ctrl->curr_timestamp; + o_ctrl->curr_timestamp = mono_time_ns; + + // when the first vsync arrived, return + if (o_ctrl->is_first_vsync) { + o_ctrl->is_first_vsync = 0; + rc = -EINVAL; + goto release_mutex; + } + + memset(o_ctrl->ring_buff, 0, o_ctrl->ring_buff_size); + read_buff = o_ctrl->ring_buff; + + for (k = 0; k < RING_BUFFER_LEN/READ_BYTE + 1; k++) { + if (k == RING_BUFFER_LEN/READ_BYTE) + read_len = RING_BUFFER_LEN%READ_BYTE; + else + read_len = READ_BYTE; + + if (read_len == 0) { + CAM_WARN(CAM_OIS, "read length is 0, break loop read"); + break; + } + + rc = camera_io_dev_ois_read_seq( + &o_ctrl->io_master_info, + AW86006_PACKET_ADDR, + read_buff + k*READ_BYTE, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_BYTE, + read_len); + + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read ois data: %d", rc); + goto release_mutex; + } + } + + sample_cnt = read_buff[0]; + delay_time = read_buff[1]; + + CAM_DBG(CAM_OIS,"sample_cnt = %d, delay_time = %d (100 us)", sample_cnt, delay_time); + + if (sample_cnt == 0 || sample_cnt > AW86006_MAX_SAMPLE) { + CAM_WARN(CAM_OIS,"sample_cnt %d is invalid, skip the data", sample_cnt); + rc = -EINVAL; + goto release_mutex; + } + +release_mutex: + if (rc < 0) { + memset(o_ctrl->ring_buff, 0, o_ctrl->ring_buff_size); + handled = IRQ_NONE; + } else + handled = IRQ_HANDLED; + + mutex_unlock(&(o_ctrl->vsync_mutex)); + + if (rc >= 0) + complete(&o_ctrl->ois_data_complete); + + return handled; +} + static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) { struct cam_ois_ctrl_t *o_ctrl = data; @@ -463,11 +562,16 @@ static int cam_ois_component_bind(struct device *dev, o_ctrl->soc_info.dev_name = pdev->name; o_ctrl->ois_device_type = MSM_CAMERA_PLATFORM_DEVICE; - o_ctrl->ois_data_size = PACKET_BYTE*MAX_PACKET; + o_ctrl->ring_buff_size = RING_BUFFER_LEN; + o_ctrl->ring_buff = kzalloc(o_ctrl->ring_buff_size, GFP_KERNEL); + if (!o_ctrl->ring_buff) + goto free_o_ctrl; + + o_ctrl->ois_data_size = PACKET_BYTE*MAX_PACKET; o_ctrl->ois_data = kzalloc(o_ctrl->ois_data_size, GFP_KERNEL); if (!o_ctrl->ois_data) - goto free_o_ctrl; + goto free_ring_buff; o_ctrl->io_master_info.master_type = CCI_MASTER; o_ctrl->io_master_info.cci_client = kzalloc( @@ -524,13 +628,24 @@ static int cam_ois_component_bind(struct device *dev, if (o_ctrl->vsync_irq > 0) { CAM_DBG(CAM_OIS, "get ois-vsync irq: %d", o_ctrl->vsync_irq); - rc = devm_request_threaded_irq(dev, - o_ctrl->vsync_irq, - NULL, - cam_ois_vsync_irq_thread, - (IRQF_TRIGGER_RISING | IRQF_ONESHOT), - "ois-vsync-irq", - o_ctrl); + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "aw86006")) { + rc = devm_request_threaded_irq(dev, + o_ctrl->vsync_irq, + NULL, + cam_aw86006_ois_vsync_irq_thread, + (IRQF_TRIGGER_RISING | IRQF_ONESHOT), + "aw86006-vsync-irq", + o_ctrl); + } else { + rc = devm_request_threaded_irq(dev, + o_ctrl->vsync_irq, + NULL, + cam_ois_vsync_irq_thread, + (IRQF_TRIGGER_RISING | IRQF_ONESHOT), + "ois-vsync-irq", + o_ctrl); + } + if (rc != 0) CAM_ERR(CAM_OIS, "failed: to request ois-vsync IRQ %d, rc %d", o_ctrl->vsync_irq, rc); else @@ -549,6 +664,8 @@ free_cci_client: kfree(o_ctrl->io_master_info.cci_client); free_ois_data: kfree(o_ctrl->ois_data); +free_ring_buff: + kfree(o_ctrl->ring_buff); free_o_ctrl: kfree(o_ctrl); return rc; @@ -590,6 +707,7 @@ static void cam_ois_component_unbind(struct device *dev, kfree(o_ctrl->soc_info.soc_private); kfree(o_ctrl->io_master_info.cci_client); kfree(o_ctrl->ois_data); + kfree(o_ctrl->ring_buff); platform_set_drvdata(pdev, NULL); v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL); kfree(o_ctrl); 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 45ec896baa48..9427cbff4623 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -37,6 +37,13 @@ #define QTIMER_SAMPLE_TIME 2 #define QTIMER_MAX_SAMPLE 20 +/* AW86006 EIS */ +#define RING_BUFFER_LEN 42 +#define AW86006_PACKET_ENABLE 0x0003 +#define AW86006_PACKET_ADDR 0x0006 +#define AW86006_MAX_SAMPLE 10 + + enum cam_ois_state { CAM_OIS_INIT, CAM_OIS_ACQUIRE, @@ -179,6 +186,10 @@ struct cam_ois_ctrl_t { struct work_struct aw_fw_update_work; struct mutex aw_ois_mutex; struct awrw_ctrl *awrw_ctrl; + uint8_t *ring_buff; + int ring_buff_size; + bool is_video_mode; + bool is_need_eis_data; }; /** 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 b6678389397e..13131a75a94d 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 @@ -178,6 +178,7 @@ enum cam_ois_packet_opcodes { CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_ROHM, CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON, CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_DONGWOON_QTIMER, + CAM_OIS_PACKET_OPCODE_ACTIVE_OIS_AW86006, CAM_OIS_PACKET_OPCODE_OIS_GYRO_OFFSET }; From e7b5115b4d18afac165b8dcd5ef215a647a4e5a7 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Sat, 28 May 2022 15:21:07 +0800 Subject: [PATCH 61/86] camera: distinguish sensor version distinguish sensor version by read sensor version address, and apply extra setting when sensor version is 0x02. Change-Id: I9d0fc6eee906e345d4ee3a67ed26c8ed3517f8e7 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2282942 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_io/cam_sensor_io.c | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c index 38c64555b29f..3d8d48f295df 100644 --- a/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c +++ b/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.c @@ -6,6 +6,27 @@ #include "cam_sensor_io.h" #include "cam_sensor_i2c.h" +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + +#define SPECIAL_SENSOR_ID 0x5041 +#define SPECIAL_SENSOR_ADDR_ID 0x300B +#define SPECIAL_SENSOR_ADDR_VERSION 0x900E +#define SPECIAL_SENSOR_IIC_ADDR 0x10 + +static uint32_t s_r900e_val = 0; + +struct cam_sensor_i2c_reg_array special_on_write_settings = {0x0100, 0x01, 0x05, 0xFF}; +struct cam_sensor_i2c_reg_array special_off_write_settings = {0x0100, 0x00, 0x00, 0xFF}; + +struct cam_sensor_i2c_reg_array special_streamon_write_settings[] = +{ + {0x7278, 0x00, 0x00, 0xFF}, + {0x727a, 0x01, 0x00, 0xFF}, + {0x7280, 0x07, 0x00, 0xFF}, + {0x0100, 0x01, 0x00, 0xFF} +}; +#endif + int32_t camera_io_dev_poll(struct camera_io_master *io_master_info, uint32_t addr, uint16_t data, uint32_t data_mask, enum camera_sensor_i2c_type addr_type, @@ -68,14 +89,25 @@ int32_t camera_io_dev_read(struct camera_io_master *io_master_info, enum camera_sensor_i2c_type addr_type, enum camera_sensor_i2c_type data_type) { +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + int32_t retval = 0; + uint32_t r900e = 0; + struct cam_sensor_i2c_reg_setting write_setting = {0}; +#endif + if (!io_master_info) { CAM_ERR(CAM_SENSOR, "Invalid Args"); return -EINVAL; } if (io_master_info->master_type == CCI_MASTER) { +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + retval = cam_cci_i2c_read(io_master_info->cci_client, + addr, data, addr_type, data_type); +#else return cam_cci_i2c_read(io_master_info->cci_client, addr, data, addr_type, data_type); +#endif } else if (io_master_info->master_type == I2C_MASTER) { return cam_qup_i2c_read(io_master_info->client, addr, data, addr_type, data_type); @@ -87,7 +119,50 @@ int32_t camera_io_dev_read(struct camera_io_master *io_master_info, io_master_info->master_type); return -EINVAL; } + +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + if (retval == 0 && + data != NULL && + *data == SPECIAL_SENSOR_ID && + addr == SPECIAL_SENSOR_ADDR_ID && + io_master_info->cci_client != NULL && + io_master_info->cci_client->cci_i2c_master == 0 && + io_master_info->cci_client->sid == SPECIAL_SENSOR_IIC_ADDR) + { + write_setting.size = 1; + write_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD; + write_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + write_setting.delay = 21; + write_setting.read_buff = NULL; + write_setting.read_buff_len = 0; + write_setting.reg_setting = &special_on_write_settings; + retval = cam_cci_i2c_write_table(io_master_info, &write_setting); + + retval = cam_cci_i2c_read(io_master_info->cci_client, + SPECIAL_SENSOR_ADDR_VERSION, + &r900e, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_BYTE); + + CAM_INFO(CAM_SENSOR, "retval = %d, r900e = %d", retval, r900e); + + if(retval == 0) + s_r900e_val = r900e; + + write_setting.size = 1; + write_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD; + write_setting.data_type = CAMERA_SENSOR_I2C_TYPE_BYTE; + write_setting.delay = 0; + write_setting.read_buff = NULL; + write_setting.read_buff_len = 0; + write_setting.reg_setting = &special_off_write_settings; + retval = cam_cci_i2c_write_table(io_master_info, &write_setting); + } + + return retval; +#else return 0; +#endif } int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info, @@ -143,6 +218,10 @@ int32_t camera_io_dev_ois_read_seq(struct camera_io_master *io_master_info, int32_t camera_io_dev_write(struct camera_io_master *io_master_info, struct cam_sensor_i2c_reg_setting *write_setting) { +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + int32_t retval = 0; +#endif + if (!write_setting || !io_master_info) { CAM_ERR(CAM_SENSOR, "Input parameters not valid ws: %pK ioinfo: %pK", @@ -155,6 +234,44 @@ int32_t camera_io_dev_write(struct camera_io_master *io_master_info, return -EINVAL; } +#ifdef CONFIG_CAM_DISTINGUISH_SENSOR_VERSION + if (io_master_info->cci_client != NULL && + io_master_info->cci_client->sid== SPECIAL_SENSOR_IIC_ADDR && + io_master_info->cci_client->cci_device == 1 && + io_master_info->cci_client->cci_i2c_master == 0 && + write_setting->reg_setting->reg_addr == 0x0100 && + write_setting->reg_setting->reg_data == 0x01) + { + CAM_INFO(CAM_SENSOR, "Detect stream on setting, r900e = %d", s_r900e_val); + + if (s_r900e_val == 0x02) + { + write_setting->reg_setting->reg_addr = special_streamon_write_settings[0].reg_addr; + write_setting->reg_setting->reg_data = special_streamon_write_settings[0].reg_data; + write_setting->reg_setting->delay = special_streamon_write_settings[0].delay; + write_setting->reg_setting->data_mask = special_streamon_write_settings[0].data_mask; + retval = cam_cci_i2c_write_table(io_master_info, write_setting); + + write_setting->reg_setting->reg_addr = special_streamon_write_settings[1].reg_addr; + write_setting->reg_setting->reg_data = special_streamon_write_settings[1].reg_data; + write_setting->reg_setting->delay = special_streamon_write_settings[1].delay; + write_setting->reg_setting->data_mask = special_streamon_write_settings[1].data_mask; + retval = cam_cci_i2c_write_table(io_master_info, write_setting); + + write_setting->reg_setting->reg_addr = special_streamon_write_settings[2].reg_addr; + write_setting->reg_setting->reg_data = special_streamon_write_settings[2].reg_data; + write_setting->reg_setting->delay = special_streamon_write_settings[2].delay; + write_setting->reg_setting->data_mask = special_streamon_write_settings[2].data_mask; + retval = cam_cci_i2c_write_table(io_master_info, write_setting); + + write_setting->reg_setting->reg_addr = special_streamon_write_settings[3].reg_addr; + write_setting->reg_setting->reg_data = special_streamon_write_settings[3].reg_data; + write_setting->reg_setting->delay = special_streamon_write_settings[3].delay; + write_setting->reg_setting->data_mask = special_streamon_write_settings[3].data_mask; + } + } +#endif + if (io_master_info->master_type == CCI_MASTER) { return cam_cci_i2c_write_table(io_master_info, write_setting); From 4cd14f3235cdc5a918b7958140f13dee35aa7a1d Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 31 May 2022 15:02:46 +0800 Subject: [PATCH 62/86] camera: ois: update aw86006 driver to v0.5.0.8 [detail] Fix ois firmware repeat upgrade. Change-Id: I4339b96ef4303fe49a6b1a91e38007d15d3057b4 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2284812 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Shuo Wang Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c | 13 +++++++------ drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index b4e47d1afb4d..bd2ae0bbe4c6 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -47,7 +47,7 @@ #include "cam_packet_util.h" #include "cam_ois_aw86006.h" -#define AW86006_DRIVER_VERSION "v0.5.0.4" +#define AW86006_DRIVER_VERSION "v0.5.0.8" #define AW86006_FW_NAME "mot_aw86006.prog" const char fw_check_str[] = { 'A', 'W', 'I', 'N', 'I', 'C', 0, 0 }; @@ -1172,6 +1172,7 @@ int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw) { int ret = OIS_ERROR; + int i = 0; uint8_t standby_flag = 0; AW_LOGI("enter"); @@ -1191,10 +1192,11 @@ int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, } mdelay(AW_RESET_DELAY); /* run app after reset */ /* Get standby flag */ - ret = aw86006_get_standby_flag(o_ctrl, &standby_flag); - if (ret != OIS_SUCCESS) { - AW_LOGE("get standby flag failed"); - goto err_get_standby_flg; + for (i = 0; i < AW_ERROR_LOOP; i++) { + aw86006_get_standby_flag(o_ctrl, &standby_flag); + if (standby_flag == AW_IC_STANDBY) + break; + mdelay(AW_RESET_DELAY); } if (standby_flag == AW_IC_STANDBY) { @@ -1212,7 +1214,6 @@ int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, AW_LOGE("fw update failed, ret: %d", ret); } -err_get_standby_flg: err_reset: err_fw_check: release_firmware(fw); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index 5e5128e47fe2..527153c4f8a7 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -133,8 +133,8 @@ enum soc_enum { SOC_ERASE_BLOCK_DELAY = 8, SOC_WRITE_BLOCK_HEAD = 13, SOC_WRITE_BLOCK_DELAY = 1000, /* us */ - SOC_READ_BLOCK_DELAY = 2000, /* us */ - SOC_CONNECT_DELAY = 2000, /* us */ + SOC_READ_BLOCK_DELAY = 200, /* us */ + SOC_CONNECT_DELAY = 200, /* us */ }; enum soc_flash_event { From 61ebef6832840c7ad73c6101e2ea58bbd18433a0 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Wed, 1 Jun 2022 17:08:45 +0800 Subject: [PATCH 63/86] camera: actuator: add retry when actuator apply setting failed [detail] Retry 5 times if actuator apply setting failed. Change-Id: I31a7583d8c2b0bd506a85e6f6cb4a81f82c36232 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2285973 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/cam_actuator_core.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index 3d318d1ff30f..a92aa16fed54 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -163,8 +163,17 @@ static int32_t cam_actuator_i2c_modes_util( uint32_t i, size; if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) { - rc = camera_io_dev_write(io_master_info, - &(i2c_list->i2c_settings)); + // if meet cci fail, retry 5 times, each time dealy 1.5ms. + for (i = 0; i < 5; i++) { + rc = camera_io_dev_write(io_master_info, + &(i2c_list->i2c_settings)); + + if (rc >= 0) + break; + + usleep_range(1000, 1500); + } + if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Failed to random write I2C settings: %d", From 3369bfb2b2b06b5457eae9f47e85e038b143da46 Mon Sep 17 00:00:00 2001 From: huqian4 Date: Tue, 7 Jun 2022 17:02:15 +0800 Subject: [PATCH 64/86] Tundra: Before read ois data,make sure data_ready register is 0x0001 details: Fix the camera records video, and the video is incoherent. Change-Id: I54449c94b63f550ba2d08e29caebaf747d144578 Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2291490 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Wang Liu Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 24 +++++++++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 63c507a2993d..cfb5491f9d0b 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -404,6 +404,8 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) uint8_t *read_buff; uint32_t k, read_len; uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; + uint32_t data_ready = 0xFFFF; + int i = 0; if (!o_ctrl) { CAM_ERR(CAM_OIS, "Invalid Args"); @@ -468,6 +470,28 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) memset(o_ctrl->ois_data, 0, o_ctrl->ois_data_size); read_buff = o_ctrl->ois_data; + for (i = 0; i < READ_COUNT; i++) { + rc = camera_io_dev_read( + &o_ctrl->io_master_info, + DATA_READY_ADDR, + &data_ready, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read OIS 0x70da reg rc: %d", rc); + goto release_mutex; + } + if (data_ready == DATA_READY) { + CAM_DBG(CAM_OIS, "data_ready == 0x0001 i = %d", i); + break; + } else if (data_ready != DATA_READY && i < READ_COUNT - 1) { + CAM_ERR(CAM_OIS, "data_ready != 0x0001 i = %d", i); + udelay(1000); + } else { + CAM_ERR(CAM_OIS, "data_ready check fail i = %d", i); + goto release_mutex; + } + } do { if (packet_cnt > 0 && packet_cnt < MAX_PACKET) read_buff += PACKET_BYTE; 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 9427cbff4623..28b35ec1738e 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.h @@ -28,6 +28,9 @@ #define MODE_ADDR 0x7014 #define ENABLE_ADDR 0x7015 #define PACKET_ADDR 0x70B0 +#define DATA_READY_ADDR 0x70DA +#define DATA_READY 0x0001 +#define READ_COUNT 3 #define PACKET_BYTE 62 #define MAX_PACKET 5 #define MAX_SAMPLE 30 From dfbf2d63270e125fad47c0a5f23ecd8c804db547 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 7 Jun 2022 10:35:08 +0800 Subject: [PATCH 65/86] camera: ois: modify aw86006 driver optimize firmware upgrade time from 4.5s to 3.5s aw86006 driver version v0.5.0.9 Change-Id: I0bb6963e9396d0b3fe4bc9213d18dcba326fb783 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2290795 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Reviewed-by: Reviewed-by: Zhuoran Xu Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c | 2 +- drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index bd2ae0bbe4c6..236de89b9e1a 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -47,7 +47,7 @@ #include "cam_packet_util.h" #include "cam_ois_aw86006.h" -#define AW86006_DRIVER_VERSION "v0.5.0.8" +#define AW86006_DRIVER_VERSION "v0.5.0.9" #define AW86006_FW_NAME "mot_aw86006.prog" const char fw_check_str[] = { 'A', 'W', 'I', 'N', 'I', 'C', 0, 0 }; diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index 527153c4f8a7..c302095c7a61 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -130,11 +130,11 @@ enum soc_enum { SOC_CONNECT_WRITE_LEN = 9, SOC_ERASE_WRITE_LEN = 15, SOC_READ_WRITE_LEN = 15, - SOC_ERASE_BLOCK_DELAY = 8, + SOC_ERASE_BLOCK_DELAY = 5, SOC_WRITE_BLOCK_HEAD = 13, - SOC_WRITE_BLOCK_DELAY = 1000, /* us */ + SOC_WRITE_BLOCK_DELAY = 600, /* us */ SOC_READ_BLOCK_DELAY = 200, /* us */ - SOC_CONNECT_DELAY = 200, /* us */ + SOC_CONNECT_DELAY = 100, /* us */ }; enum soc_flash_event { From 6466772790881deea0c519331d5b23b201786ac3 Mon Sep 17 00:00:00 2001 From: yangmf3 Date: Wed, 15 Jun 2022 16:51:38 +0800 Subject: [PATCH 66/86] tundra: Modify the register according to Qcom patch details: 1.refer to Qcom patch for modification,modify two registers 2.slove the signal interference problem Change-Id: I24158814dc56f6ef021b86ff384a589118cc08b4 Signed-off-by: yangmf3 Reviewed-on: https://gerrit.mot.com/2301431 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Shuo Wang Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../include/cam_csiphy_1_2_3_hwreg.h | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h index aaa8bae0b667..7dddef775129 100644 --- a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h +++ b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h @@ -376,12 +376,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = { { .lane_identifier = CPHY_LANE_0, .csiphy_data_rate_regs = { +#ifdef CONFIG_CAM_CTLE_ENABLE + {0x144, 0xB2, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0x988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +#ifdef CONFIG_CAM_CTLE_ENABLE + {0x980, 0x60, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0x980, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0x9B4, 0x08, 0x0A, CSIPHY_DEFAULT_PARAMS}, }, @@ -389,12 +399,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = { { .lane_identifier = CPHY_LANE_1, .csiphy_data_rate_regs = { +#ifdef CONFIG_CAM_CTLE_ENABLE + {0x344, 0xB2, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0xA88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +#ifdef CONFIG_CAM_CTLE_ENABLE + {0xA80, 0x60, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0xA80, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0xAB4, 0x08, 0x0A, CSIPHY_DEFAULT_PARAMS}, }, @@ -402,12 +422,22 @@ struct data_rate_settings_t data_rate_delta_table_1_2_3 = { { .lane_identifier = CPHY_LANE_2, .csiphy_data_rate_regs = { +#ifdef CONFIG_CAM_CTLE_ENABLE + {0x544, 0xB2, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0xB88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +#ifdef CONFIG_CAM_CTLE_ENABLE + {0xB80, 0x60, 0x00, + CSIPHY_DEFAULT_PARAMS}, +#else {0xB80, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, +#endif {0xBB4, 0x08, 0x0A, CSIPHY_DEFAULT_PARAMS}, }, From dd8ca877e397393df9a43978509771bbf9d7abf5 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Mon, 1 Aug 2022 10:23:39 +0800 Subject: [PATCH 67/86] camera: ois: avoid ois power down twice when download firmware failed [detail] ois will power down when received CAM_RELEASE_DEV command. Change-Id: I58a573356614670d898095772c28c873d43eb830 Signed-off-by: liuwang2 Reviewed-on: https://gerrit.mot.com/2350085 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Yongqin Wan Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_core.c | 6 +++++- 1 file changed, 5 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 2c5b66db9e67..fa84bab7c278 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -167,6 +167,8 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl) return rc; } + CAM_INFO(CAM_OIS, "OIS Power up successfully"); + rc = camera_io_init(&o_ctrl->io_master_info); if (rc) { CAM_ERR(CAM_OIS, "cci_init failed: rc: %d", rc); @@ -216,6 +218,8 @@ static int cam_ois_power_down(struct cam_ois_ctrl_t *o_ctrl) return rc; } + CAM_INFO(CAM_OIS, "OIS power down successed"); + camera_io_release(&o_ctrl->io_master_info); return rc; @@ -1680,7 +1684,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (!rc) return rc; pwr_dwn: - cam_ois_power_down(o_ctrl); + //cam_ois_power_down(o_ctrl); /* ois will pown down in CAM_RELEASE_DEV when closed camera */ return rc; } From f9409551b9e4dc6c159698e3f256495825d34231 Mon Sep 17 00:00:00 2001 From: Xiaofeng Wang Date: Tue, 26 Jul 2022 20:14:51 +0800 Subject: [PATCH 68/86] milanf: modify ois vsync irq processing flow modify ois vsync irq processing flow same with aw86006, avoid interrupt read conflict with firmware download Change-Id: I397e33312d42b91fdb2eb9b04ae96d7a482dfffa Signed-off-by: Xiaofeng Wang Reviewed-on: https://gerrit.mot.com/2345102 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Shuo Wang Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 9 +++++ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 38 ++++--------------- 2 files changed, 16 insertions(+), 31 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 fa84bab7c278..72e3a6e27de0 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -302,6 +302,13 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, else o_ctrl->is_video_mode = false; } + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "dw9781c")) { + if (i2c_list->i2c_settings.reg_setting[0].reg_addr == 0x7014 && + i2c_list->i2c_settings.reg_setting[0].reg_data == 0x00) + o_ctrl->is_video_mode = true; + else + o_ctrl->is_video_mode = false; + } } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) { rc = camera_io_dev_write_continuous( &(o_ctrl->io_master_info), @@ -1241,6 +1248,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) uint32_t size; unsigned long rem_jiffies = 0; + o_ctrl->is_need_eis_data = true; + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { rc = -EINVAL; CAM_WARN(CAM_OIS, diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index cfb5491f9d0b..d3c56aa01f35 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -403,7 +403,6 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) struct timespec64 ts; uint8_t *read_buff; uint32_t k, read_len; - uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; uint32_t data_ready = 0xFFFF; int i = 0; @@ -412,43 +411,20 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) return IRQ_NONE; } - if (!mutex_trylock(&o_ctrl->vsync_mutex)) { - CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); - return IRQ_NONE; - } - if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state); goto release_mutex; } - rc = camera_io_dev_read( - &o_ctrl->io_master_info, - MODE_ADDR, - &mode_val, - CAMERA_SENSOR_I2C_TYPE_WORD, - CAMERA_SENSOR_I2C_TYPE_WORD); - if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to read OIS 0x7014 reg rc: %d", rc); - goto release_mutex; + if(o_ctrl->is_video_mode == false || + o_ctrl->is_need_eis_data == false) { + CAM_WARN(CAM_OIS, "No need to read Eis data %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data); + return IRQ_NONE; } - rc = camera_io_dev_read( - &o_ctrl->io_master_info, - ENABLE_ADDR, - &enable_val, - CAMERA_SENSOR_I2C_TYPE_WORD, - CAMERA_SENSOR_I2C_TYPE_WORD); - if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to read OIS 0x7015 reg rc: %d", rc); - goto release_mutex; - } - - CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); - - if (mode_val != 0 || enable_val != 0) { - CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); - goto release_mutex; + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { + CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); + return IRQ_NONE; } ktime_get_boottime_ts64(&ts); From f7a4e1ba180489a3c4f72a516f787e16ecfe29c1 Mon Sep 17 00:00:00 2001 From: HQ Cam LiJunyu Date: Wed, 3 Aug 2022 14:34:17 +0800 Subject: [PATCH 69/86] penang: Actuator noise reduction detalis: Add MOT_DEVICE_PENANG for workaround, follow rhodec Change-Id: I29ce4af36ebc4024f3152a0f7215e117a6ead3c2 Reviewed-on: https://gerrit.mot.com/2352675 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Zhuoran Xu Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 72f9f4a4909f..8cae9dbba8af 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -65,6 +65,7 @@ typedef enum { MOT_DEVICE_CORFUR, MOT_DEVICE_RHODEC, MOT_DEVICE_RHODEI, + MOT_DEVICE_PENANG, MOT_DEVICE_NUM, } mot_dev_type; @@ -499,6 +500,32 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, + { + .dev_type = MOT_DEVICE_PENANG, + .actuator_num = 1, + .dev_name = "penang", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_DW9800V, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x1, + .regulator_list = {"camera_ldo_dovdd", "pm6125_l21"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + }, + }, + }, + }; static uint32_t mot_device_index = MOT_DEVICE_NUM; From fbdc3222fbe967cd4eb1e7821a22a4b20d2c0f10 Mon Sep 17 00:00:00 2001 From: HQ Cam LiJunyu Date: Tue, 27 Sep 2022 14:54:49 +0800 Subject: [PATCH 70/86] penang: Adjust actuator noise reduction details: Add drive node Modify the motor voltage value Change-Id: I8abcd884a33e4326ea1066a1ca810e7e23ba3e67 Signed-off-by: HQ Cam LiJunyu Reviewed-on: https://gerrit.mot.com/2392270 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Shuo Wang Reviewed-by: Wang Liu Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 8cae9dbba8af..e8de4855efc4 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -44,6 +44,7 @@ typedef enum { MOT_ACTUATOR_GT9772, MOT_ACTUATOR_DW9714, MOT_ACTUATOR_DW9800V, + MOT_ACTUATOR_PENANG_DW9800V, MOT_ACTUATOR_NUM, } mot_actuator_type; @@ -221,6 +222,21 @@ static struct cam_sensor_i2c_reg_setting mot_dw9800v_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; +/*Register settings of Device of Penang DW9800V*/ +static struct cam_sensor_i2c_reg_array mot_penang_dw9800v_init_setting[] ={ + {0x02, 0x02, 0}, + {0x06, 0x80, 0}, + {0x07, 0x62, 0}, + {0x03, 0x00, 0}, +}; + +static struct cam_sensor_i2c_reg_setting mot_penang_dw9800v_init_settings = { + .reg_setting = mot_penang_dw9800v_init_setting, + .size = ARRAY_SIZE(mot_penang_dw9800v_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + /*Register settings of all supported actuator types*/ static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { //MUST be sorted as definition order in above structure: mot_actuator_type @@ -228,6 +244,7 @@ static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, {&mot_dw9714_init_settings, &mot_dw9714_dac_settings}, {&mot_dw9800v_init_settings, &mot_dw9800v_dac_settings}, + {&mot_penang_dw9800v_init_settings}, }; static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { @@ -506,7 +523,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .dev_name = "penang", .actuator_info = { [0] = { - .actuator_type = MOT_ACTUATOR_DW9800V, + .actuator_type = MOT_ACTUATOR_PENANG_DW9800V, .dac_pos = 0, .init_pos = 512, .cci_addr = 0x0c, @@ -514,14 +531,6 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .cci_master = 0x1, .regulator_list = {"camera_ldo_dovdd", "pm6125_l21"}, .regulator_volt_uv = {1800000, 2800000}, - .launch_lens = { - .launch_lens_needed = true, - .launch_lens_step = { - {200, 100}, - {100, 60}, - {50, 30}, - }, - }, }, }, }, @@ -951,13 +960,21 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (consumers == 0) { /*Just move lens when camera off and before first vibrating*/ /*use launch_lens to move lens step-by-step,reduce TICK noise*/ - if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { - ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); - }else { - ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); - /*delay 10~12ms to wait lens move to specify location*/ - usleep_range(10000, 12000); + if(mot_device_index == MOT_DEVICE_PENANG) + { + ret = 0; + CAM_WARN(CAM_ACTUATOR, "Device is Penang 5G,skip move lens !!!!"); } + else { + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { + ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); + }else { + ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*delay 10~12ms to wait lens move to specify location*/ + usleep_range(10000, 12000); + } + } + if (ret == 0) { CAM_WARN(CAM_ACTUATOR, "actuator is safe now, safe_dac_pos:%d, please start vibrating.", mot_actuator_runtime[index].safe_dac_pos); From 7a9b63f36cfa65c2e644271706e7f06784c35819 Mon Sep 17 00:00:00 2001 From: HQ Cam LiJunyu Date: Sat, 15 Oct 2022 13:38:12 +0800 Subject: [PATCH 71/86] penang: Adjust actuator noise reduction details: Modify the limiting current of pmic to 120ma Change-Id: I684c7f24ef550fbc94ca653d242273032a80769d Signed-off-by: HQ Cam LiJunyu Reviewed-on: https://gerrit.mot.com/2404981 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index e8de4855efc4..1de7dfe77576 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -44,7 +44,6 @@ typedef enum { MOT_ACTUATOR_GT9772, MOT_ACTUATOR_DW9714, MOT_ACTUATOR_DW9800V, - MOT_ACTUATOR_PENANG_DW9800V, MOT_ACTUATOR_NUM, } mot_actuator_type; @@ -106,6 +105,8 @@ typedef struct { bool park_lens_needed; bool reset_lens_needed; mot_launch_lens launch_lens; + bool pmic_load_needed; + uint32_t regulator_load_ua[REGULATOR_NUM]; } mot_actuator_hw_info; typedef struct { @@ -222,21 +223,6 @@ static struct cam_sensor_i2c_reg_setting mot_dw9800v_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; -/*Register settings of Device of Penang DW9800V*/ -static struct cam_sensor_i2c_reg_array mot_penang_dw9800v_init_setting[] ={ - {0x02, 0x02, 0}, - {0x06, 0x80, 0}, - {0x07, 0x62, 0}, - {0x03, 0x00, 0}, -}; - -static struct cam_sensor_i2c_reg_setting mot_penang_dw9800v_init_settings = { - .reg_setting = mot_penang_dw9800v_init_setting, - .size = ARRAY_SIZE(mot_penang_dw9800v_init_setting), - .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, - .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, -}; - /*Register settings of all supported actuator types*/ static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { //MUST be sorted as definition order in above structure: mot_actuator_type @@ -244,7 +230,6 @@ static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, {&mot_dw9714_init_settings, &mot_dw9714_dac_settings}, {&mot_dw9800v_init_settings, &mot_dw9800v_dac_settings}, - {&mot_penang_dw9800v_init_settings}, }; static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { @@ -523,7 +508,7 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .dev_name = "penang", .actuator_info = { [0] = { - .actuator_type = MOT_ACTUATOR_PENANG_DW9800V, + .actuator_type = MOT_ACTUATOR_DW9800V, .dac_pos = 0, .init_pos = 512, .cci_addr = 0x0c, @@ -531,6 +516,16 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { .cci_master = 0x1, .regulator_list = {"camera_ldo_dovdd", "pm6125_l21"}, .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + .pmic_load_needed = true, + .regulator_load_ua = {120000, 120000}, }, }, }, @@ -703,6 +698,16 @@ static int mot_actuator_init_runtime(void) regulator_set_voltage(mot_actuator_runtime[i].regulators[regIdx], mot_dev_list[mot_device_index].actuator_info[i].regulator_volt_uv[regIdx], mot_dev_list[mot_device_index].actuator_info[i].regulator_volt_uv[regIdx]); + /*change current to 120ma avoid current exceeds pmic linit just for penang*/ + if(mot_dev_list[mot_device_index].actuator_info[i].pmic_load_needed == true){ + regulator_set_load(mot_actuator_runtime[i].regulators[regIdx], + mot_dev_list[mot_device_index].actuator_info[i].regulator_load_ua[regIdx]); + CAM_WARN(CAM_ACTUATOR, "REGULATOR use custom load %d !", + mot_dev_list[mot_device_index].actuator_info[i].regulator_load_ua[regIdx]); + } + else{ + CAM_DBG(CAM_ACTUATOR, "REGULATOR Use default load !"); + } } } } @@ -960,21 +965,13 @@ static int32_t mot_actuator_vib_move_lens(uint32_t index) if (consumers == 0) { /*Just move lens when camera off and before first vibrating*/ /*use launch_lens to move lens step-by-step,reduce TICK noise*/ - if(mot_device_index == MOT_DEVICE_PENANG) - { - ret = 0; - CAM_WARN(CAM_ACTUATOR, "Device is Penang 5G,skip move lens !!!!"); + if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { + ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); + }else { + ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); + /*delay 10~12ms to wait lens move to specify location*/ + usleep_range(10000, 12000); } - else { - if (mot_dev_list[mot_device_index].actuator_info[index].launch_lens.launch_lens_needed == true) { - ret = mot_actuator_launch_lens(index, mot_actuator_runtime[index].safe_dac_pos); - }else { - ret = mot_actuator_move_lens_by_dac(index, mot_actuator_runtime[index].safe_dac_pos); - /*delay 10~12ms to wait lens move to specify location*/ - usleep_range(10000, 12000); - } - } - if (ret == 0) { CAM_WARN(CAM_ACTUATOR, "actuator is safe now, safe_dac_pos:%d, please start vibrating.", mot_actuator_runtime[index].safe_dac_pos); From e55c0873bf2fd92468b3d3e7007e05a52eede2f7 Mon Sep 17 00:00:00 2001 From: Victor Toon de Araujo Date: Tue, 14 Feb 2023 15:13:26 -0300 Subject: [PATCH 72/86] Revert "(CR): milanf: modify ois vsync irq processing flow" This reverts commit ac3ba34d7de8499bc123d3218f04464227fe8c62. The commit was causing FPS drops while using ActiveEIS on Tundra, the Ioctl calls to the OIS module were returning a timeout error. Change-Id: Ia6a68f351e44a6305a8193833302966a6e99f3e1 Reviewed-on: https://gerrit.mot.com/2511883 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Miguel Nicodemus Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 9 ----- .../cam_sensor_module/cam_ois/cam_ois_dev.c | 38 +++++++++++++++---- 2 files changed, 31 insertions(+), 16 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 72e3a6e27de0..fa84bab7c278 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -302,13 +302,6 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, else o_ctrl->is_video_mode = false; } - if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "dw9781c")) { - if (i2c_list->i2c_settings.reg_setting[0].reg_addr == 0x7014 && - i2c_list->i2c_settings.reg_setting[0].reg_data == 0x00) - o_ctrl->is_video_mode = true; - else - o_ctrl->is_video_mode = false; - } } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) { rc = camera_io_dev_write_continuous( &(o_ctrl->io_master_info), @@ -1248,8 +1241,6 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) uint32_t size; unsigned long rem_jiffies = 0; - o_ctrl->is_need_eis_data = true; - if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { rc = -EINVAL; CAM_WARN(CAM_OIS, diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index d3c56aa01f35..cfb5491f9d0b 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -403,6 +403,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) struct timespec64 ts; uint8_t *read_buff; uint32_t k, read_len; + uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; uint32_t data_ready = 0xFFFF; int i = 0; @@ -411,20 +412,43 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) return IRQ_NONE; } + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { + CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); + return IRQ_NONE; + } + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state); goto release_mutex; } - if(o_ctrl->is_video_mode == false || - o_ctrl->is_need_eis_data == false) { - CAM_WARN(CAM_OIS, "No need to read Eis data %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data); - return IRQ_NONE; + rc = camera_io_dev_read( + &o_ctrl->io_master_info, + MODE_ADDR, + &mode_val, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read OIS 0x7014 reg rc: %d", rc); + goto release_mutex; } - if (!mutex_trylock(&o_ctrl->vsync_mutex)) { - CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); - return IRQ_NONE; + rc = camera_io_dev_read( + &o_ctrl->io_master_info, + ENABLE_ADDR, + &enable_val, + CAMERA_SENSOR_I2C_TYPE_WORD, + CAMERA_SENSOR_I2C_TYPE_WORD); + if (rc < 0) { + CAM_ERR(CAM_OIS, "failed to read OIS 0x7015 reg rc: %d", rc); + goto release_mutex; + } + + CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); + + if (mode_val != 0 || enable_val != 0) { + CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); + goto release_mutex; } ktime_get_boottime_ts64(&ts); From b7a390c5504ca747e21bf2089375b2372530c390 Mon Sep 17 00:00:00 2001 From: Xiaofeng Wang Date: Wed, 1 Mar 2023 15:21:17 +0800 Subject: [PATCH 73/86] Tundra: add delay at check ois data_ready https://gerrit.mot.com/#/c/2514636/ https://gerrit.mot.com/#/c/2515569/ this submit resolve CTS error, this submit cause video flick. video flick root cause is ois array 9 data sometimes is 0. add 0.4ms delay at check ois data_ready from FAE. Change-Id: I8390a64eff292e09d0c37dcaf1a996d4f409c22f Signed-off-by: Xiaofeng Wang Reviewed-on: https://gerrit.mot.com/2524567 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_ois/cam_ois_dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index cfb5491f9d0b..8037247f6920 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -483,6 +483,7 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) } if (data_ready == DATA_READY) { CAM_DBG(CAM_OIS, "data_ready == 0x0001 i = %d", i); + udelay(400); break; } else if (data_ready != DATA_READY && i < READ_COUNT - 1) { CAM_ERR(CAM_OIS, "data_ready != 0x0001 i = %d", i); From 5a991db5630f3b00475674bd766b1d63114ef14f Mon Sep 17 00:00:00 2001 From: Xiaofeng Wang Date: Sun, 19 Feb 2023 10:09:56 +0800 Subject: [PATCH 74/86] Tundra: restore ois delete submit (CR) temp submit https://gerrit.mot.com/#/c/2511883/ The root cause has been found, so restore it. Change-Id: Icb37f7d3f15f4ef4d1095e0cc9fb13d3c9068b1a Signed-off-by: Xiaofeng Wang Reviewed-on: https://gerrit.mot.com/2515569 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Wang Liu Reviewed-by: Long Cheng Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_core.c | 9 +++++ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 38 ++++--------------- 2 files changed, 16 insertions(+), 31 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 fa84bab7c278..72e3a6e27de0 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -302,6 +302,13 @@ static int cam_ois_apply_settings(struct cam_ois_ctrl_t *o_ctrl, else o_ctrl->is_video_mode = false; } + if (o_ctrl->ic_name != NULL && strstr(o_ctrl->ic_name, "dw9781c")) { + if (i2c_list->i2c_settings.reg_setting[0].reg_addr == 0x7014 && + i2c_list->i2c_settings.reg_setting[0].reg_data == 0x00) + o_ctrl->is_video_mode = true; + else + o_ctrl->is_video_mode = false; + } } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) { rc = camera_io_dev_write_continuous( &(o_ctrl->io_master_info), @@ -1241,6 +1248,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) uint32_t size; unsigned long rem_jiffies = 0; + o_ctrl->is_need_eis_data = true; + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { rc = -EINVAL; CAM_WARN(CAM_OIS, diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 8037247f6920..5526895b9fa4 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -403,7 +403,6 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) struct timespec64 ts; uint8_t *read_buff; uint32_t k, read_len; - uint32_t mode_val = 0xFFFF, enable_val = 0xFFFF; uint32_t data_ready = 0xFFFF; int i = 0; @@ -412,43 +411,20 @@ static irqreturn_t cam_ois_vsync_irq_thread(int irq, void *data) return IRQ_NONE; } - if (!mutex_trylock(&o_ctrl->vsync_mutex)) { - CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); - return IRQ_NONE; - } - if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { CAM_WARN(CAM_OIS, "Not in right state to read OIS: %d", o_ctrl->cam_ois_state); goto release_mutex; } - rc = camera_io_dev_read( - &o_ctrl->io_master_info, - MODE_ADDR, - &mode_val, - CAMERA_SENSOR_I2C_TYPE_WORD, - CAMERA_SENSOR_I2C_TYPE_WORD); - if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to read OIS 0x7014 reg rc: %d", rc); - goto release_mutex; + if(o_ctrl->is_video_mode == false || + o_ctrl->is_need_eis_data == false) { + CAM_WARN(CAM_OIS, "No need to read Eis data %d %d", o_ctrl->is_video_mode, o_ctrl->is_need_eis_data); + return IRQ_NONE; } - rc = camera_io_dev_read( - &o_ctrl->io_master_info, - ENABLE_ADDR, - &enable_val, - CAMERA_SENSOR_I2C_TYPE_WORD, - CAMERA_SENSOR_I2C_TYPE_WORD); - if (rc < 0) { - CAM_ERR(CAM_OIS, "failed to read OIS 0x7015 reg rc: %d", rc); - goto release_mutex; - } - - CAM_DBG(CAM_OIS, "mode_val = 0x%02x, enable_val = 0x%02x", mode_val, enable_val); - - if (mode_val != 0 || enable_val != 0) { - CAM_DBG(CAM_OIS, "ois is not in move mode, skip this irq"); - goto release_mutex; + if (!mutex_trylock(&o_ctrl->vsync_mutex)) { + CAM_ERR(CAM_OIS, "try lock fail, skip this irq"); + return IRQ_NONE; } ktime_get_boottime_ts64(&ts); From eaea2579ad2ee58a6b6363f243ab47f18a620de0 Mon Sep 17 00:00:00 2001 From: "tin_qiquan.zhou_tmp" Date: Wed, 12 Apr 2023 18:05:32 +0800 Subject: [PATCH 75/86] bangkk: Secondary supply flash driver ic compatible details: 1.dts add distinguish-flash-supplier= 2.ioctl query cap,distinguish flash. 3.if cci read FlashIdRegAddr is FlashId,this is sencondary,flash_supplier return 1. 4.if don't find distinguish-flash-supplier,flash_supplier is default Change-Id: Ie48452465892ea4728272634010fd5c966b68986 Signed-off-by: tin_qiquan.zhou_tmp Reviewed-on: https://gerrit.mot.com/2573829 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_flash/cam_flash_core.c | 95 +++++++++++++++++++ .../cam_flash/cam_flash_dev.c | 39 +++++++- .../cam_flash/cam_flash_dev.h | 5 +- include/uapi/camera/media/cam_sensor.h | 1 + 4 files changed, 137 insertions(+), 3 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 6c1bbaba624c..17359fd2c8d3 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -2117,3 +2117,98 @@ int cam_flash_apply_request(struct cam_req_mgr_apply_request *apply) return rc; } + +#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE +static int cam_flash_construct_power_vio_setting( + struct cam_sensor_power_ctrl_t *power_info) +{ + int rc = 0; + + power_info->power_setting_size = 2; + power_info->power_setting = + kzalloc(sizeof(struct cam_sensor_power_setting) * 2, + GFP_KERNEL); + if (!power_info->power_setting) + return -ENOMEM; + + power_info->power_setting[0].seq_type = SENSOR_VIO; + power_info->power_setting[0].seq_val = CAM_VIO; + power_info->power_setting[0].config_val = 1; + power_info->power_setting[0].delay = 2; + power_info->power_setting[1].seq_type = SENSOR_CUSTOM_GPIO1; + power_info->power_setting[1].seq_val = 0; + power_info->power_setting[1].config_val = 1; + power_info->power_setting[1].delay = 0; + + power_info->power_down_setting_size = 2; + power_info->power_down_setting = + kzalloc(sizeof(struct cam_sensor_power_setting) * 2, + GFP_KERNEL); + if (!power_info->power_down_setting) { + rc = -ENOMEM; + goto free_power_settings; + } + + power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_GPIO1; + power_info->power_down_setting[0].seq_val = 0; + power_info->power_down_setting[0].config_val = 0; + power_info->power_down_setting[0].seq_type = SENSOR_VIO; + power_info->power_down_setting[0].seq_val = CAM_VIO; + power_info->power_down_setting[0].config_val = 0; + + return rc; + +free_power_settings: + kfree(power_info->power_setting); + power_info->power_setting = NULL; + power_info->power_setting_size = 0; + return rc; +} + +int cam_flash_fill_vreg_setting(struct cam_flash_ctrl *fctrl) +{ + int rc = 0; + + rc = cam_flash_construct_power_vio_setting( + &fctrl->power_info); + if (rc) { + CAM_ERR(CAM_FLASH, "Failed Flash Power VIO Setting: rc=%d\n", rc); + return rc; + } + rc = msm_camera_fill_vreg_params(&fctrl->soc_info, + fctrl->power_info.power_setting, + fctrl->power_info.power_setting_size); + if(rc) + { + CAM_ERR(CAM_FLASH, "Failed Flash Fill Power Up Params: rc=%d\n", rc); + return rc; + } + rc = msm_camera_fill_vreg_params(&fctrl->soc_info, + fctrl->power_info.power_down_setting, + fctrl->power_info.power_down_setting_size); + if(rc) + { + CAM_ERR(CAM_FLASH, "Failed Flash Fill Power Down Params: rc=%d\n", rc); + return rc; + } + return rc; +} + +int cam_flash_fill_i2c_default_setting(struct cam_flash_ctrl *fctrl, uint32_t slave_addr) +{ + int rc = 0; + + struct cam_cmd_i2c_info i2c_info={0}; + i2c_info.slave_addr = slave_addr; + i2c_info.i2c_freq_mode = I2C_STANDARD_MODE; + + rc = cam_flash_slaveInfo_pkt_parser( + fctrl, (uint32_t *)&i2c_info, sizeof(struct cam_cmd_i2c_info)); + if (rc < 0) { + CAM_ERR(CAM_FLASH, + "Failed parsing slave info: rc: %d", + rc); + } + return rc; +} +#endif diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index 011ce8d8ecb1..6aae862ed4a5 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -141,7 +141,10 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, } case CAM_QUERY_CAP: { struct cam_flash_query_cap_info flash_cap = {0}; - +#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE + uint32_t flash_iic_supplier[3]; + uint32_t flashid=0; +#endif CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP"); flash_cap.slot_info = fctrl->soc_info.index; flash_cap.flash_type = soc_private->flash_type; @@ -159,7 +162,39 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, for (i = 0; i < fctrl->torch_num_sources; i++) flash_cap.max_current_torch[i] = soc_private->torch_max_current[i]; - +#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE + rc = of_property_read_u32_array(fctrl->of_node, "distinguish-flash-supplier", + flash_iic_supplier, 3); + if (!rc) { + CAM_DBG(CAM_FLASH, "Distinguish IIC Flash Supplier dev:0x%x addr:0x%x data:0x%x", + flash_iic_supplier[0],flash_iic_supplier[1],flash_iic_supplier[2]); + if (cam_flash_fill_vreg_setting(fctrl)){ + CAM_ERR(CAM_FLASH, "Flash Fill Vreg Failed"); + goto release_mutex; + } + if (fctrl->func_tbl.power_ops(fctrl, true)){ + CAM_ERR(CAM_FLASH, "Power Up Failed"); + goto release_mutex; + } + if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){ + CAM_ERR(CAM_FLASH, "Failed Flash Fill I2C Setting rc =%d",rc); + goto release_mutex; + } + rc = camera_io_dev_read(&(fctrl->io_master_info), + flash_iic_supplier[1],&flashid, + CAMERA_SENSOR_I2C_TYPE_BYTE, + CAMERA_SENSOR_I2C_TYPE_BYTE); + CAM_DBG(CAM_FLASH, "flashid=%d",flashid); + if ((!rc) && (flashid == flash_iic_supplier[2])) + flash_cap.flash_supplier = 1; + else + flash_cap.flash_supplier = 0; + if (fctrl->func_tbl.power_ops(fctrl, false)){ + CAM_ERR(CAM_FLASH, "Power Down Failed"); + goto release_mutex; + } + } +#endif if (copy_to_user(u64_to_user_ptr(cmd->handle), &flash_cap, sizeof(struct cam_flash_query_cap_info))) { CAM_ERR(CAM_FLASH, "Failed Copy to User"); diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h index 8f76d5e8173e..59af237869c4 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h @@ -242,7 +242,10 @@ int cam_flash_pmic_flush_request(struct cam_flash_ctrl *fctrl, enum cam_flash_flush_type, uint64_t req_id); void cam_flash_shutdown(struct cam_flash_ctrl *fctrl); int cam_flash_release_dev(struct cam_flash_ctrl *fctrl); - +#ifdef CONFIG_CAMERA_FLASH_IIC_COMPATIBLE +int cam_flash_fill_i2c_default_setting(struct cam_flash_ctrl *fctrl, uint32_t slave_addr); +int cam_flash_fill_vreg_setting(struct cam_flash_ctrl *fctrl); +#endif /** * @brief : API to register FLASH hw to platform framework. * @return struct platform_device pointer on on success, or ERR_PTR() on error. diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index 7f52004c4f85..92d6672ba37d 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -508,6 +508,7 @@ struct cam_flash_query_cap_info { __u32 max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS]; __u32 max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS]; __u32 flash_type; + __u32 flash_supplier; } __attribute__ ((packed)); #endif From 22323ff3ed00dacf8a8b5134f850ae437e6d573d Mon Sep 17 00:00:00 2001 From: "tin_minchao.wang_tmp" Date: Tue, 25 Apr 2023 17:00:39 +0800 Subject: [PATCH 76/86] bangkk: dw9784 ois bring up details: add fw download for dw9784 Change-Id: I094285bbb437e6b6c41fd8dd6edbb0ba14c4f282 Signed-off-by: tin_minchao.wang_tmp Reviewed-on: https://gerrit.mot.com/2570378 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/Makefile | 1 + .../cam_sensor_module/cam_ois/cam_ois_core.c | 56 ++- .../cam_ois/cam_ois_dw9784.c | 406 ++++++++++++++++++ 3 files changed, 451 insertions(+), 12 deletions(-) create mode 100644 drivers/cam_sensor_module/cam_ois/cam_ois_dw9784.c diff --git a/drivers/Makefile b/drivers/Makefile index 10d91f552fac..214817f9aa25 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -163,6 +163,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \ cam_sensor_module/cam_ois/cam_ois_core.o \ cam_sensor_module/cam_ois/cam_ois_soc.o \ cam_sensor_module/cam_ois/cam_ois_dw9781.o \ + cam_sensor_module/cam_ois/cam_ois_dw9784.o \ cam_sensor_module/cam_ois/cam_ois_aw86006.o \ cam_sensor_module/cam_sensor/cam_sensor_dev.o \ cam_sensor_module/cam_sensor/cam_sensor_core.o \ 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 72e3a6e27de0..82d703bc785d 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -15,9 +15,14 @@ #include "cam_common_util.h" #include "cam_packet_util.h" +#define DW9784_IF_SIZE (512) + extern int dw9781c_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); extern void dw9781_post_firmware_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); extern int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct firmware *fw); +extern int dw9784_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); +extern void dw9784_post_firmware_download(struct camera_io_master * io_master_info); +extern int dw9784_check_if_download(struct camera_io_master * io_master_info); int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -433,6 +438,13 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) return 0; } CAM_INFO(CAM_OIS, "Firmware download started."); + }else if (strstr(o_ctrl->ois_name, "dw9784")) { + if (!dw9784_check_fw_download(&(o_ctrl->io_master_info), fw->data, fw->size)) { + CAM_INFO(CAM_OIS, "Skip firmware download."); + release_firmware(fw); + return 0; + } + CAM_INFO(CAM_OIS, "Firmware download started."); } else if (strstr(o_ctrl->ois_name, "aw86006")) { mutex_lock(&o_ctrl->aw_ois_mutex); @@ -474,23 +486,40 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) int regAddrOffset = 0; if(o_ctrl->ois_fw_inc_addr == 1) regAddrOffset = total_idx/o_ctrl->ois_fw_data_type + packet_idx; - - i2c_reg_setting.reg_setting[packet_idx].reg_addr = - o_ctrl->opcode.prog + regAddrOffset; - if (o_ctrl->ois_fw_data_type == CAMERA_SENSOR_I2C_TYPE_WORD) { + if (strstr(o_ctrl->ois_name, "dw9784") && total_idx >= total_bytes - DW9784_IF_SIZE) { + i2c_reg_setting.reg_setting[packet_idx].reg_addr = o_ctrl->opcode.prog + regAddrOffset - (total_bytes - DW9784_IF_SIZE)/2; i2c_reg_setting.reg_setting[packet_idx].reg_data = (uint32_t)(*ptr << 8) | *(ptr+1); + i2c_reg_setting.reg_setting[packet_idx].delay = 0; + i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; + CAM_DBG(CAM_OIS, "IF OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", + i2c_reg_setting.reg_setting[packet_idx].reg_addr, + i2c_reg_setting.reg_setting[packet_idx].reg_data, + (ptr-(uint8_t *)fw->data)); } else { - i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + i2c_reg_setting.reg_setting[packet_idx].reg_addr = + o_ctrl->opcode.prog + regAddrOffset; + if (o_ctrl->ois_fw_data_type == CAMERA_SENSOR_I2C_TYPE_WORD) { + i2c_reg_setting.reg_setting[packet_idx].reg_data = (uint32_t)(*ptr << 8) | *(ptr+1); + } else { + i2c_reg_setting.reg_setting[packet_idx].reg_data = *ptr; + } + i2c_reg_setting.reg_setting[packet_idx].delay = 0; + i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; + CAM_DBG(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", + i2c_reg_setting.reg_setting[packet_idx].reg_addr, + i2c_reg_setting.reg_setting[packet_idx].reg_data, + (ptr-(uint8_t *)fw->data)); } - i2c_reg_setting.reg_setting[packet_idx].delay = 0; - i2c_reg_setting.reg_setting[packet_idx].data_mask = 0; - CAM_DBG(CAM_OIS, "OIS_FW Reg:[0x%04x]: 0x%04x P:0x%x", - i2c_reg_setting.reg_setting[packet_idx].reg_addr, - i2c_reg_setting.reg_setting[packet_idx].reg_data, - (ptr-(uint8_t *)fw->data)); } i2c_reg_setting.size = packet_idx; if (o_ctrl->ois_fw_inc_addr == 1) { + if (strstr(o_ctrl->ois_name, "dw9784") && total_idx == total_bytes - DW9784_IF_SIZE){ + rc = dw9784_check_if_download(&(o_ctrl->io_master_info)); + if (rc < 0) { + CAM_ERR(CAM_OIS, "dw9784 check if download fail"); + goto release_firmware; + } + } rc = camera_io_dev_write_continuous(&(o_ctrl->io_master_info), &i2c_reg_setting, 0); } else { @@ -507,6 +536,8 @@ static int cam_ois_fw_prog_download(struct cam_ois_ctrl_t *o_ctrl) if (strstr(o_ctrl->ois_name, "dw9781")) { dw9781_post_firmware_download(&(o_ctrl->io_master_info), fw->data, fw->size); + } else if (strstr(o_ctrl->ois_name, "dw9784")) { + dw9784_post_firmware_download(&(o_ctrl->io_master_info)); } release_firmware: @@ -536,7 +567,8 @@ static int cam_ois_fw_coeff_download(struct cam_ois_ctrl_t *o_ctrl) return -EINVAL; } - if (strstr(o_ctrl->ois_name, "dw9781") || strstr(o_ctrl->ois_name, "aw86006")) { + if (strstr(o_ctrl->ois_name, "dw9781") || strstr(o_ctrl->ois_name, "aw86006") || + strstr(o_ctrl->ois_name, "dw9784")) { CAM_DBG(CAM_OIS, "not need download coeff fw for %s.", o_ctrl->ois_name); return 0; } diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dw9784.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9784.c new file mode 100644 index 000000000000..e79847778356 --- /dev/null +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dw9784.c @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2021 Motorola Mobility LLC. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "cam_ois_core.h" +#include "cam_ois_soc.h" +#include "cam_sensor_util.h" +#include "cam_debug_util.h" +#include "cam_common_util.h" + +#define DW9784_CHIP_ID_ADDRESS 0x7000 +#define DW9784_CHECKSUM_ADDRESS 0x700C +#define DW9784_CHIP_ID 0x9784 +#define FW_VER_CURR_ADDR 0x7001 + +#define EOK 0 + +#define FW_VERSION_OFFSET 10493 +#define FW_CHECKSUM_OFFSET 10495 + +typedef struct +{ + unsigned int driverIc; + unsigned int size; + const uint16_t *fwContentPtr; + uint16_t version; + uint16_t checksum; +} FirmwareContex; + +static FirmwareContex g_dw9784FirmwareContext; + +static int32_t dw9784_cci_write(struct camera_io_master * io_master_info, uint16_t reg, uint16_t val) +{ + int32_t rc = 0; + struct cam_sensor_i2c_reg_array reg_setting; + struct cam_sensor_i2c_reg_setting wr_setting; + + reg_setting.reg_addr = reg; + reg_setting.reg_data = val; + reg_setting.delay = 0; + reg_setting.data_mask = 0; + wr_setting.addr_type = CAMERA_SENSOR_I2C_TYPE_WORD; + wr_setting.data_type = CAMERA_SENSOR_I2C_TYPE_WORD; + wr_setting.reg_setting = ®_setting; + wr_setting.size = 1; + wr_setting.delay = 0; + rc = camera_io_dev_write(io_master_info, &wr_setting); + return rc; +} + +static int32_t dw9784_cci_read(struct camera_io_master * io_master_info, uint16_t reg, uint16_t *val) +{ + int32_t rc = 0; + uint32_t regVal = 0; + rc = camera_io_dev_read(io_master_info, reg, ®Val, CAMERA_SENSOR_I2C_TYPE_WORD, CAMERA_SENSOR_I2C_TYPE_WORD); + if (!rc) { + *val = (uint16_t)regVal; + } + return rc; +} + +static void dw9784_delay_ms(uint32_t ms) +{ + usleep_range(ms*1000, ms*1000+10); + return; +} + +void dw9784_ois_reset(struct camera_io_master * io_master_info) +{ + CAM_INFO(CAM_OIS, "[dw9784_ois_reset] ois reset"); + dw9784_cci_write(io_master_info, 0xD002, 0x0001); /* DW9784_DBGc reset */ + dw9784_delay_ms(4); + dw9784_cci_write(io_master_info, 0xD001, 0x0001); /* Active mode (DSP ON) */ + dw9784_delay_ms(25); /* ST gyro - over wait 25ms, default Servo On */ + dw9784_cci_write(io_master_info, 0xEBF1, 0x56FA); /* User protection release */ +} + +void dw9784_code_pt_off(struct camera_io_master * io_master_info) +{ + CAM_INFO(CAM_OIS, "[dw9784_code_pt_off] start"); + /* release all protection */ + dw9784_cci_write(io_master_info, 0xFD00, 0x5252); + dw9784_delay_ms(1); + CAM_INFO(CAM_OIS, "[dw9784_code_pt_off] finish"); +} + +void dw9784_pid_erase(struct camera_io_master * io_master_info) +{ + CAM_INFO(CAM_OIS, "[dw9784_pid_erase] start pid flash(IF) erase"); + dw9784_cci_write(io_master_info, 0xde03, 0x0000); // page 0 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0008); // page erase + dw9784_delay_ms(10); // need to delay after erase + CAM_INFO(CAM_OIS, "[dw9784_pid_erase] finish"); +} + +void dw9784_fw_eflash_erase(struct camera_io_master * io_master_info) +{ + CAM_INFO(CAM_OIS, "[dw9784_fw_eflash_erase] start fw flash erase"); + dw9784_cci_write(io_master_info, 0xde03, 0x0000); // 4k Sector_0 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase + dw9784_delay_ms(10); // need to delay after erase + + dw9784_cci_write(io_master_info, 0xde03, 0x0008); // 4k Sector_1 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase + dw9784_delay_ms(10); // need to delay after erase + + dw9784_cci_write(io_master_info, 0xde03, 0x0010); // 4k Sector_2 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase + dw9784_delay_ms(10); // need to delay after erase + + dw9784_cci_write(io_master_info, 0xde03, 0x0018); // 4k Sector_3 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase + dw9784_delay_ms(10); // need to delay after erase + + dw9784_cci_write(io_master_info, 0xde03, 0x0020); // 4k Sector_4 + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xde04, 0x0002); // 4k Sector Erase + dw9784_delay_ms(10); // need to delay after erase + CAM_INFO(CAM_OIS, "[dw9784_fw_eflash_erase] finish"); +} + +void dw9784_flash_acess(struct camera_io_master * io_master_info) +{ + CAM_INFO(CAM_OIS, "[dw9784_flash_acess] execution"); + /* release all protection */ + dw9784_cci_write(io_master_info, 0xFAFA, 0x98AC); + dw9784_delay_ms(1); + dw9784_cci_write(io_master_info, 0xF053, 0x70BD); + dw9784_delay_ms(1); +} + +int dw9784_whoami_chk(struct camera_io_master * io_master_info) +{ + uint16_t sec_chip_id; + dw9784_cci_write(io_master_info, 0xD000, 0x0001); /* chip enable */ + dw9784_delay_ms(4); + dw9784_cci_write(io_master_info, 0xD001, 0x0000); /* dsp off mode */ + dw9784_delay_ms(1); + + dw9784_flash_acess(io_master_info); /* All protection */ + + dw9784_cci_read(io_master_info, 0xD060, &sec_chip_id); /* 2nd chip id */ + CAM_INFO(CAM_OIS, "[dw9784_ois_ready_check] sec_chip_id : 0x%04x", sec_chip_id); + if(sec_chip_id != 0x0020) + { + CAM_ERR(CAM_OIS, "[dw9784] second_chip_id check fail : 0x%04X", sec_chip_id); + CAM_ERR(CAM_OIS, "[dw9784] second_enter shutdown mode"); + dw9784_cci_write(io_master_info, 0xD000, 0x0000); /* ic */ + return -1; + } + + dw9784_ois_reset(io_master_info); /* ois reset */ + return 0; +} + +int dw9784_checksum_fw_chk(struct camera_io_master * io_master_info) +{ + /* + Bit [0]: FW checksum error + Bit [1]: Module cal. checksum error + Bit [2]: Set cal. checksum error + */ + uint16_t reg_fw_checksum; // 0x700C + uint16_t reg_checksum_status; // 0x700D + + dw9784_cci_read(io_master_info, 0x700C, ®_fw_checksum); + dw9784_cci_read(io_master_info, 0x700D, ®_checksum_status); + + CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] reg_checksum_status : 0x%04X", reg_checksum_status); + CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] reg_fw_checksum : 0x%04X", reg_fw_checksum); + + if( (reg_checksum_status & 0x0001) == 0) + { + CAM_INFO(CAM_OIS, "[dw9784_checksum_fw_chk] fw checksum pass"); + return 0; + }else + { + CAM_ERR(CAM_OIS, "[dw9784_checksum_fw_chk] fw checksum error reg_fw_checksum : 0x%04X", reg_fw_checksum); + return -1; + } +} + +static int dw9784_erase_mtp_rewritefw(struct camera_io_master * io_master_info) +{ + uint16_t FMC; + CAM_INFO(CAM_OIS, "dw9784 erase for rewritefw starting.."); + dw9784_cci_write(io_master_info, 0xd001, 0x0000); + dw9784_delay_ms(1); + dw9784_flash_acess(io_master_info); + + dw9784_cci_write(io_master_info, 0xDE01, 0x0000); // FMC block FW select + dw9784_delay_ms(1); + dw9784_cci_read(io_master_info, 0xDE01, &FMC); + if (FMC != 0) + { + CAM_INFO(CAM_OIS, "[dw9784_download_fw] FMC register value 1st warning : %04x", FMC); + dw9784_cci_write(io_master_info, 0xDE01, 0x0000); + dw9784_delay_ms(1); + FMC = 0; // initialize FMC value + + dw9784_cci_read(io_master_info, 0xDE01, &FMC); + if (FMC != 0) + { + CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd FMC register value 2nd warning : %04x", FMC); + CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop f/w download"); + return -1; + } + } + + /* code protection off */ + dw9784_code_pt_off(io_master_info); + + /* 512 byte page */ + dw9784_cci_write(io_master_info, 0xde03, 0x0027); + /* page erase */ + dw9784_cci_write(io_master_info, 0xde04, 0x0008); + dw9784_delay_ms(10); + + dw9784_cci_write(io_master_info, 0xd000, 0x0000); /* Shut download mode */ + + return 0; +} + +static int dw9784_prepare_fw_download(struct camera_io_master * io_master_info) +{ + /* step 1: MTP Erase and DSP Disable for firmware 0x8000 write */ + /* step 2: MTP setup */ + /* step 3. FMC register check */ + /* step 4. code protection off */ + /* step 5. erase flash fw data */ + uint16_t FMC; + dw9784_cci_write(io_master_info, 0xd001, 0x0000); + dw9784_flash_acess(io_master_info); + + dw9784_cci_write(io_master_info, 0xDE01, 0x0000); // FMC block FW select + dw9784_delay_ms(1); + dw9784_cci_read(io_master_info, 0xDE01, &FMC); + if (FMC != 0) + { + CAM_INFO(CAM_OIS, "[dw9784_download_fw] FMC register value 1st warning : %04x", FMC); + dw9784_cci_write(io_master_info, 0xDE01, 0x0000); + dw9784_delay_ms(1); + FMC = 0; // initialize FMC value + + dw9784_cci_read(io_master_info, 0xDE01, &FMC); + if (FMC != 0) + { + CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd FMC register value 2nd warning : %04x", FMC); + CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop f/w download"); + return -1; + } + } + + dw9784_code_pt_off(io_master_info); + dw9784_fw_eflash_erase(io_master_info); + CAM_INFO(CAM_OIS, "[dw9784_download_fw] start firmware download"); + return 0; +} + +int dw9784_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize) +{ + uint8_t ret; + uint8_t needDownload = 0; + uint16_t fwchecksum = 0; + uint16_t first_chip_id = 0; + uint16_t chip_checksum = 0; + uint16_t fw_version_current = 0; + uint16_t fw_version_latest = 0; + + if (io_master_info == NULL) { + CAM_ERR(CAM_OIS, "FATAL: OIS CCI context error!!!"); + return -1; + } + + if (fwData == NULL || fwSize < FW_VERSION_OFFSET*sizeof(uint16_t)) { + CAM_ERR(CAM_OIS, "FATAL: firmware buffer(%p) is NULL or size(%d) abnormal!!!", fwData, fwSize); + return -1; + } + + g_dw9784FirmwareContext.driverIc = 0x9784; + g_dw9784FirmwareContext.fwContentPtr = (const uint16_t *)fwData; + g_dw9784FirmwareContext.size = fwSize; + g_dw9784FirmwareContext.version = *(g_dw9784FirmwareContext.fwContentPtr+FW_VERSION_OFFSET); + g_dw9784FirmwareContext.version = ((g_dw9784FirmwareContext.version << 8) & 0xff00) | + ((g_dw9784FirmwareContext.version >> 8) & 0xff); + g_dw9784FirmwareContext.checksum = *(g_dw9784FirmwareContext.fwContentPtr+FW_CHECKSUM_OFFSET); + g_dw9784FirmwareContext.checksum = ((g_dw9784FirmwareContext.checksum << 8) & 0xff00) | + ((g_dw9784FirmwareContext.checksum >> 8) & 0xff); + if (dw9784_whoami_chk(io_master_info) != 0) { + CAM_ERR(CAM_OIS, "[dw9784] second chip id check fail"); + return -1; + } + + dw9784_cci_read(io_master_info, DW9784_CHIP_ID_ADDRESS, &first_chip_id); + dw9784_cci_read(io_master_info, 0x7001, &chip_checksum); + CAM_INFO(CAM_OIS, "[dw9784] FW_VER_PHONE_MAKER : 0x%x", chip_checksum); + dw9784_cci_read(io_master_info, 0x7002, &chip_checksum); + CAM_INFO(CAM_OIS, "[dw9784] FW_DATE_PHONE_MAKER : 0x%x", chip_checksum); + + CAM_INFO(CAM_OIS, "[dw9784] first_chip_id : 0x%x", first_chip_id); + if (first_chip_id != DW9784_CHIP_ID) { /* first_chip_id verification failed */ + CAM_INFO(CAM_OIS, "[dw9784] start flash download:: size:%d, version:0x%x", + g_dw9784FirmwareContext.size, g_dw9784FirmwareContext.version); + needDownload = 1; + ret = dw9784_prepare_fw_download(io_master_info); /* Need to forced update OIS firmware again. */ + } else { + fwchecksum = dw9784_checksum_fw_chk(io_master_info); + if(fwchecksum != 0) + { + needDownload = 1; + CAM_INFO(CAM_OIS, "[dw9784] firmware checksum error"); + } + + dw9784_cci_read(io_master_info, FW_VER_CURR_ADDR, &fw_version_current); + fw_version_latest = g_dw9784FirmwareContext.version; /*Firmware version read from file content.*/ + + CAM_INFO(CAM_OIS, "[dw9784] fw_version_current = 0x%x, fw_version_latest = 0x%x", + fw_version_current, fw_version_latest); + + /* download firmware, check if need update, download firmware to flash */ + if (needDownload || ((fw_version_current & 0xFFFF) != (fw_version_latest & 0xFFFF))) { + needDownload = 1; + + CAM_INFO(CAM_OIS, "[dw9784] start flash download:: size:%d, version:0x%x needDownload %d", + g_dw9784FirmwareContext.size, g_dw9784FirmwareContext.version, needDownload); + + ret = dw9784_prepare_fw_download(io_master_info); + CAM_INFO(CAM_OIS, "[dw9784] flash download::vendor_dw9784"); + if (ret != EOK) { + dw9784_erase_mtp_rewritefw(io_master_info); + CAM_ERR(CAM_OIS, "[dw9784] firmware download error, ret = 0x%x", ret); + CAM_ERR(CAM_OIS, "[dw9784] change dw9784 state to shutdown mode"); + needDownload = 1; + } + } else { + CAM_INFO(CAM_OIS, "[dw9784] ois firmware version is updated, skip download"); + } + } + return needDownload; +} +EXPORT_SYMBOL(dw9784_check_fw_download); + +int dw9784_check_if_download(struct camera_io_master * io_master_info) +{ + uint16_t FMC; + + /* step 1. Writes 512Byte FW(PID) data to IF flash. (FMC register check) */ + dw9784_cci_write(io_master_info, 0xDE01, 0x1000); + dw9784_delay_ms(1); + dw9784_cci_read(io_master_info,0xDE01, &FMC); + dw9784_delay_ms(1); + if (FMC != 0x1000) + { + CAM_INFO(CAM_OIS, "[dw9784_download_fw] IF FMC register value 1st warning : %04x", FMC); + dw9784_cci_write(io_master_info, 0xDE01, 0x1000); + dw9784_delay_ms(1); + FMC = 0; // initialize FMC value + + dw9784_cci_read(io_master_info,0xDE01, &FMC); + if (FMC != 0x1000) + { + CAM_ERR(CAM_OIS, "[dw9784_download_fw] 2nd IF FMC register value 2nd fail : %04x", FMC); + CAM_ERR(CAM_OIS, "[dw9784_download_fw] stop firmware download"); + return -1; + } + } + + /* step 2. erease IF(FW/PID) eFLASH */ + dw9784_pid_erase(io_master_info); + + CAM_INFO(CAM_OIS, "[dw9784_download_fw] start firmware/pid download"); + return 0; +} +EXPORT_SYMBOL(dw9784_check_if_download); + +void dw9784_post_firmware_download(struct camera_io_master * io_master_info) +{ + uint16_t fwchecksum = 0; + + dw9784_ois_reset(io_master_info); + fwchecksum = dw9784_checksum_fw_chk(io_master_info); + if(fwchecksum != 0) + { + CAM_ERR(CAM_OIS, "[dw9784] firmware checksum error"); + dw9784_erase_mtp_rewritefw(io_master_info); + CAM_ERR(CAM_OIS, "[dw9784] change dw9784 state to shutdown mode"); + } + return; +} + +EXPORT_SYMBOL(dw9784_post_firmware_download); From 360ff769a11277c5fc554bf8f052bbc88deb0f85 Mon Sep 17 00:00:00 2001 From: "tin_zhiyuan.liao_tmp" Date: Wed, 3 May 2023 18:55:05 +0800 Subject: [PATCH 77/86] bangkk: open Camera preview may be black sometimes details: Modyfy flash i2c function to fix cci timeout Change-Id: Idbdc2f3f0532c7449dacf1fe8d0fda3d74405a6a Reviewed-on: https://gerrit.mot.com/2594431 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Pengfei Qiao Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_flash/cam_flash_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index 6aae862ed4a5..db810e8f5484 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -176,10 +176,10 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, CAM_ERR(CAM_FLASH, "Power Up Failed"); goto release_mutex; } - if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){ + /*if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){ CAM_ERR(CAM_FLASH, "Failed Flash Fill I2C Setting rc =%d",rc); goto release_mutex; - } + }*/ rc = camera_io_dev_read(&(fctrl->io_master_info), flash_iic_supplier[1],&flashid, CAMERA_SENSOR_I2C_TYPE_BYTE, From d3c34abf724a4dbdc7d2a676ccb5586683ee7c2e Mon Sep 17 00:00:00 2001 From: "tin_yingying.zhang_tmp" Date: Thu, 4 May 2023 21:15:18 +0800 Subject: [PATCH 78/86] bangkk: Open Camera preview will be black then camera error details: Solve open main camera error. Change-Id: I20a6a743ce921be683c296d97a4cb0282c9e0542 Signed-off-by: tin_yingying.zhang_tmp Reviewed-on: https://gerrit.mot.com/2596467 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Yongqin Wan Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_flash/cam_flash_core.c | 6 +++--- drivers/cam_sensor_module/cam_flash/cam_flash_dev.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 17359fd2c8d3..fe1e40144965 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -2152,9 +2152,9 @@ static int cam_flash_construct_power_vio_setting( power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_GPIO1; power_info->power_down_setting[0].seq_val = 0; power_info->power_down_setting[0].config_val = 0; - power_info->power_down_setting[0].seq_type = SENSOR_VIO; - power_info->power_down_setting[0].seq_val = CAM_VIO; - power_info->power_down_setting[0].config_val = 0; + power_info->power_down_setting[1].seq_type = SENSOR_VIO; + power_info->power_down_setting[1].seq_val = CAM_VIO; + power_info->power_down_setting[1].config_val = 0; return rc; diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index db810e8f5484..80d2bd4382dd 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -172,14 +172,14 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, CAM_ERR(CAM_FLASH, "Flash Fill Vreg Failed"); goto release_mutex; } + if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){ + CAM_ERR(CAM_FLASH, "Failed Flash Fill I2C Setting rc =%d",rc); + goto release_mutex; + } if (fctrl->func_tbl.power_ops(fctrl, true)){ CAM_ERR(CAM_FLASH, "Power Up Failed"); goto release_mutex; } - /*if (cam_flash_fill_i2c_default_setting(fctrl, flash_iic_supplier[0])){ - CAM_ERR(CAM_FLASH, "Failed Flash Fill I2C Setting rc =%d",rc); - goto release_mutex; - }*/ rc = camera_io_dev_read(&(fctrl->io_master_info), flash_iic_supplier[1],&flashid, CAMERA_SENSOR_I2C_TYPE_BYTE, From 156d926f68aacc9283e0b7edd41d9852497ee51f Mon Sep 17 00:00:00 2001 From: huqian4 Date: Mon, 22 May 2023 11:56:17 +0800 Subject: [PATCH 79/86] bangkk: support dw9784 af drift details: apply af drift setting immediately after writing DAC value, porting from (CR). Change-Id: Ie67d3e0202ce3345d233dcdcc5396fd98694655b Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2616209 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/cam_actuator_core.c | 40 +++++++++++++++++++ .../cam_actuator/cam_actuator_dev.h | 3 ++ .../cam_actuator/cam_actuator_soc.c | 9 +++++ .../cam_sensor_module/cam_ois/cam_ois_core.c | 26 ++++++++++++ .../cam_sensor_module/cam_ois/cam_ois_dev.c | 35 ++++++++++++++++ 5 files changed, 113 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index a92aa16fed54..3f2441907ab4 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -15,6 +15,11 @@ #include "mot_actuator.h" #endif +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT +extern int cam_ois_get_init_info(void); +extern int cam_ois_write_af_drift(uint32_t dac); +#endif + int32_t cam_actuator_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) { @@ -263,6 +268,11 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl, struct i2c_settings_list *i2c_list; int32_t rc = 0; +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + struct cam_sensor_i2c_reg_setting * i2c_reg = NULL; + uint32_t dac = 0; +#endif + if (a_ctrl == NULL || i2c_set == NULL) { CAM_ERR(CAM_ACTUATOR, "Invalid Args"); return -EINVAL; @@ -292,6 +302,36 @@ int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl, CAM_DBG(CAM_ACTUATOR, "Success:request ID: %d", i2c_set->request_id); +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + if (a_ctrl->af_drift_supported == true && + (cam_ois_get_init_info() == 1) && + i2c_list != NULL) { + + #define ADDR_ACTUATOR 0x18 + #define REG_ACTUATOR 0x00 + #define DATA_SHIFT 4 + + i2c_reg = &(i2c_list->i2c_settings); + + if (i2c_reg != NULL && + i2c_reg->reg_setting != NULL && + a_ctrl->io_master_info.cci_client != NULL && + a_ctrl->io_master_info.cci_client->sid == (ADDR_ACTUATOR >> 1) && + i2c_reg->addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE && + i2c_reg->data_type == CAMERA_SENSOR_I2C_TYPE_WORD && + i2c_reg->reg_setting[0].reg_data != 0 && + i2c_reg->reg_setting[0].reg_addr == REG_ACTUATOR) + { + dac = i2c_reg->reg_setting[0].reg_data >> DATA_SHIFT; + + rc = cam_ois_write_af_drift(dac); + if (rc < 0) { + CAM_ERR(CAM_ACTUATOR, "Failed to apply af drift settings: %d", rc); + rc = 0; // avoid broken actuator function + } + } + } +#endif } } diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h b/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h index 5406e2c96e55..6ed2d19a97f1 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h @@ -118,6 +118,9 @@ struct cam_actuator_ctrl_t { #ifdef CONFIG_AF_NOISE_ELIMINATION bool is_multi_user_supported; #endif +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + bool af_drift_supported; +#endif }; /** diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c index 7ef6b95595d2..f664633fd865 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_soc.c @@ -43,6 +43,15 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl, CAM_DBG(CAM_ACTUATOR, "multi-user-support %d", a_ctrl->is_multi_user_supported); #endif +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + if (!of_property_read_bool(of_node, "af-drift-support")) { + a_ctrl->af_drift_supported = false; + } else { + a_ctrl->af_drift_supported = true; + } + CAM_DBG(CAM_ACTUATOR, "af-drift-support %d", a_ctrl->af_drift_supported); +#endif + if (a_ctrl->io_master_info.master_type == CCI_MASTER) { rc = of_property_read_u32(of_node, "cci-master", &(a_ctrl->cci_i2c_master)); 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 82d703bc785d..189ce58fefb3 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -23,6 +23,19 @@ extern int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, const struct f extern int dw9784_check_fw_download(struct camera_io_master * io_master_info, const uint8_t *fwData, uint32_t fwSize); extern void dw9784_post_firmware_download(struct camera_io_master * io_master_info); extern int dw9784_check_if_download(struct camera_io_master * io_master_info); +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT +int m_ois_init = 0; + +int cam_ois_get_init_info(void) +{ + return m_ois_init; +} + +static void cam_ois_set_init_info(int value) +{ + m_ois_init = value; +} +#endif int32_t cam_ois_construct_default_power_setting( struct cam_sensor_power_ctrl_t *power_info) @@ -225,6 +238,11 @@ static int cam_ois_power_down(struct cam_ois_ctrl_t *o_ctrl) CAM_INFO(CAM_OIS, "OIS power down successed"); +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + if (strstr(o_ctrl->ois_name, "dw9784")) + cam_ois_set_init_info(0); +#endif + camera_io_release(&o_ctrl->io_master_info); return rc; @@ -932,6 +950,10 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) goto pwr_dwn; } +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + if (strstr(o_ctrl->ois_name, "dw9784")) + cam_ois_set_init_info(1); +#endif if (o_ctrl->is_ois_calib) { rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_calib_data); @@ -1888,6 +1910,10 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg) if (o_ctrl->i2c_mode_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_mode_data); +#ifdef CONFIG_MOT_OIS_AF_DRIFT + if (o_ctrl->i2c_af_drift_data.is_settings_valid == 1) + delete_request(&o_ctrl->i2c_af_drift_data); +#endif if (o_ctrl->i2c_gyro_data.is_settings_valid == 1) delete_request(&o_ctrl->i2c_gyro_data); diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c index 5526895b9fa4..bd8b1c0740db 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_dev.c @@ -34,6 +34,38 @@ static int cam_ois_clear_data_ready(struct cam_ois_ctrl_t *o_ctrl) CAM_DBG(CAM_OIS,"Clear data-ready success"); return rc; } +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT +static struct cam_ois_ctrl_t * g_o_ctrl = NULL; + +int cam_ois_write_af_drift(uint32_t dac) +{ + struct cam_ois_ctrl_t *o_ctrl = g_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 = {0x7070, dac, 0, 0}; + int rc = 0; + + if (!o_ctrl) { + CAM_ERR(CAM_OIS, "invalid args"); + return -EINVAL; + } + + if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) { + CAM_WARN(CAM_OIS, "Not in right state to write af drift: %d", o_ctrl->cam_ois_state); + 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, "fail in applying i2c wrt settings"); + return -EINVAL; + } + + CAM_DBG(CAM_OIS,"write af-drift success 0x%x", dac); + return rc; +} +#endif static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) @@ -617,6 +649,9 @@ static int cam_ois_component_bind(struct device *dev, platform_set_drvdata(pdev, o_ctrl); o_ctrl->cam_ois_state = CAM_OIS_INIT; +#ifdef CONFIG_MOT_DONGWOON_OIS_AF_DRIFT + g_o_ctrl = o_ctrl; +#endif mutex_init(&(o_ctrl->vsync_mutex)); init_completion(&o_ctrl->ois_data_complete); From 9cc3f930c36ed615ca9c841cc407d570654f95c9 Mon Sep 17 00:00:00 2001 From: "tin_zhiyuan.liao_tmp" Date: Wed, 24 May 2023 14:37:37 +0800 Subject: [PATCH 80/86] bangkk: Fix flash request GPIO-24 failed details: fixed GPIO-24 set shared failed. Change-Id: Ib7fbec1be357585eb14c4d898c06b80af37bd6ba Signed-off-by: tin_zhiyuan.liao_tmp Reviewed-on: https://gerrit.mot.com/2619027 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_flash/cam_flash_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index fe1e40144965..3972b5c62b08 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -2135,7 +2135,7 @@ static int cam_flash_construct_power_vio_setting( power_info->power_setting[0].seq_val = CAM_VIO; power_info->power_setting[0].config_val = 1; power_info->power_setting[0].delay = 2; - power_info->power_setting[1].seq_type = SENSOR_CUSTOM_GPIO1; + power_info->power_setting[1].seq_type = SENSOR_CUSTOM_REG2; power_info->power_setting[1].seq_val = 0; power_info->power_setting[1].config_val = 1; power_info->power_setting[1].delay = 0; @@ -2149,7 +2149,7 @@ static int cam_flash_construct_power_vio_setting( goto free_power_settings; } - power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_GPIO1; + power_info->power_down_setting[0].seq_type = SENSOR_CUSTOM_REG2; power_info->power_down_setting[0].seq_val = 0; power_info->power_down_setting[0].config_val = 0; power_info->power_down_setting[1].seq_type = SENSOR_VIO; From 12db07489bb66b3d730d826b30061fefb4074569 Mon Sep 17 00:00:00 2001 From: Liu Yang Date: Tue, 16 May 2023 20:26:42 +0800 Subject: [PATCH 81/86] bangkk: Powerup and initialize sensor early [3/4] Powering on and initializing main sensor in camera open instead of streams configuration to optimize the startup KPI. It is a common feature and depends on sensor setting. It can save about 30ms. Porting this func from (CR) and (CR). mot-cam-category: KPI Change-Id: Iab7653a3598cd5816b9700c90cea920b1d172001 Signed-off-by: Liu Yang Reviewed-on: https://gerrit.mot.com/2640367 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Ji Zhao Reviewed-by: Bolei Shang Reviewed-by: Reviewed-by: Zilong Zhang Reviewed-by: Hualong Zhu Reviewed-by: Reviewed-by: Dongju He Reviewed-by: Reviewed-by: Zhuoran Xu Submit-Approved: Jira Key --- .../cam_sensor/cam_sensor_core.c | 79 +++++++++++++++++++ .../cam_sensor/cam_sensor_dev.h | 3 + include/uapi/camera/media/cam_defs.h | 6 ++ 3 files changed, 88 insertions(+) diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 9e32a73719bd..a9f1d813a3a0 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -1033,6 +1033,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, */ s_ctrl->is_probe_succeed = 1; s_ctrl->sensor_state = CAM_SENSOR_INIT; +#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP + s_ctrl->sensor_power_up_done = 0; +#endif } break; case CAM_ACQUIRE_DEV: { @@ -1322,6 +1325,69 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } } break; +#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP + case CAM_MOT_PRE_POWER_UP: { + if (!s_ctrl->sensor_power_up_done) + { + rc = cam_sensor_power_up(s_ctrl); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "MotPreAct - Sensor Power up failed for sensor_id:0x%x, slave_addr:0x%x", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr); + goto release_mutex; + } + s_ctrl->sensor_power_up_done = 1; + CAM_DBG(CAM_SENSOR, "MotPreAct - Camera sensor_id:0x%x, slave_addr:0x%x, pre power on done = %d", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensor_power_up_done); + } + } + break; + case CAM_MOT_PRE_POWER_DOWN: { + if (s_ctrl->sensor_power_up_done) + { + rc = cam_sensor_power_down(s_ctrl); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "Sensor Power Down failed sensor_id: 0x%x, slave_addr:0x%x", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr); + goto release_mutex; + } + CAM_DBG(CAM_SENSOR, "MotPreAct - Camera sensor_id:0x%x, slave_addr:0x%x, pre power on done = %d", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + s_ctrl->sensor_power_up_done); + } + } + break; + case CAM_MOT_QUERY_SENSOR_STATUS: { + uint32_t isSensorActive = 0; + + if (s_ctrl->sensor_power_up_done) + { + isSensorActive = 1; + } + else + { + isSensorActive = 0; + } + + if (copy_to_user(u64_to_user_ptr(cmd->handle), + &isSensorActive, sizeof(uint32_t))) { + CAM_ERR(CAM_SENSOR, "MotPreAct - Failed Copy to User"); + rc = -EFAULT; + goto release_mutex; + } + CAM_DBG(CAM_SENSOR, "MotPreAct - Query camera sensor_id:0x%x, slave_addr:0x%x, status = %d", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr, + isSensorActive); + } + break; +#endif default: CAM_ERR(CAM_SENSOR, "Invalid Opcode: %d", cmd->op_code); rc = -EINVAL; @@ -1424,6 +1490,16 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl) return -EINVAL; } +#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP + if (s_ctrl->sensor_power_up_done) + { + CAM_INFO(CAM_SENSOR, "MotPreAct - sensor has power on done for sensor_id:0x%x, slave_addr:0x%x", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensordata->slave_info.sensor_slave_addr); + return 0; + } +#endif + power_info = &s_ctrl->sensordata->power_info; slave_info = &(s_ctrl->sensordata->slave_info); @@ -1498,6 +1574,9 @@ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl) } camera_io_release(&(s_ctrl->io_master_info)); +#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP + s_ctrl->sensor_power_up_done = 0; +#endif return rc; } diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index 96c1cf9bc6fd..486574164f56 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -128,6 +128,9 @@ struct cam_sensor_ctrl_t { uint16_t i2c_switch_reg_addr; uint16_t i2c_switch_reg_data; uint16_t i2c_switch_reg_delayMs; +#ifdef CONFIG_MOT_SENSOR_PRE_POWERUP + bool sensor_power_up_done; +#endif }; /** diff --git a/include/uapi/camera/media/cam_defs.h b/include/uapi/camera/media/cam_defs.h index 9da3a636ab0e..b76d67e43028 100644 --- a/include/uapi/camera/media/cam_defs.h +++ b/include/uapi/camera/media/cam_defs.h @@ -32,6 +32,12 @@ #define CAM_EXT_OPCODE_BASE 0x200 #define CAM_CONFIG_DEV_EXTERNAL (CAM_EXT_OPCODE_BASE + 0x1) +/* CONFIG_MOT_SENSOR_PRE_POWERUP */ +#define CAM_MOT_OPCODE_BASE 0x250 +#define CAM_MOT_PRE_POWER_UP (CAM_MOT_OPCODE_BASE + 0x1) +#define CAM_MOT_PRE_POWER_DOWN (CAM_MOT_OPCODE_BASE + 0x2) +#define CAM_MOT_QUERY_SENSOR_STATUS (CAM_MOT_OPCODE_BASE + 0x3) + /* camera handle type */ #define CAM_HANDLE_USER_POINTER 1 #define CAM_HANDLE_MEM_HANDLE 2 From 2117786f35e920a6e80c80b71ee249b75ca8bcc5 Mon Sep 17 00:00:00 2001 From: Simon C Date: Wed, 28 Jun 2023 20:13:13 +0800 Subject: [PATCH 82/86] fogor: Actuator noise reduction[2/2] Details: Add AF noise reduction code for gt9764 in fogor Leverage from penang Change-Id: Ic66bdfd82e47adc790bb4cf72e5624b07053e5a0 Signed-off-by: Simon C Reviewed-on: https://gerrit.mot.com/2659037 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Reviewed-by: Long Cheng Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_actuator/mot_actuator.c | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 1de7dfe77576..35b29b036a10 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -41,6 +41,7 @@ typedef enum { MOT_ACTUATOR_INVALID, MOT_ACTUATOR_FIRST, MOT_ACTUATOR_GT9767 = MOT_ACTUATOR_FIRST, + MOT_ACTUATOR_GT9764, MOT_ACTUATOR_GT9772, MOT_ACTUATOR_DW9714, MOT_ACTUATOR_DW9800V, @@ -66,6 +67,7 @@ typedef enum { MOT_DEVICE_RHODEC, MOT_DEVICE_RHODEI, MOT_DEVICE_PENANG, + MOT_DEVICE_FOGOR, MOT_DEVICE_NUM, } mot_dev_type; @@ -142,6 +144,31 @@ static struct cam_sensor_i2c_reg_setting mot_gt9767_dac_settings = { .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, }; +/*Register settings of GT9764*/ +static struct cam_sensor_i2c_reg_array mot_gt9764_init_setting[] ={ + {0x02, 0x00, 1000}, + {0x02, 0x02, 0}, + {0x06, 0x40, 0}, + {0x07, 0x08, 0}, +}; + +static struct cam_sensor_i2c_reg_array mot_gt9764_dac_setting[] ={ + {0x03, 0x3ff, 0} +}; +static struct cam_sensor_i2c_reg_setting mot_gt9764_init_settings = { + .reg_setting = mot_gt9764_init_setting, + .size = ARRAY_SIZE(mot_gt9764_init_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_BYTE, +}; + +static struct cam_sensor_i2c_reg_setting mot_gt9764_dac_settings = { + .reg_setting = mot_gt9764_dac_setting, + .size = ARRAY_SIZE(mot_gt9764_dac_setting), + .addr_type = CAMERA_SENSOR_I2C_TYPE_BYTE, + .data_type = CAMERA_SENSOR_I2C_TYPE_WORD, +}; + /*Register settings of GT9772*/ static struct cam_sensor_i2c_reg_array mot_gt9772_init_setting[] ={ {0xED, 0xAB, 0}, @@ -227,6 +254,7 @@ static struct cam_sensor_i2c_reg_setting mot_dw9800v_dac_settings = { static mot_actuator_settings mot_actuator_list[MOT_ACTUATOR_NUM-1] = { //MUST be sorted as definition order in above structure: mot_actuator_type {&mot_gt9767_init_settings, &mot_gt9767_dac_settings}, + {&mot_gt9764_init_settings, &mot_gt9764_dac_settings}, {&mot_gt9772_init_settings, &mot_gt9772_dac_settings}, {&mot_dw9714_init_settings, &mot_dw9714_dac_settings}, {&mot_dw9800v_init_settings, &mot_dw9800v_dac_settings}, @@ -530,6 +558,34 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, }, + { + .dev_type = MOT_DEVICE_FOGOR, + .actuator_num = 1, + .dev_name = "fogor", + .actuator_info = { + [0] = { + .actuator_type = MOT_ACTUATOR_GT9764, + .dac_pos = 0, + .init_pos = 512, + .cci_addr = 0x0c, + .cci_dev = 0x00, + .cci_master = 0x0, + .regulator_list = {"pm6125_l13", "camera_ldo_50m_afvdd"}, + .regulator_volt_uv = {1800000, 2800000}, + .launch_lens = { + .launch_lens_needed = true, + .launch_lens_step = { + {200, 100}, + {100, 60}, + {50, 30}, + }, + }, + .pmic_load_needed = true, + .regulator_load_ua = {120000, 120000}, + }, + }, + }, + }; static uint32_t mot_device_index = MOT_DEVICE_NUM; From af41ca223f7c1178f9b402b88957cf147b12e30a Mon Sep 17 00:00:00 2001 From: huqian4 Date: Fri, 18 Aug 2023 15:29:42 +0800 Subject: [PATCH 83/86] fogos: Actuator noise reduction[2/2] Details: Change from fogor fo fogos,and change init setting as sac setting. Change-Id: I2d402372d74ca8004ff8458a6c97c197eb076aeb Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2713198 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Simon C Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- drivers/cam_sensor_module/cam_actuator/mot_actuator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c index 35b29b036a10..8311d5ff639a 100644 --- a/drivers/cam_sensor_module/cam_actuator/mot_actuator.c +++ b/drivers/cam_sensor_module/cam_actuator/mot_actuator.c @@ -67,7 +67,7 @@ typedef enum { MOT_DEVICE_RHODEC, MOT_DEVICE_RHODEI, MOT_DEVICE_PENANG, - MOT_DEVICE_FOGOR, + MOT_DEVICE_FOGOS, MOT_DEVICE_NUM, } mot_dev_type; @@ -148,8 +148,8 @@ static struct cam_sensor_i2c_reg_setting mot_gt9767_dac_settings = { static struct cam_sensor_i2c_reg_array mot_gt9764_init_setting[] ={ {0x02, 0x00, 1000}, {0x02, 0x02, 0}, - {0x06, 0x40, 0}, - {0x07, 0x08, 0}, + {0x06, 0x80, 0}, + {0x07, 0x62, 0}, }; static struct cam_sensor_i2c_reg_array mot_gt9764_dac_setting[] ={ @@ -559,9 +559,9 @@ static const mot_dev_info mot_dev_list[MOT_DEVICE_NUM] = { }, { - .dev_type = MOT_DEVICE_FOGOR, + .dev_type = MOT_DEVICE_FOGOS, .actuator_num = 1, - .dev_name = "fogor", + .dev_name = "fogos", .actuator_info = { [0] = { .actuator_type = MOT_ACTUATOR_GT9764, From 40dc422a6c5ab314ee792c5431074daae9d632f8 Mon Sep 17 00:00:00 2001 From: huqian4 Date: Tue, 26 Sep 2023 17:35:57 +0800 Subject: [PATCH 84/86] Bangkk: reset ois when read standby_flag fail details: Fix read standby_flag fail. Change-Id: I9d1165690b9b7ddb0d39883e70aa91047e0190cb Signed-off-by: huqian4 Reviewed-on: https://gerrit.mot.com/2751921 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Wang Liu Reviewed-by: Reviewed-by: Simon C Reviewed-by: Dongju He Reviewed-by: Yongqin Wan Reviewed-by: Zhichao Chen Reviewed-by: Zhuoran Xu Submit-Approved: Jira Key --- .../cam_sensor_module/cam_ois/cam_ois_aw86006.c | 16 +++++++++++++--- .../cam_sensor_module/cam_ois/cam_ois_aw86006.h | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c index 236de89b9e1a..5c2fcbc1d719 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.c @@ -1173,6 +1173,7 @@ int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, { int ret = OIS_ERROR; int i = 0; + int j = 0; uint8_t standby_flag = 0; AW_LOGI("enter"); @@ -1192,11 +1193,20 @@ int aw86006_firmware_update(struct cam_ois_ctrl_t *o_ctrl, } mdelay(AW_RESET_DELAY); /* run app after reset */ /* Get standby flag */ - for (i = 0; i < AW_ERROR_LOOP; i++) { - aw86006_get_standby_flag(o_ctrl, &standby_flag); + for (j = 0; j < AW_ERROR_LOOP; j++) { + for (i = 0; i < AW_ERROR_LOOP; i++) { + aw86006_get_standby_flag(o_ctrl, &standby_flag); + if (standby_flag == AW_IC_STANDBY) + break; + mdelay(AW_RESET_DELAY); + } + //Retry reset + if((i == AW_ERROR_LOOP) && (standby_flag != AW_IC_STANDBY)){ + aw86006_reset(o_ctrl); + mdelay(AW_RESET_DELAY); + } if (standby_flag == AW_IC_STANDBY) break; - mdelay(AW_RESET_DELAY); } if (standby_flag == AW_IC_STANDBY) { diff --git a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h index c302095c7a61..62e2f429053a 100644 --- a/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h +++ b/drivers/cam_sensor_module/cam_ois/cam_ois_aw86006.h @@ -43,7 +43,7 @@ /* Loop */ #define AW_STAY_ON_MOVE_LOOP (20) #define AW_STAY_ON_BOOT_LOOP (20) -#define AW_ERROR_LOOP (5) +#define AW_ERROR_LOOP (3) #define AW_FLASH_WRITE_ERROR_LOOP (2) #define AW_FLASH_READ_ERROR_LOOP (2) #define AW_FLASH_ERASE_ERROR_LOOP (2) From 057002666633da6ddd552221c96f9d78dd31c6ca Mon Sep 17 00:00:00 2001 From: zhanggc10 Date: Fri, 20 Oct 2023 11:02:05 +0800 Subject: [PATCH 85/86] fogo: Fix secure mode switch error (2/2) Detail: For secure camera case, sometime switch secure mode fail,so add retry logic to fix it Change-Id: I7062e06aaf2aaaa3092774ea41afc49b8f1e7cc7 Signed-off-by: zhanggc10 Reviewed-on: https://gerrit.mot.com/2773005 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_csiphy/cam_csiphy_core.c | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index c1a2a53c9d10..f27b79cfa344 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -36,6 +36,10 @@ /* Mask to enable skew calibration registers */ #define SKEW_CAL_MASK 0x2 +#ifdef CONFIG_MOT_SECURE_CAMERA +#define QCOM_SCM_EBUSY_MAX_RETRY 5 +#endif + static DEFINE_MUTEX(active_csiphy_cnt_mutex); static int csiphy_dump; @@ -1091,6 +1095,10 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, struct cam_control *cmd = (struct cam_control *)arg; int32_t rc = 0; +#ifdef CONFIG_MOT_SECURE_CAMERA + int32_t retry_count = 0; +#endif + if (!csiphy_dev || !cmd) { CAM_ERR(CAM_CSIPHY, "Invalid input args"); return -EINVAL; @@ -1287,7 +1295,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, cam_csiphy_update_lane(csiphy_dev, offset, false); goto release_mutex; } - +#ifndef CONFIG_MOT_SECURE_CAMERA if (csiphy_dev->csiphy_info[offset].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, @@ -1295,6 +1303,29 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; +#else + retry_count = 0; +retry_a: + retry_count++; + + if (csiphy_dev->csiphy_info[offset].secure_mode) { + rc = cam_csiphy_notify_secure_mode( + csiphy_dev, + CAM_SECURE_MODE_NON_SECURE, offset); + if (rc <0 && retry_count <= QCOM_SCM_EBUSY_MAX_RETRY) { + CAM_INFO(CAM_CSIPHY, "CAM_STOP_PHYDEV: scm call with count: %d,",retry_count); + goto retry_a; + } else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){ + CAM_INFO(CAM_CSIPHY, "CAM_STOP_PHYDEV: notify secure mode finally failed scm call with count: %d,",retry_count); + goto release_mutex; + + } else { + csiphy_dev->csiphy_info[offset].secure_mode = + CAM_SECURE_MODE_NON_SECURE; + } + } + +#endif csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0; @@ -1350,6 +1381,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } +#ifndef CONFIG_MOT_SECURE_CAMERA if (csiphy_dev->csiphy_info[offset].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, @@ -1357,6 +1389,28 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; +#else + retry_count = 0; +retry_b: + retry_count++; + + if (csiphy_dev->csiphy_info[offset].secure_mode) { + rc = cam_csiphy_notify_secure_mode( + csiphy_dev, + CAM_SECURE_MODE_NON_SECURE, offset); + if (rc <0 && retry_count <= QCOM_SCM_EBUSY_MAX_RETRY) { + CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: zhp scm call with count: %d,",retry_count); + goto retry_b; + } else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){ + CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: zhp notify secure mode finally failed scm call with count: %d,",retry_count); + goto release_mutex; + + } else { + csiphy_dev->csiphy_info[offset].secure_mode = + CAM_SECURE_MODE_NON_SECURE; + } + } +#endif csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0; From b111c17738dbbcf6b59fc27eb28654c5117aec77 Mon Sep 17 00:00:00 2001 From: Xuehui Ye Date: Wed, 1 Nov 2023 15:39:14 +0800 Subject: [PATCH 86/86] fogo: fix tombstone when use secure camera details: keep qcom's original call flow Change-Id: I4ec83f60ab9d3a8bd2960c8c0f14e7dba16ba14d Reviewed-on: https://gerrit.mot.com/2782622 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Binsheng Que Reviewed-by: Reviewed-by: Zhichao Chen Submit-Approved: Jira Key --- .../cam_csiphy/cam_csiphy_core.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index f27b79cfa344..c06e867a185d 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -1317,14 +1317,13 @@ retry_a: goto retry_a; } else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){ CAM_INFO(CAM_CSIPHY, "CAM_STOP_PHYDEV: notify secure mode finally failed scm call with count: %d,",retry_count); - goto release_mutex; - - } else { - csiphy_dev->csiphy_info[offset].secure_mode = - CAM_SECURE_MODE_NON_SECURE; } + } + csiphy_dev->csiphy_info[offset].secure_mode = + CAM_SECURE_MODE_NON_SECURE; + #endif csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0; @@ -1399,17 +1398,15 @@ retry_b: csiphy_dev, CAM_SECURE_MODE_NON_SECURE, offset); if (rc <0 && retry_count <= QCOM_SCM_EBUSY_MAX_RETRY) { - CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: zhp scm call with count: %d,",retry_count); + CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: scm call with count: %d,",retry_count); goto retry_b; } else if (rc <0 && retry_count > QCOM_SCM_EBUSY_MAX_RETRY){ - CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: zhp notify secure mode finally failed scm call with count: %d,",retry_count); - goto release_mutex; - - } else { - csiphy_dev->csiphy_info[offset].secure_mode = - CAM_SECURE_MODE_NON_SECURE; + CAM_INFO(CAM_CSIPHY, "CAM_RELEASE_PHYDEV: notify secure mode finally failed scm call with count: %d,",retry_count); } } + + csiphy_dev->csiphy_info[offset].secure_mode = + CAM_SECURE_MODE_NON_SECURE; #endif csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0;