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:

committed by
Camera Software Integration

parent
2c9200df57
commit
8202146af3
@@ -1910,8 +1910,6 @@ static int32_t cam_cci_write(struct v4l2_subdev *sd,
|
|||||||
SYNC_QUEUE, MSM_SYNC_ENABLE);
|
SYNC_QUEUE, MSM_SYNC_ENABLE);
|
||||||
break;
|
break;
|
||||||
case MSM_CCI_I2C_WRITE:
|
case MSM_CCI_I2C_WRITE:
|
||||||
case MSM_CCI_I2C_WRITE_SEQ:
|
|
||||||
case MSM_CCI_I2C_WRITE_BURST:
|
|
||||||
for (i = 0; i < NUM_QUEUES; i++) {
|
for (i = 0; i < NUM_QUEUES; i++) {
|
||||||
if (mutex_trylock(&cci_master_info->mutex_q[i])) {
|
if (mutex_trylock(&cci_master_info->mutex_q[i])) {
|
||||||
rc = cam_cci_i2c_write(sd, c_ctrl, 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);
|
PRIORITY_QUEUE, MSM_SYNC_DISABLE);
|
||||||
mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
|
mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]);
|
||||||
break;
|
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:
|
case MSM_CCI_I2C_WRITE_ASYNC:
|
||||||
rc = cam_cci_i2c_write_async(sd, c_ctrl,
|
rc = cam_cci_i2c_write_async(sd, c_ctrl,
|
||||||
PRIORITY_QUEUE, MSM_SYNC_DISABLE);
|
PRIORITY_QUEUE, MSM_SYNC_DISABLE);
|
||||||
|
@@ -239,16 +239,34 @@ static int cam_ois_update_time(struct i2c_settings_array *i2c_set)
|
|||||||
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
|
if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
|
||||||
size = i2c_list->i2c_settings.size;
|
size = i2c_list->i2c_settings.size;
|
||||||
/* qtimer is 8 bytes so validate here*/
|
/* 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");
|
CAM_ERR(CAM_OIS, "Invalid write time settings");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < size; i++) {
|
switch (i2c_list->i2c_settings.data_type) {
|
||||||
CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
case CAMERA_SENSOR_I2C_TYPE_BYTE:
|
||||||
i, (qtime_ns & 0xFF));
|
for (i = 0; i < size; i++) {
|
||||||
i2c_list->i2c_settings.reg_setting[i].reg_data =
|
CAM_DBG(CAM_OIS, "time: reg_data[%d]: 0x%x",
|
||||||
(qtime_ns & 0xFF);
|
i, (qtime_ns & 0xFF));
|
||||||
qtime_ns >>= 8;
|
i2c_list->i2c_settings.reg_setting[i].reg_data =
|
||||||
|
(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;
|
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)
|
static int cam_ois_fw_download(struct cam_ois_ctrl_t *o_ctrl)
|
||||||
{
|
{
|
||||||
uint16_t total_bytes = 0;
|
uint16_t total_bytes = 0;
|
||||||
@@ -480,6 +736,207 @@ release_firmware:
|
|||||||
return rc;
|
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
|
* cam_ois_pkt_parse - Parse csl packet
|
||||||
* @o_ctrl: ctrl structure
|
* @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) {
|
switch (csl_packet->header.op_code & 0xFFFFFF) {
|
||||||
case CAM_OIS_PACKET_OPCODE_INIT:
|
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 = (uint32_t *)&csl_packet->payload;
|
||||||
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
|
offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
|
||||||
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
|
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 */
|
/* Loop through multiple command buffers */
|
||||||
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
|
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
|
||||||
total_cmd_buf_in_bytes = cmd_desc[i].length;
|
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);
|
cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
|
||||||
cmm_hdr = (struct common_header *)cmd_buf;
|
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) {
|
switch (cmm_hdr->cmd_type) {
|
||||||
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
|
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
|
||||||
rc = cam_ois_slaveInfo_pkt_parser(
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
if (o_ctrl->i2c_init_data.is_settings_valid == 0) {
|
if (o_ctrl->i2c_init_data.is_settings_valid == 0) {
|
||||||
CAM_DBG(CAM_OIS,
|
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,
|
i2c_reg_settings,
|
||||||
&cmd_desc[i], 1, NULL);
|
&cmd_desc[i], 1, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_OIS,
|
CAM_DBG(CAM_OIS,
|
||||||
"fw init parsing failed: %d", rc);
|
"fw init parsing failed: %d", rc);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -667,32 +1137,43 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|||||||
o_ctrl->cam_ois_state = CAM_OIS_CONFIG;
|
o_ctrl->cam_ois_state = CAM_OIS_CONFIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1) {
|
CAM_DBG(CAM_OIS, "ois_fw_flag: %d", o_ctrl->ois_fw_flag);
|
||||||
rc = cam_ois_apply_settings(o_ctrl,
|
|
||||||
&o_ctrl->i2c_fwinit_data);
|
|
||||||
if ((rc == -EAGAIN) &&
|
|
||||||
(o_ctrl->io_master_info.master_type == CCI_MASTER)) {
|
|
||||||
CAM_WARN(CAM_OIS,
|
|
||||||
"CCI HW is restting: Reapplying fwinit settings");
|
|
||||||
usleep_range(1000, 1010);
|
|
||||||
rc = cam_ois_apply_settings(o_ctrl,
|
|
||||||
&o_ctrl->i2c_fwinit_data);
|
|
||||||
}
|
|
||||||
if (rc) {
|
|
||||||
CAM_ERR(CAM_OIS,
|
|
||||||
"Cannot apply fwinit data %d",
|
|
||||||
rc);
|
|
||||||
goto pwr_dwn;
|
|
||||||
} else {
|
|
||||||
CAM_DBG(CAM_OIS, "OIS fwinit settings success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o_ctrl->ois_fw_flag) {
|
if (o_ctrl->ois_fw_flag) {
|
||||||
rc = cam_ois_fw_download(o_ctrl);
|
CAM_DBG(CAM_OIS, "fw_count: %d", o_ctrl->fw_info.fw_count);
|
||||||
if (rc) {
|
if (o_ctrl->fw_info.fw_count != 0) {
|
||||||
CAM_ERR(CAM_OIS, "Failed OIS FW Download");
|
rc = cam_ois_fw_download_v2(o_ctrl);
|
||||||
goto pwr_dwn;
|
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)) {
|
||||||
|
CAM_WARN(CAM_OIS,
|
||||||
|
"Reapplying fwinit settings");
|
||||||
|
usleep_range(1000, 1010);
|
||||||
|
rc = cam_ois_apply_settings(o_ctrl,
|
||||||
|
&o_ctrl->i2c_fwinit_data);
|
||||||
|
}
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS,
|
||||||
|
"Cannot apply fwinit data %d",
|
||||||
|
rc);
|
||||||
|
goto pwr_dwn;
|
||||||
|
} else {
|
||||||
|
CAM_DBG(CAM_OIS, "OIS fwinit settings success");
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_ois_fw_download(o_ctrl);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS, "Failed OIS FW Download");
|
||||||
|
goto pwr_dwn;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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,
|
rc = cam_ois_apply_settings(o_ctrl,
|
||||||
&o_ctrl->i2c_init_data);
|
&o_ctrl->i2c_init_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_OIS,
|
CAM_ERR(CAM_OIS,
|
||||||
"Cannot apply Init settings: rc = %d",
|
"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;
|
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);
|
rc = delete_request(&o_ctrl->i2c_init_data);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_WARN(CAM_OIS,
|
CAM_WARN(CAM_OIS,
|
||||||
@@ -754,6 +1255,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAM_OIS_PACKET_OPCODE_OIS_CONTROL:
|
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) {
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
CAM_WARN(CAM_OIS,
|
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 cam_buf_io_cfg *io_cfg;
|
||||||
struct i2c_settings_array i2c_read_settings;
|
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) {
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
CAM_WARN(CAM_OIS,
|
CAM_WARN(CAM_OIS,
|
||||||
@@ -869,6 +1373,8 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAM_OIS_PACKET_OPCODE_WRITE_TIME: {
|
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) {
|
if (o_ctrl->cam_ois_state < CAM_OIS_CONFIG) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
CAM_ERR(CAM_OIS,
|
CAM_ERR(CAM_OIS,
|
||||||
@@ -925,7 +1431,7 @@ pwr_dwn:
|
|||||||
|
|
||||||
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl)
|
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 *soc_private =
|
||||||
(struct cam_ois_soc_private *)o_ctrl->soc_info.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;
|
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)
|
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
|
||||||
delete_request(&o_ctrl->i2c_fwinit_data);
|
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)
|
if (o_ctrl->i2c_mode_data.is_settings_valid == 1)
|
||||||
delete_request(&o_ctrl->i2c_mode_data);
|
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 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_ois_query_cap_t ois_cap = {0};
|
||||||
struct cam_control *cmd = (struct cam_control *)arg;
|
struct cam_control *cmd = (struct cam_control *)arg;
|
||||||
struct cam_ois_soc_private *soc_private = NULL;
|
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)
|
if (o_ctrl->i2c_fwinit_data.is_settings_valid == 1)
|
||||||
delete_request(&o_ctrl->i2c_fwinit_data);
|
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;
|
break;
|
||||||
case CAM_STOP_DEV:
|
case CAM_STOP_DEV:
|
||||||
if (o_ctrl->cam_ois_state != CAM_OIS_START) {
|
if (o_ctrl->cam_ois_state != CAM_OIS_START) {
|
||||||
|
@@ -334,7 +334,7 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client)
|
|||||||
static int cam_ois_component_bind(struct device *dev,
|
static int cam_ois_component_bind(struct device *dev,
|
||||||
struct device *master_dev, void *data)
|
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_ctrl_t *o_ctrl = NULL;
|
||||||
struct cam_ois_soc_private *soc_private = NULL;
|
struct cam_ois_soc_private *soc_private = NULL;
|
||||||
bool i3c_i2c_target;
|
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;
|
o_ctrl->soc_info.soc_private = soc_private;
|
||||||
soc_private->power_info.dev = &pdev->dev;
|
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_init_data.list_head));
|
||||||
INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head));
|
INIT_LIST_HEAD(&(o_ctrl->i2c_calib_data.list_head));
|
||||||
INIT_LIST_HEAD(&(o_ctrl->i2c_fwinit_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_mode_data.list_head));
|
||||||
INIT_LIST_HEAD(&(o_ctrl->i2c_time_data.list_head));
|
INIT_LIST_HEAD(&(o_ctrl->i2c_time_data.list_head));
|
||||||
mutex_init(&(o_ctrl->ois_mutex));
|
mutex_init(&(o_ctrl->ois_mutex));
|
||||||
|
@@ -121,6 +121,9 @@ struct cam_ois_ctrl_t {
|
|||||||
uint8_t ois_fw_flag;
|
uint8_t ois_fw_flag;
|
||||||
uint8_t is_ois_calib;
|
uint8_t is_ois_calib;
|
||||||
struct cam_ois_opcode opcode;
|
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];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -304,7 +304,7 @@ int32_t cam_sensor_handle_random_write(
|
|||||||
return rc;
|
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 cam_cmd_i2c_continuous_wr *cam_cmd_i2c_continuous_wr,
|
||||||
struct i2c_settings_array *i2c_reg_settings,
|
struct i2c_settings_array *i2c_reg_settings,
|
||||||
uint32_t *cmd_length_in_bytes, int32_t *offset,
|
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;
|
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 cam_cmd_i2c_random_rd *cmd_i2c_random_rd,
|
||||||
struct i2c_settings_array *i2c_reg_settings,
|
struct i2c_settings_array *i2c_reg_settings,
|
||||||
uint16_t *cmd_length_in_bytes,
|
uint16_t *cmd_length_in_bytes,
|
||||||
@@ -498,7 +498,7 @@ static int32_t cam_sensor_handle_random_read(
|
|||||||
return rc;
|
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 cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd,
|
||||||
struct i2c_settings_array *i2c_reg_settings,
|
struct i2c_settings_array *i2c_reg_settings,
|
||||||
uint16_t *cmd_length_in_bytes, int32_t *offset,
|
uint16_t *cmd_length_in_bytes, int32_t *offset,
|
||||||
|
@@ -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(
|
int32_t cam_sensor_util_write_qtimer_to_io_buffer(
|
||||||
uint64_t qtime_ns, struct cam_buf_io_cfg *io_cfg);
|
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,
|
int cam_sensor_i2c_command_parser(struct camera_io_master *io_master,
|
||||||
struct i2c_settings_array *i2c_reg_settings,
|
struct i2c_settings_array *i2c_reg_settings,
|
||||||
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,
|
struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers,
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#define CAM_SENSOR_PROBE_CMD (CAM_COMMON_OPCODE_MAX + 1)
|
#define CAM_SENSOR_PROBE_CMD (CAM_COMMON_OPCODE_MAX + 1)
|
||||||
#define CAM_FLASH_MAX_LED_TRIGGERS 2
|
#define CAM_FLASH_MAX_LED_TRIGGERS 2
|
||||||
#define MAX_OIS_NAME_SIZE 32
|
#define MAX_OIS_NAME_SIZE 32
|
||||||
|
#define MAX_OIS_FW_COUNT 2
|
||||||
#define CAM_CSIPHY_SECURE_MODE_ENABLED 1
|
#define CAM_CSIPHY_SECURE_MODE_ENABLED 1
|
||||||
#define CAM_SENSOR_NAME_MAX_SIZE 32
|
#define CAM_SENSOR_NAME_MAX_SIZE 32
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ enum camera_sensor_cmd_type {
|
|||||||
CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET,
|
CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET,
|
||||||
CAMERA_SENSOR_CMD_TYPE_RD_DATA,
|
CAMERA_SENSOR_CMD_TYPE_RD_DATA,
|
||||||
CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE,
|
CAMERA_SENSOR_FLASH_CMD_TYPE_INIT_FIRE,
|
||||||
|
CAMERA_SENSOR_OIS_CMD_TYPE_FW_INFO,
|
||||||
CAMERA_SENSOR_CMD_TYPE_MAX,
|
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_BRST_VERF,
|
||||||
CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN,
|
CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN,
|
||||||
CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN_VERF,
|
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,
|
CAMERA_SENSOR_I2C_OP_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,6 +124,11 @@ enum cam_sensor_packet_opcodes {
|
|||||||
CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127,
|
CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum cam_endianness_type {
|
||||||
|
CAM_ENDIANNESS_BIG,
|
||||||
|
CAM_ENDIANNESS_LITTLE,
|
||||||
|
};
|
||||||
|
|
||||||
enum tpg_command_type_t {
|
enum tpg_command_type_t {
|
||||||
TPG_CMD_TYPE_INVALID = 0,
|
TPG_CMD_TYPE_INVALID = 0,
|
||||||
TPG_CMD_TYPE_GLOBAL_CONFIG,
|
TPG_CMD_TYPE_GLOBAL_CONFIG,
|
||||||
@@ -394,6 +403,68 @@ struct cam_cmd_ois_info {
|
|||||||
struct cam_ois_opcode opcode;
|
struct cam_ois_opcode opcode;
|
||||||
} __attribute__((packed));
|
} __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
|
* struct cam_cmd_probe - Contains sensor slave info
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user