ois: enable active ois

[detail]
enable active ois for milan5G dw9781c

Change-Id: I48087bbcc20ad23d91469e40bbe3054714a12f08
Signed-off-by: liuwang2 <liuwang2@lenovo.com>
Reviewed-on: https://gerrit.mot.com/2126132
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: XiaoFeng Wang <wangxf32@lenovo.com>
Reviewed-by: <yinhy6@motorola.com>
Reviewed-by: Long Cheng <chengl1@motorola.com>
Reviewed-by: Ji Zhao <zhaoji1@lenovo.com>
Reviewed-by: Zhuoran Xu <xuzr3@motorola.com>
Reviewed-by: Zhichao Chen <chenzc2@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
liuwang2 2021-11-24 17:41:50 +08:00 • committed by zhaoji1
commit fdd0555708
3 changed files with 216 additions and 2 deletions

View file

@ -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 *)&timestamp, 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));

View file

@ -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;
};

View file

@ -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 {