From eb14c6118f6446db24127413558086a279790184 Mon Sep 17 00:00:00 2001 From: liuwang2 Date: Tue, 14 Dec 2021 16:58:58 +0800 Subject: [PATCH] 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]; }; /**