mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 21:54:34 -04:00
camera: ois: support vsync interrupt
[detail] Use vsync interrupt timestamp for ois data timestamp. Change-Id: I56ffced64ad368129115067f84109d8a66663f59 Signed-off-by: liuwang2 <liuwang2@lenovo.com> Reviewed-on: https://gerrit.mot.com/2138044 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: XiaoFeng Wang <wangxf32@lenovo.com> Reviewed-by: <liuzy55@motorola.com> Reviewed-by: Long Cheng <chengl1@motorola.com> Reviewed-by: Zhichao Chen <chenzc2@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
fdd0555708
commit
0e977529ef
4 changed files with 83 additions and 24 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue