|
@@ -121,7 +121,7 @@ static void cam_sensor_release_per_frame_resource(
|
|
|
rc = delete_request(i2c_set);
|
|
|
if (rc < 0)
|
|
|
CAM_ERR(CAM_SENSOR,
|
|
|
- "delete request: %lld rc: %d",
|
|
|
+ "delete per frame setting for request: %lld rc: %d",
|
|
|
i2c_set->request_id, rc);
|
|
|
}
|
|
|
}
|
|
@@ -135,7 +135,21 @@ static void cam_sensor_release_per_frame_resource(
|
|
|
rc = delete_request(i2c_set);
|
|
|
if (rc < 0)
|
|
|
CAM_ERR(CAM_SENSOR,
|
|
|
- "delete request: %lld rc: %d",
|
|
|
+ "delete frame skip setting for request: %lld rc: %d",
|
|
|
+ i2c_set->request_id, rc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (s_ctrl->i2c_data.bubble_update != NULL) {
|
|
|
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
|
|
|
+ i2c_set = &(s_ctrl->i2c_data.bubble_update[i]);
|
|
|
+ if (i2c_set->is_settings_valid == 1) {
|
|
|
+ i2c_set->is_settings_valid = -1;
|
|
|
+ rc = delete_request(i2c_set);
|
|
|
+ if (rc < 0)
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "delete bubble update setting for request: %lld rc: %d",
|
|
|
i2c_set->request_id, rc);
|
|
|
}
|
|
|
}
|
|
@@ -146,6 +160,7 @@ static int cam_sensor_handle_res_info(struct cam_sensor_res_info *res_info,
|
|
|
struct cam_sensor_ctrl_t *s_ctrl)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
+ uint32_t idx = 0;
|
|
|
|
|
|
if (!s_ctrl || !res_info) {
|
|
|
CAM_ERR(CAM_SENSOR, "Invalid params: res_info: %s, s_ctrl: %s",
|
|
@@ -154,19 +169,30 @@ static int cam_sensor_handle_res_info(struct cam_sensor_res_info *res_info,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- s_ctrl->sensor_res.res_index = res_info->res_index;
|
|
|
- strscpy(s_ctrl->sensor_res.caps, res_info->caps,
|
|
|
- sizeof(s_ctrl->sensor_res.caps));
|
|
|
- s_ctrl->sensor_res.width = res_info->width;
|
|
|
- s_ctrl->sensor_res.height = res_info->height;
|
|
|
- s_ctrl->sensor_res.fps = res_info->fps;
|
|
|
+ idx = s_ctrl->last_updated_req % MAX_PER_FRAME_ARRAY;
|
|
|
+
|
|
|
+ s_ctrl->sensor_res[idx].res_index = res_info->res_index;
|
|
|
+ strscpy(s_ctrl->sensor_res[idx].caps, res_info->caps,
|
|
|
+ sizeof(s_ctrl->sensor_res[idx].caps));
|
|
|
+ s_ctrl->sensor_res[idx].width = res_info->width;
|
|
|
+ s_ctrl->sensor_res[idx].height = res_info->height;
|
|
|
+ s_ctrl->sensor_res[idx].fps = res_info->fps;
|
|
|
+
|
|
|
+ if (res_info->num_valid_params > 0) {
|
|
|
+ if (res_info->valid_param_mask & CAM_SENSOR_FEATURE_MASK)
|
|
|
+ s_ctrl->sensor_res[idx].feature_mask =
|
|
|
+ res_info->params[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ s_ctrl->is_res_info_updated = true;
|
|
|
|
|
|
/* If request id is 0, it will be during an initial config/acquire */
|
|
|
- CAM_INFO(CAM_SENSOR,
|
|
|
- "Res index switch for request id: %lu, index: %u, width: 0x%x, height: 0x%x, capability: %s, fps: %u",
|
|
|
- s_ctrl->sensor_res.request_id, s_ctrl->sensor_res.res_index,
|
|
|
- s_ctrl->sensor_res.width, s_ctrl->sensor_res.height,
|
|
|
- s_ctrl->sensor_res.caps, s_ctrl->sensor_res.fps);
|
|
|
+ CAM_DBG(CAM_SENSOR,
|
|
|
+ "Feature: 0x%x updated for request id: %lu, res index: %u, width: 0x%x, height: 0x%x, capability: %s, fps: %u",
|
|
|
+ s_ctrl->sensor_res[idx].feature_mask,
|
|
|
+ s_ctrl->sensor_res[idx].request_id, s_ctrl->sensor_res[idx].res_index,
|
|
|
+ s_ctrl->sensor_res[idx].width, s_ctrl->sensor_res[idx].height,
|
|
|
+ s_ctrl->sensor_res[idx].caps, s_ctrl->sensor_res[idx].fps);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -219,7 +245,8 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
size_t len_of_buff = 0;
|
|
|
size_t remain_len = 0;
|
|
|
uint32_t *offset = NULL;
|
|
|
- uint32_t cmd_buf_type;
|
|
|
+ int64_t prev_updated_req;
|
|
|
+ uint32_t cmd_buf_type, idx;
|
|
|
struct cam_config_dev_cmd config;
|
|
|
struct i2c_data_settings *i2c_data = NULL;
|
|
|
|
|
@@ -280,6 +307,10 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
if (csl_packet->header.request_id > s_ctrl->last_flush_req)
|
|
|
s_ctrl->last_flush_req = 0;
|
|
|
|
|
|
+ prev_updated_req = s_ctrl->last_updated_req;
|
|
|
+ s_ctrl->last_updated_req = csl_packet->header.request_id;
|
|
|
+ s_ctrl->is_res_info_updated = false;
|
|
|
+
|
|
|
i2c_data = &(s_ctrl->i2c_data);
|
|
|
CAM_DBG(CAM_SENSOR, "Header OpCode: %d", csl_packet->header.op_code);
|
|
|
switch (csl_packet->header.op_code & 0xFFFFFF) {
|
|
@@ -385,6 +416,22 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
csl_packet->header.request_id);
|
|
|
break;
|
|
|
}
|
|
|
+ case CAM_SENSOR_PACKET_OPCODE_SENSOR_BUBBLE_UPDATE: {
|
|
|
+ if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
|
|
|
+ (s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) {
|
|
|
+ CAM_WARN(CAM_SENSOR,
|
|
|
+ "Rxed Update packets without linking");
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ i2c_reg_settings =
|
|
|
+ &i2c_data->bubble_update[csl_packet->header.request_id %
|
|
|
+ MAX_PER_FRAME_ARRAY];
|
|
|
+ CAM_DBG(CAM_SENSOR, "Received bubble update packet: %lld req: %lld",
|
|
|
+ csl_packet->header.request_id % MAX_PER_FRAME_ARRAY,
|
|
|
+ csl_packet->header.request_id);
|
|
|
+ break;
|
|
|
+ }
|
|
|
case CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP: {
|
|
|
if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
|
|
|
(s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) {
|
|
@@ -434,7 +481,9 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
csl_packet->header.op_code & 0xFFFFFF);
|
|
|
goto end;
|
|
|
}
|
|
|
- s_ctrl->sensor_res.request_id = csl_packet->header.request_id;
|
|
|
+
|
|
|
+ idx = s_ctrl->last_updated_req % MAX_PER_FRAME_ARRAY;
|
|
|
+ s_ctrl->sensor_res[idx].request_id = csl_packet->header.request_id;
|
|
|
|
|
|
/**
|
|
|
* is_settings_valid is set to false for this case, as generic
|
|
@@ -450,11 +499,19 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
rc = cam_packet_util_process_generic_cmd_buffer(cmd_desc,
|
|
|
cam_sensor_generic_blob_handler, s_ctrl);
|
|
|
if (rc)
|
|
|
- s_ctrl->sensor_res.request_id = 0;
|
|
|
+ s_ctrl->sensor_res[idx].request_id = 0;
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * If no res info in current request, then we pick previous
|
|
|
+ * resolution info as current resolution info.
|
|
|
+ */
|
|
|
+ if (!s_ctrl->is_res_info_updated)
|
|
|
+ s_ctrl->sensor_res[s_ctrl->last_updated_req % MAX_PER_FRAME_ARRAY] =
|
|
|
+ s_ctrl->sensor_res[prev_updated_req % MAX_PER_FRAME_ARRAY];
|
|
|
+
|
|
|
if ((csl_packet->header.op_code & 0xFFFFFF) ==
|
|
|
CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE) {
|
|
|
i2c_reg_settings->request_id =
|
|
@@ -473,6 +530,12 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
csl_packet->header.request_id;
|
|
|
}
|
|
|
|
|
|
+ if ((csl_packet->header.op_code & 0xFFFFFF) ==
|
|
|
+ CAM_SENSOR_PACKET_OPCODE_SENSOR_BUBBLE_UPDATE) {
|
|
|
+ i2c_reg_settings->request_id =
|
|
|
+ csl_packet->header.request_id;
|
|
|
+ }
|
|
|
+
|
|
|
end:
|
|
|
return rc;
|
|
|
}
|
|
@@ -943,7 +1006,7 @@ int cam_sensor_stream_off(struct cam_sensor_ctrl_t *s_ctrl)
|
|
|
cam_sensor_release_per_frame_resource(s_ctrl);
|
|
|
s_ctrl->last_flush_req = 0;
|
|
|
s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE;
|
|
|
- memset(&s_ctrl->sensor_res, 0, sizeof(s_ctrl->sensor_res));
|
|
|
+ memset(s_ctrl->sensor_res, 0, sizeof(s_ctrl->sensor_res));
|
|
|
|
|
|
CAM_GET_TIMESTAMP(ts);
|
|
|
CAM_CONVERT_TIMESTAMP_FORMAT(ts, hrs, min, sec, ms);
|
|
@@ -1183,6 +1246,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE;
|
|
|
s_ctrl->last_flush_req = 0;
|
|
|
s_ctrl->is_stopped_by_user = false;
|
|
|
+ s_ctrl->last_updated_req = 0;
|
|
|
+ s_ctrl->last_applied_req = 0;
|
|
|
+ memset(s_ctrl->sensor_res, 0, sizeof(s_ctrl->sensor_res));
|
|
|
CAM_INFO(CAM_SENSOR,
|
|
|
"CAM_ACQUIRE_DEV Success for %s sensor_id:0x%x,sensor_slave_addr:0x%x",
|
|
|
s_ctrl->sensor_name,
|
|
@@ -1653,7 +1719,7 @@ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)
|
|
|
}
|
|
|
|
|
|
int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
- uint64_t req_id, enum cam_sensor_packet_opcodes opcode)
|
|
|
+ int64_t req_id, enum cam_sensor_packet_opcodes opcode)
|
|
|
{
|
|
|
int rc = 0, offset, i;
|
|
|
uint64_t top = 0, del_req_id = 0;
|
|
@@ -1712,7 +1778,16 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
|
|
|
if (opcode == CAM_SENSOR_PACKET_OPCODE_SENSOR_FRAME_SKIP_UPDATE)
|
|
|
i2c_set = s_ctrl->i2c_data.frame_skip;
|
|
|
- else
|
|
|
+ else if (opcode == CAM_SENSOR_PACKET_OPCODE_SENSOR_BUBBLE_UPDATE) {
|
|
|
+ i2c_set = s_ctrl->i2c_data.bubble_update;
|
|
|
+ /*
|
|
|
+ * If bubble update isn't valid, then we just use
|
|
|
+ * per frame update.
|
|
|
+ */
|
|
|
+ if (!(i2c_set[offset].is_settings_valid == 1) &&
|
|
|
+ (i2c_set[offset].request_id == req_id))
|
|
|
+ i2c_set = s_ctrl->i2c_data.per_frame;
|
|
|
+ } else
|
|
|
i2c_set = s_ctrl->i2c_data.per_frame;
|
|
|
|
|
|
if (i2c_set[offset].is_settings_valid == 1 &&
|
|
@@ -1736,6 +1811,9 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
}
|
|
|
|
|
|
s_ctrl->last_applied_req = req_id;
|
|
|
+ CAM_DBG(CAM_REQ,
|
|
|
+ "Sensor[%d] updating last_applied [req id: %lld last_applied: %lld] with opcode:%d",
|
|
|
+ s_ctrl->soc_info.index, req_id, s_ctrl->last_applied_req, opcode);
|
|
|
|
|
|
/* Change the logic dynamically */
|
|
|
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
|
|
@@ -1778,6 +1856,34 @@ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
|
|
|
del_req_id, rc);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If the op code is bubble update, then we also need to delete
|
|
|
+ * req for per frame update, vice versa.
|
|
|
+ */
|
|
|
+ if (opcode == CAM_SENSOR_PACKET_OPCODE_SENSOR_BUBBLE_UPDATE)
|
|
|
+ i2c_set = s_ctrl->i2c_data.per_frame;
|
|
|
+ else if (opcode == CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE)
|
|
|
+ i2c_set = s_ctrl->i2c_data.bubble_update;
|
|
|
+ else
|
|
|
+ i2c_set = NULL;
|
|
|
+
|
|
|
+ if (i2c_set) {
|
|
|
+ for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
|
|
|
+ if ((del_req_id >
|
|
|
+ i2c_set[i].request_id) && (
|
|
|
+ i2c_set[i].is_settings_valid
|
|
|
+ == 1)) {
|
|
|
+ i2c_set[i].request_id = 0;
|
|
|
+ rc = delete_request(
|
|
|
+ &(i2c_set[i]));
|
|
|
+ if (rc < 0)
|
|
|
+ CAM_ERR(CAM_SENSOR,
|
|
|
+ "Delete request Fail:%lld rc:%d",
|
|
|
+ del_req_id, rc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return rc;
|
|
@@ -1787,6 +1893,7 @@ int32_t cam_sensor_apply_request(struct cam_req_mgr_apply_request *apply)
|
|
|
{
|
|
|
int32_t rc = 0;
|
|
|
struct cam_sensor_ctrl_t *s_ctrl = NULL;
|
|
|
+ int32_t curr_idx, last_applied_idx;
|
|
|
enum cam_sensor_packet_opcodes opcode =
|
|
|
CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE;
|
|
|
|
|
@@ -1800,9 +1907,35 @@ int32_t cam_sensor_apply_request(struct cam_req_mgr_apply_request *apply)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- CAM_DBG(CAM_REQ, " Sensor[%d] update req id: %lld",
|
|
|
- s_ctrl->soc_info.index, apply->request_id);
|
|
|
+ if ((apply->recovery) && (apply->request_id > 0)) {
|
|
|
+ curr_idx = apply->request_id % MAX_PER_FRAME_ARRAY;
|
|
|
+ last_applied_idx = s_ctrl->last_applied_req % MAX_PER_FRAME_ARRAY;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If the sensor resolution index in current req isn't same with
|
|
|
+ * last applied index, we should apply bubble update.
|
|
|
+ */
|
|
|
+
|
|
|
+ if ((s_ctrl->sensor_res[curr_idx].res_index !=
|
|
|
+ s_ctrl->sensor_res[last_applied_idx].res_index) ||
|
|
|
+ (s_ctrl->sensor_res[curr_idx].feature_mask !=
|
|
|
+ s_ctrl->sensor_res[last_applied_idx].feature_mask)) {
|
|
|
+ opcode = CAM_SENSOR_PACKET_OPCODE_SENSOR_BUBBLE_UPDATE;
|
|
|
+ CAM_INFO(CAM_REQ,
|
|
|
+ "Sensor[%d] update req id: %lld [last_applied: %lld] with opcode:%d recovery: %d last_applied_res_idx: %u current_res_idx: %u",
|
|
|
+ s_ctrl->soc_info.index, apply->request_id,
|
|
|
+ s_ctrl->last_applied_req, opcode, apply->recovery,
|
|
|
+ s_ctrl->sensor_res[last_applied_idx].res_index,
|
|
|
+ s_ctrl->sensor_res[curr_idx].res_index);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CAM_DBG(CAM_REQ,
|
|
|
+ "Sensor[%d] update req id: %lld [last_applied: %lld] with opcode:%d recovery: %d",
|
|
|
+ s_ctrl->soc_info.index, apply->request_id,
|
|
|
+ s_ctrl->last_applied_req, opcode, apply->recovery);
|
|
|
trace_cam_apply_req("Sensor", s_ctrl->soc_info.index, apply->request_id, apply->link_hdl);
|
|
|
+
|
|
|
mutex_lock(&(s_ctrl->cam_sensor_mutex));
|
|
|
rc = cam_sensor_apply_settings(s_ctrl, apply->request_id,
|
|
|
opcode);
|