msm: camera: sensor: Infrastructure to support OIS FW download V2

Add 16 bit data read/write. Add new FW information
cmd parser. Add new FW download v2. Force CCI burst/
sequential write to be queued into Q0.

CRs-Fixed: 3322287
External Impact: No.

Change-Id: I8a1ea42b01a3748f466a9bc6083a799b939e6d02
Signed-off-by: Yulei Yao <quic_yuleiy@quicinc.com>
This commit is contained in:
Yulei Yao
2022-10-28 10:24:13 +08:00
committed by Camera Software Integration
parent 2c9200df57
commit 8202146af3
7 changed files with 708 additions and 45 deletions

View File

@@ -1910,8 +1910,6 @@ static int32_t cam_cci_write(struct v4l2_subdev *sd,
SYNC_QUEUE, MSM_SYNC_ENABLE);
break;
case MSM_CCI_I2C_WRITE:
case MSM_CCI_I2C_WRITE_SEQ:
case MSM_CCI_I2C_WRITE_BURST:
for (i = 0; i < NUM_QUEUES; i++) {
if (mutex_trylock(&cci_master_info->mutex_q[i])) {
rc = cam_cci_i2c_write(sd, c_ctrl, i,
@@ -1925,6 +1923,13 @@ static int32_t cam_cci_write(struct v4l2_subdev *sd,
PRIORITY_QUEUE, MSM_SYNC_DISABLE);
mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
break;
case MSM_CCI_I2C_WRITE_SEQ:
case MSM_CCI_I2C_WRITE_BURST:
mutex_lock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
rc = cam_cci_i2c_write(sd, c_ctrl,
PRIORITY_QUEUE, MSM_SYNC_DISABLE);
mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
break;
case MSM_CCI_I2C_WRITE_ASYNC:
rc = cam_cci_i2c_write_async(sd, c_ctrl,
PRIORITY_QUEUE, MSM_SYNC_DISABLE);

View File

@@ -239,10 +239,12 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set)
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
size = i2c_list->i2c_settings.size;
/* qtimer is 8 bytes so validate here*/
if (size < 8) {
if (size * (uint32_t)(i2c_list->i2c_settings.data_type) != 8) {
CAM_ERR(CAM_OIS, "Invalid write time settings");
return -EINVAL;
}
switch (i2c_list->i2c_settings.data_type) {
case CAMERA_SENSOR_I2C_TYPE_BYTE:
for (i = 0; i < size; i++) {
CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
i, (qtime_ns & 0xFF));
@@ -250,6 +252,22 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set)
(qtime_ns & 0xFF);
qtime_ns >>= 8;
}
break;
case CAMERA_SENSOR_I2C_TYPE_WORD:
for (i = 0; i < size; i++) {
CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
i, (qtime_ns & 0xFFFF));
i2c_list->i2c_settings.reg_setting[i].reg_data =
(qtime_ns & 0xFFFF);
qtime_ns >>= 16;
}
break;
default:
CAM_ERR(CAM_OIS, "Unsupported reg data type!");
return -EINVAL;
}
}
}
@@ -356,6 +374,244 @@ static int cam_ois_slaveInfo_pkt_parser(struct cam_ois_ctrl_t *o_ctrl,
return rc;
}
static int cam_ois_parse_fw_setting(uint8_t *cmd_buf, uint32_t size,
struct i2c_settings_array *reg_settings)
{
int32_t rc = 0;
uint32_t byte_cnt = 0;
struct common_header *cmm_hdr;
uint16_t op_code;
uint32_t j = 0;
struct list_head *list = NULL;
while (byte_cnt < size) {
if ((size - byte_cnt) < sizeof(struct common_header)) {
CAM_ERR(CAM_SENSOR, "Not enough buffer");
rc = -EINVAL;
goto end;
}
cmm_hdr = (struct common_header *)cmd_buf;
op_code = cmm_hdr->fifth_byte;
CAM_DBG(CAM_SENSOR, "Command Type:%d, Op code:%d",
cmm_hdr->cmd_type, op_code);
switch (cmm_hdr->cmd_type) {
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: {
uint32_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_random_wr
*cam_cmd_i2c_random_wr =
(struct cam_cmd_i2c_random_wr *)cmd_buf;
if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_random_wr)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided,size %d,byte_cnt %d",
size, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_random_write(
cam_cmd_i2c_random_wr,
reg_settings,
&cmd_length_in_bytes, &j, &list);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in random write %d", rc);
goto end;
}
byte_cnt += sizeof(struct cam_cmd_i2c_random_wr);
cmd_buf += sizeof(struct cam_cmd_i2c_random_wr);
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_WR: {
uint32_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_continuous_wr
*cam_cmd_i2c_continuous_wr =
(struct cam_cmd_i2c_continuous_wr *)cmd_buf;
if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_continuous_wr)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided,size %d,byte_cnt %d",
size, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_continuous_write(
cam_cmd_i2c_continuous_wr,
reg_settings,
&cmd_length_in_bytes, &j, &list);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in continuous write %d", rc);
goto end;
}
byte_cnt += sizeof(struct cam_cmd_i2c_continuous_wr);
cmd_buf += sizeof(struct cam_cmd_i2c_continuous_wr);
break;
}
case CAMERA_SENSOR_CMD_TYPE_WAIT: {
if (op_code == CAMERA_SENSOR_WAIT_OP_HW_UCND ||
op_code == CAMERA_SENSOR_WAIT_OP_SW_UCND) {
if ((size - byte_cnt) <
sizeof(struct cam_cmd_unconditional_wait)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided,size %d,byte_cnt %d",
size, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_delay(
(uint32_t **)(&cmd_buf), op_code,
reg_settings, j, &byte_cnt,
list);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"delay hdl failed: %d",
rc);
goto end;
}
}
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_random_rd *i2c_random_rd =
(struct cam_cmd_i2c_random_rd *)cmd_buf;
if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_random_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided,size %d,byte_cnt %d",
size, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_random_read(
i2c_random_rd,
reg_settings,
&cmd_length_in_bytes, &j, &list,
NULL);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in random read %d", rc);
goto end;
}
byte_cnt += sizeof(struct cam_cmd_i2c_random_rd);
cmd_buf += sizeof(struct cam_cmd_i2c_random_rd);
break;
}
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: {
uint16_t cmd_length_in_bytes = 0;
struct cam_cmd_i2c_continuous_rd
*i2c_continuous_rd =
(struct cam_cmd_i2c_continuous_rd *)cmd_buf;
if ((size - byte_cnt) < sizeof(struct cam_cmd_i2c_continuous_rd)) {
CAM_ERR(CAM_SENSOR,
"Not enough buffer provided,size %d,byte_cnt %d",
size, byte_cnt);
rc = -EINVAL;
goto end;
}
rc = cam_sensor_handle_continuous_read(
i2c_continuous_rd,
reg_settings,
&cmd_length_in_bytes, &j, &list,
NULL);
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"Failed in continuous read %d", rc);
goto end;
}
byte_cnt += sizeof(struct cam_cmd_i2c_continuous_rd);
cmd_buf += sizeof(struct cam_cmd_i2c_continuous_rd);
break;
}
default:
CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
cmm_hdr->cmd_type);
rc = -EINVAL;
goto end;
}
}
end:
return rc;
}
static int cam_ois_fw_info_pkt_parser(struct cam_ois_ctrl_t *o_ctrl,
uint32_t *cmd_buf, size_t len)
{
int32_t rc = 0;
struct cam_cmd_ois_fw_info *ois_fw_info;
uint8_t *pSettingData = NULL;
uint32_t size;
struct i2c_settings_array *reg_settings = NULL;
uint8_t count = 0;
uint32_t idx;
if (!o_ctrl || !cmd_buf || len < sizeof(struct cam_cmd_ois_fw_info)) {
CAM_ERR(CAM_OIS, "Invalid Args,o_ctrl %p,cmd_buf %p,len %d",
o_ctrl, cmd_buf, len);
return -EINVAL;
}
ois_fw_info = (struct cam_cmd_ois_fw_info *)cmd_buf;
CAM_DBG(CAM_SENSOR, "fw_count %d, endianness %d",
ois_fw_info->fw_count, ois_fw_info->endianness);
if (ois_fw_info->fw_count <= MAX_OIS_FW_COUNT) {
memcpy(&o_ctrl->fw_info, ois_fw_info, sizeof(struct cam_cmd_ois_fw_info));
pSettingData = (uint8_t *)cmd_buf + sizeof(struct cam_cmd_ois_fw_info);
for (count = 0; count < ois_fw_info->fw_count*2; count++) {
idx = count / 2;
/* init settings */
if ((count & 0x1) == 0) {
size = ois_fw_info->fw_param[idx].fw_init_size;
reg_settings = &o_ctrl->i2c_fw_init_data[idx];
CAM_DBG(CAM_SENSOR, "init size %d", size);
/* finalize settings */
} else if ((count & 0x1) == 1) {
size = ois_fw_info->fw_param[idx].fw_finalize_size;
reg_settings = &o_ctrl->i2c_fw_finalize_data[idx];
CAM_DBG(CAM_SENSOR, "finalize size %d", size);
} else {
size = 0;
CAM_DBG(CAM_SENSOR, "Unsupported case!");
return -EINVAL;
}
if (size != 0) {
reg_settings->is_settings_valid = 1;
rc = cam_ois_parse_fw_setting(pSettingData, size, reg_settings);
}
if (rc) {
CAM_ERR(CAM_OIS, "Failed to parse fw setting!");
return rc;
}
pSettingData += size;
}
} else {
CAM_ERR(CAM_OIS, "Exceed max fw count!");
}
return rc;
}
static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl)
{
uint16_t total_bytes = 0;
@@ -480,6 +736,207 @@ release_firmware:
return rc;
}
static inline uint32_t swap_high_byte_and_low_byte(uint8_t *src,
uint8_t data_type)
{
uint32_t ret_value = 0x00;
uint8_t cycle = 0;
for (cycle = 0; cycle < data_type; cycle++)
ret_value = ((ret_value<<8) | ((*(src+cycle))&0xff));
return ret_value;
}
static int write_ois_fw(uint8_t *fw_data, enum cam_endianness_type endianness,
struct cam_cmd_ois_fw_param *fw_param, struct camera_io_master io_master_info,
uint8_t i2c_operation)
{
int32_t rc = 0;
struct cam_sensor_i2c_reg_setting setting;
uint8_t *ptr = fw_data;
int32_t cnt = 0, wcnt = 0;
void *vaddr = NULL;
uint16_t data_type = fw_param->fw_data_type;
uint16_t len_per_write = fw_param->fw_len_per_write /
fw_param->fw_data_type;
vaddr = vmalloc((sizeof(struct cam_sensor_i2c_reg_array) * len_per_write));
if (!vaddr) {
CAM_ERR(CAM_OIS,
"Failed in allocating i2c_array: size: %u",
(sizeof(struct cam_sensor_i2c_reg_array) * len_per_write));
return -ENOMEM;
}
setting.reg_setting = (struct cam_sensor_i2c_reg_array *) (vaddr);
setting.addr_type = fw_param->fw_addr_type;
setting.data_type = fw_param->fw_data_type;
setting.size = len_per_write;
setting.delay = fw_param->fw_delayUs;
for (wcnt = 0; wcnt < (fw_param->fw_size/data_type); wcnt += len_per_write) {
for (cnt = 0; cnt < len_per_write; cnt++, ptr += data_type) {
setting.reg_setting[cnt].reg_addr =
fw_param->fw_reg_addr + wcnt + cnt;
/* Big */
if (endianness == CAM_ENDIANNESS_BIG) {
setting.reg_setting[cnt].reg_data =
swap_high_byte_and_low_byte(ptr, data_type);
/* Little */
} else if (endianness == CAM_ENDIANNESS_LITTLE) {
switch (data_type) {
case CAMERA_SENSOR_I2C_TYPE_BYTE:
setting.reg_setting[cnt].reg_data = *((uint8_t *)ptr);
break;
case CAMERA_SENSOR_I2C_TYPE_WORD:
setting.reg_setting[cnt].reg_data = *((uint16_t *)ptr);
break;
default:
CAM_ERR(CAM_OIS,
"Unsupported data type");
rc = -EINVAL;
goto End;
}
}
setting.reg_setting[cnt].delay = fw_param->fw_delayUs;
setting.reg_setting[cnt].data_mask = 0;
}
if (i2c_operation == CAM_SENSOR_I2C_WRITE_RANDOM) {
rc = camera_io_dev_write(&(io_master_info),
&setting);
} else if (i2c_operation == CAM_SENSOR_I2C_WRITE_BURST ||
i2c_operation == CAM_SENSOR_I2C_WRITE_SEQ) {
rc = camera_io_dev_write_continuous(&io_master_info,
&setting, i2c_operation);
}
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Failed in Applying i2c wrt settings");
break;
}
}
End:
vfree(vaddr);
vaddr = NULL;
return rc;
}
static int cam_ois_fw_download_v2(struct cam_ois_ctrl_t *o_ctrl)
{
int32_t rc = 0;
struct cam_cmd_ois_fw_param *fw_param = NULL;
uint32_t fw_size;
uint16_t len_per_write = 0;
uint8_t *ptr = NULL;
const struct firmware *fw = NULL;
struct device *dev = &(o_ctrl->pdev->dev);
uint8_t count = 0;
uint8_t cont_wr_flag = 0;
if (!o_ctrl) {
CAM_ERR(CAM_OIS, "Invalid Args");
return -EINVAL;
}
for (count = 0; count < o_ctrl->fw_info.fw_count; count++) {
fw_param = &o_ctrl->fw_info.fw_param[count];
fw_size = fw_param->fw_size;
len_per_write = fw_param->fw_len_per_write / fw_param->fw_data_type;
CAM_DBG(CAM_OIS, "count: %d, fw_size: %d, data_type: %d, len_per_write: %d",
count, fw_size, fw_param->fw_data_type, len_per_write);
/* Load FW */
rc = request_firmware(&fw, fw_param->fw_name, dev);
if (rc) {
CAM_ERR(CAM_OIS, "Failed to locate %s", fw_param->fw_name);
return rc;
}
if (0 == rc && NULL != fw &&
(fw_size <= fw->size - fw_param->fw_start_pos)) {
/* fw init */
CAM_DBG(CAM_OIS, "fw init");
if (o_ctrl->i2c_fw_init_data[count].is_settings_valid == 1) {
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fw_init_data[count]);
if ((rc == -EAGAIN) &&
(o_ctrl->io_master_info.master_type == CCI_MASTER)) {
CAM_WARN(CAM_OIS,
"CCI HW is resetting: Reapplying FW init settings");
usleep_range(1000, 1010);
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fw_init_data[count]);
}
if (rc) {
CAM_ERR(CAM_OIS,
"Cannot apply FW init settings %d",
rc);
goto release_firmware;
} else {
CAM_DBG(CAM_OIS, "OIS FW init settings success");
}
}
/* send fw */
CAM_DBG(CAM_OIS, "send fw, operation %d", fw_param->fw_operation);
ptr = (uint8_t *)(fw->data + fw_param->fw_start_pos);
if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_RNDM_WR)
cont_wr_flag = CAM_SENSOR_I2C_WRITE_RANDOM;
else if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
cont_wr_flag = CAM_SENSOR_I2C_WRITE_BURST;
else if (fw_param->fw_operation == CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN)
cont_wr_flag = CAM_SENSOR_I2C_WRITE_SEQ;
write_ois_fw(ptr, o_ctrl->fw_info.endianness, fw_param,
o_ctrl->io_master_info, cont_wr_flag);
/* fw finalize */
CAM_DBG(CAM_OIS, "fw finalize");
if (o_ctrl->i2c_fw_finalize_data[count].is_settings_valid == 1) {
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fw_finalize_data[count]);
if ((rc == -EAGAIN) &&
(o_ctrl->io_master_info.master_type == CCI_MASTER)) {
CAM_WARN(CAM_OIS,
"CCI HW is resetting: Reapplying FW finalize settings");
usleep_range(1000, 1010);
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fw_finalize_data[count]);
}
if (rc) {
CAM_ERR(CAM_OIS,
"Cannot apply FW finalize settings %d",
rc);
goto release_firmware;
} else {
CAM_DBG(CAM_OIS, "OIS FW finalize settings success");
}
}
}
if (fw != NULL) {
release_firmware(fw);
fw = NULL;
}
}
release_firmware:
if (fw != NULL) {
release_firmware(fw);
fw = NULL;
}
return rc;
}
/**
* cam_ois_pkt_parse - Parse csl packet
* @o_ctrl: ctrl structure
@@ -543,13 +1000,13 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
switch (csl_packet->header.op_code & 0xFFFFFF) {
case CAM_OIS_PACKET_OPCODE_INIT:
CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_INIT,num_cmd_buf %d",
csl_packet->num_cmd_buf);
offset = (uint32_t *)&csl_packet->payload;
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
CAM_DBG(CAM_OIS, "num_cmd_buf %d",
csl_packet->num_cmd_buf);
/* Loop through multiple command buffers */
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
total_cmd_buf_in_bytes = cmd_desc[i].length;
@@ -580,6 +1037,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
cmm_hdr = (struct common_header *)cmd_buf;
CAM_DBG(CAM_OIS,
"cmm_hdr->cmd_type: %d", cmm_hdr->cmd_type);
switch (cmm_hdr->cmd_type) {
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
rc = cam_ois_slaveInfo_pkt_parser(
@@ -604,6 +1063,18 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
return rc;
}
break;
case CAMERA_SENSOR_OIS_CMD_TYPE_FW_INFO:
CAM_DBG(CAM_OIS,
"Received fwInfo buffer,total_cmd_buf_in_bytes: %d",
total_cmd_buf_in_bytes);
rc = cam_ois_fw_info_pkt_parser(
o_ctrl, cmd_buf, total_cmd_buf_in_bytes);
if (rc) {
CAM_ERR(CAM_OIS,
"Failed: parse fw info settings");
return rc;
}
break;
default:
if (o_ctrl->i2c_init_data.is_settings_valid == 0) {
CAM_DBG(CAM_OIS,
@@ -649,9 +1120,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
i2c_reg_settings,
&cmd_desc[i], 1, NULL);
if (rc < 0) {
CAM_ERR(CAM_OIS,
CAM_DBG(CAM_OIS,
"fw init parsing failed: %d", rc);
return rc;
}
}
break;
@@ -667,13 +1137,24 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
o_ctrl->cam_ois_state = CAM_OIS_CONFIG;
}
CAM_DBG(CAM_OIS, "ois_fw_flag: %d", o_ctrl->ois_fw_flag);
if (o_ctrl->ois_fw_flag) {
CAM_DBG(CAM_OIS, "fw_count: %d", o_ctrl->fw_info.fw_count);
if (o_ctrl->fw_info.fw_count != 0) {
rc = cam_ois_fw_download_v2(o_ctrl);
if (rc) {
CAM_ERR(CAM_OIS, "Failed OIS FW Download v2");
goto pwr_dwn;
}
} else {
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1) {
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fwinit_data);
if ((rc == -EAGAIN) &&
(o_ctrl->io_master_info.master_type == CCI_MASTER)) {
(o_ctrl->io_master_info.master_type ==
CCI_MASTER)) {
CAM_WARN(CAM_OIS,
"CCI HW is restting: Reapplying fwinit settings");
"Reapplying fwinit settings");
usleep_range(1000, 1010);
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_fwinit_data);
@@ -686,15 +1167,15 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
} else {
CAM_DBG(CAM_OIS, "OIS fwinit settings success");
}
}
if (o_ctrl->ois_fw_flag) {
rc = cam_ois_fw_download(o_ctrl);
if (rc) {
CAM_ERR(CAM_OIS, "Failed OIS FW Download");
goto pwr_dwn;
}
}
}
}
rc = cam_ois_apply_settings(o_ctrl, &o_ctrl->i2c_init_data);
if ((rc == -EAGAIN) &&
@@ -705,6 +1186,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = cam_ois_apply_settings(o_ctrl,
&o_ctrl->i2c_init_data);
}
if (rc < 0) {
CAM_ERR(CAM_OIS,
"Cannot apply Init settings: rc = %d",
@@ -740,6 +1222,25 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
rc = 0;
}
for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_init_data: rc: %d", rc);
rc = 0;
}
}
if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_finalize_data: rc: %d", rc);
rc = 0;
}
}
}
rc = delete_request(&o_ctrl->i2c_init_data);
if (rc < 0) {
CAM_WARN(CAM_OIS,
@@ -754,6 +1255,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
}
break;
case CAM_OIS_PACKET_OPCODE_OIS_CONTROL:
CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_OIS_CONTROL");
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_OIS,
@@ -793,6 +1295,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
struct cam_buf_io_cfg *io_cfg;
struct i2c_settings_array i2c_read_settings;
CAM_DBG(CAM_OIS, "CAM_OIS_PACKET_OPCODE_READ");
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
rc = -EINVAL;
CAM_WARN(CAM_OIS,
@@ -869,6 +1373,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
break;
}
case CAM_OIS_PACKET_OPCODE_WRITE_TIME: {
CAM_DBG(CAM_OIS,
"CAM_OIS_PACKET_OPCODE_WRITE_TIME");
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
rc = -EINVAL;
CAM_ERR(CAM_OIS,
@@ -925,7 +1431,7 @@ pwr_dwn:
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
{
int rc = 0;
int rc = 0, i = 0;
struct cam_ois_soc_private *soc_private =
(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
@@ -952,6 +1458,25 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_fwinit_data);
for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_init_data: rc: %d", rc);
rc = 0;
}
}
if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_finalize_data: rc: %d", rc);
rc = 0;
}
}
}
if (o_ctrl->i2c_mode_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_mode_data);
@@ -980,7 +1505,7 @@ void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
*/
int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
{
int rc = 0;
int rc = 0, i = 0;
struct cam_ois_query_cap_t ois_cap = {0};
struct cam_control *cmd = (struct cam_control *)arg;
struct cam_ois_soc_private *soc_private = NULL;
@@ -1091,6 +1616,25 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *o_ctrl, void *arg)
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
delete_request(&o_ctrl->i2c_fwinit_data);
for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
if (o_ctrl->i2c_fw_init_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_init_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_init_data: rc: %d", rc);
rc = 0;
}
}
if (o_ctrl->i2c_fw_finalize_data[i].is_settings_valid == 1) {
rc = delete_request(&o_ctrl->i2c_fw_finalize_data[i]);
if (rc < 0) {
CAM_WARN(CAM_OIS,
"Fail deleting i2c_fw_finalize_data: rc: %d", rc);
rc = 0;
}
}
}
break;
case CAM_STOP_DEV:
if (o_ctrl->cam_ois_state != CAM_OIS_START) {

View File

@@ -334,7 +334,7 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client)
static int cam_ois_component_bind(struct device *dev,
struct device *master_dev, void *data)
{
int32_t rc = 0;
int32_t rc = 0, i = 0;
struct cam_ois_ctrl_t *o_ctrl = NULL;
struct cam_ois_soc_private *soc_private = NULL;
bool i3c_i2c_target;
@@ -370,9 +370,15 @@ static int cam_ois_component_bind(struct device *dev,
o_ctrl->soc_info.soc_private = soc_private;
soc_private->power_info.dev = &pdev->dev;
memset(&o_ctrl->fw_info, 0, sizeof(struct cam_cmd_ois_fw_info));
INIT_LIST_HEAD(&(o_ctrl->i2c_init_data.list_head));
INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head));
INIT_LIST_HEAD(&(o_ctrl->i2c_fwinit_data.list_head));
for (i = 0; i < MAX_OIS_FW_COUNT; i++) {
INIT_LIST_HEAD(&(o_ctrl->i2c_fw_init_data[i].list_head));
INIT_LIST_HEAD(&(o_ctrl->i2c_fw_finalize_data[i].list_head));
}
INIT_LIST_HEAD(&(o_ctrl->i2c_mode_data.list_head));
INIT_LIST_HEAD(&(o_ctrl->i2c_time_data.list_head));
mutex_init(&(o_ctrl->ois_mutex));

View File

@@ -121,6 +121,9 @@ struct cam_ois_ctrl_t {
uint8_t ois_fw_flag;
uint8_t is_ois_calib;
struct cam_ois_opcode opcode;
struct cam_cmd_ois_fw_info fw_info;
struct i2c_settings_array i2c_fw_init_data[MAX_OIS_FW_COUNT];
struct i2c_settings_array i2c_fw_finalize_data[MAX_OIS_FW_COUNT];
};
/**

View File

@@ -304,7 +304,7 @@ int32_t cam_sensor_handle_random_write(
return rc;
}
static int32_t cam_sensor_handle_continuous_write(
int32_t cam_sensor_handle_continuous_write(
struct cam_cmd_i2c_continuous_wr *cam_cmd_i2c_continuous_wr,
struct i2c_settings_array *i2c_reg_settings,
uint32_t *cmd_length_in_bytes, int32_t *offset,
@@ -450,7 +450,7 @@ int32_t cam_sensor_util_write_qtimer_to_io_buffer(
return rc;
}
static int32_t cam_sensor_handle_random_read(
int32_t cam_sensor_handle_random_read(
struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes,
@@ -498,7 +498,7 @@ static int32_t cam_sensor_handle_random_read(
return rc;
}
static int32_t cam_sensor_handle_continuous_read(
int32_t cam_sensor_handle_continuous_read(
struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes, int32_t *offset,

View File

@@ -52,6 +52,40 @@ int32_t cam_sensor_util_get_current_qtimer_ns(uint64_t *qtime_ns);
int32_t cam_sensor_util_write_qtimer_to_io_buffer(
uint64_t qtime_ns, struct cam_buf_io_cfg *io_cfg);
int32_t cam_sensor_handle_random_write(
struct cam_cmd_i2c_random_wr *cam_cmd_i2c_random_wr,
struct i2c_settings_array *i2c_reg_settings,
uint32_t *cmd_length_in_bytes, int32_t *offset,
struct list_head **list);
int32_t cam_sensor_handle_continuous_write(
struct cam_cmd_i2c_continuous_wr *cam_cmd_i2c_continuous_wr,
struct i2c_settings_array *i2c_reg_settings,
uint32_t *cmd_length_in_bytes, int32_t *offset,
struct list_head **list);
int32_t cam_sensor_handle_delay(
uint32_t **cmd_buf,
uint16_t generic_op_code,
struct i2c_settings_array *i2c_reg_settings,
uint32_t offset, uint32_t *byte_cnt,
struct list_head *list_ptr);
int32_t cam_sensor_handle_random_read(
struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes,
int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg);
int32_t cam_sensor_handle_continuous_read(
struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
struct i2c_settings_array *i2c_reg_settings,
uint16_t *cmd_length_in_bytes, int32_t *offset,
struct list_head **list,
struct cam_buf_io_cfg *io_cfg);
int cam_sensor_i2c_command_parser(struct camera_io_master *io_master,
struct i2c_settings_array *i2c_reg_settings,
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,

View File

@@ -14,6 +14,7 @@
#define CAM_SENSOR_PROBE_CMD (CAM_COMMON_OPCODE_MAX + 1)
#define CAM_FLASH_MAX_LED_TRIGGERS 2
#define MAX_OIS_NAME_SIZE 32
#define MAX_OIS_FW_COUNT 2
#define CAM_CSIPHY_SECURE_MODE_ENABLED 1
#define CAM_SENSOR_NAME_MAX_SIZE 32
@@ -57,6 +58,7 @@ enum camera_sensor_cmd_type {
CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET,
CAMERA_SENSOR_CMD_TYPE_RD_DATA,
CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE,
CAMERA_SENSOR_OIS_CMD_TYPE_FW_INFO,
CAMERA_SENSOR_CMD_TYPE_MAX,
};
@@ -87,6 +89,8 @@ enum camera_sensor_i2c_op_code {
CAMERA_SENSOR_I2C_OP_CONT_WR_BRST_VERF,
CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN,
CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN_VERF,
CAMERA_SENSOR_I2C_OP_RNDM_RD,
CAMERA_SENSOR_I2C_OP_CONT_RD,
CAMERA_SENSOR_I2C_OP_MAX,
};
@@ -120,6 +124,11 @@ enum cam_sensor_packet_opcodes {
CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127,
};
enum cam_endianness_type {
CAM_ENDIANNESS_BIG,
CAM_ENDIANNESS_LITTLE,
};
enum tpg_command_type_t {
TPG_CMD_TYPE_INVALID = 0,
TPG_CMD_TYPE_GLOBAL_CONFIG,
@@ -394,6 +403,68 @@ struct cam_cmd_ois_info {
struct cam_ois_opcode opcode;
} __attribute__((packed));
/**
* struct cam_cmd_ois_fw_param - Contains OIS firmware param
*
* NOTE: if this struct is updated,
* please also update version in struct cam_cmd_ois_fw_info
*
* @fw_name : firmware file name
* @fw_start_pos : data start position in file
* @fw_size : firmware size
* @fw_len_per_write: data length per write in bytes
* @fw_addr_type : addr type
* @fw_data_type : data type
* @fw_operation : type of operation
* @reserved : reserved for 32-bit alignment
* @fw_delayUs : delay in cci write
* @fw_reg_addr : start register addr to write
* @fw_init_size : size of fw download init settings
* @fw_finalize_size: size of fw download finalize settings
*/
struct cam_cmd_ois_fw_param {
char fw_name[MAX_OIS_NAME_SIZE];
__u32 fw_start_pos;
__u32 fw_size;
__u32 fw_len_per_write;
__u8 fw_addr_type;
__u8 fw_data_type;
__u8 fw_operation;
__u8 reserved;
__u32 fw_delayUs;
__u32 fw_reg_addr;
__u32 fw_init_size;
__u32 fw_finalize_size;
} __attribute__((packed));
/**
* struct cam_cmd_ois_fw_info - Contains OIS firmware info
*
* @version : version info
* NOTE: if struct cam_cmd_ois_fw_param is updated,
* version here needs to be updated too.
* @reserved : reserved
* @cmd_type : Explains type of command
* @fw_count : firmware count
* @endianness : firmware data's endianness
* @fw_param : includes firmware parameters
* @num_valid_params: Number of valid params
* @param_mask : Mask to indicate fields in params
* @params : Additional Params
*/
struct cam_cmd_ois_fw_info {
__u32 version;
__u8 reserved;
__u8 cmd_type;
__u8 fw_count;
__u8 endianness;
struct cam_cmd_ois_fw_param fw_param[MAX_OIS_FW_COUNT];
__u32 num_valid_params;
__u32 param_mask;
__u32 params[4];
} __attribute__((packed));
/**
* struct cam_cmd_probe - Contains sensor slave info
*