diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 5f05139af252..f7dda7d2029b 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -3910,6 +3910,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( add_req.dev_hdl = ctx->dev_hdl; add_req.req_id = req->request_id; add_req.skip_before_applying = 0; + add_req.trigger_eof = false; rc = ctx->ctx_crm_intf->add_req(&add_req); if (rc) { CAM_ERR(CAM_ISP, "Add req failed: req id=%llu", @@ -4525,7 +4526,8 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, ctx->link_hdl = link->link_hdl; ctx->ctx_crm_intf = link->crm_cb; - ctx_isp->subscribe_event = link->subscribe_event; + ctx_isp->subscribe_event = + CAM_TRIGGER_POINT_SOF | CAM_TRIGGER_POINT_EOF; ctx_isp->trigger_id = link->trigger_id; /* change state only if we had the init config */ diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 51604fda6a1f..c78e8e39879b 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -49,6 +49,7 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->initial_skip = true; link->sof_timestamp = 0; link->prev_sof_timestamp = 0; + atomic_set(&link->eof_event_cnt, 0); } void cam_req_mgr_handle_core_shutdown(void) @@ -456,10 +457,15 @@ static void __cam_req_mgr_flush_req_slot( tbl->pd, idx, tbl->slot[idx].state); tbl->slot[idx].req_ready_map = 0; tbl->slot[idx].state = CRM_REQ_STATE_EMPTY; + tbl->slot[idx].ops.apply_at_eof = false; + tbl->slot[idx].ops.skip_next_frame = false; + tbl->slot[idx].ops.dev_hdl = -1; + tbl->slot[idx].ops.is_applied = false; tbl = tbl->next; } } + atomic_set(&link->eof_event_cnt, 0); in_q->wr_idx = 0; in_q->rd_idx = 0; } @@ -502,6 +508,10 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, tbl->pd, idx, tbl->slot[idx].state); tbl->slot[idx].req_ready_map = 0; tbl->slot[idx].state = CRM_REQ_STATE_EMPTY; + tbl->slot[idx].ops.apply_at_eof = false; + tbl->slot[idx].ops.skip_next_frame = false; + tbl->slot[idx].ops.dev_hdl = -1; + tbl->slot[idx].ops.is_applied = false; tbl = tbl->next; } } @@ -668,6 +678,10 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, apply_req.re_apply = true; } + /* + * This For loop is to address the special operation requested + * by device + */ for (i = 0; i < link->num_devs; i++) { dev = &link->l_dev[i]; if (!dev) @@ -681,37 +695,76 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, idx = link->req.apply_data[pd].idx; slot = &dev->pd_tbl->slot[idx]; - /* - * Just let flash go for this request and other - * device get restricted - */ - if ((slot->skip_next_frame != true) || - (slot->dev_hdl != dev->dev_hdl)) + if (slot->ops.dev_hdl < 0) { + CAM_DBG(CAM_CRM, + "No special ops detected for this table slot"); continue; + } - if (!(dev->dev_info.trigger & trigger)) + if (slot->ops.apply_at_eof && slot->ops.skip_next_frame) { + CAM_ERR(CAM_CRM, + "Both EOF and SOF trigger is not supported"); + return -EINVAL; + } + + if (dev->dev_hdl != slot->ops.dev_hdl) { + CAM_DBG(CAM_CRM, + "Dev_hdl : %d Not matched:: Expected dev_hdl: %d", + dev->dev_hdl, slot->ops.dev_hdl); continue; + } + + /* This one is to prevent EOF request to apply on SOF*/ + if ((trigger == CAM_TRIGGER_POINT_SOF) && + (slot->ops.apply_at_eof)) { + CAM_DBG(CAM_CRM, "EOF event cannot be applied at SOF"); + break; + } + + if ((trigger == CAM_TRIGGER_POINT_EOF) && + (!slot->ops.apply_at_eof)) { + CAM_DBG(CAM_CRM, "NO EOF DATA FOR REQ: %llu", + link->req.apply_data[pd].req_id); + break; + } apply_req.dev_hdl = dev->dev_hdl; apply_req.request_id = link->req.apply_data[pd].req_id; apply_req.trigger_point = trigger; - if (dev->ops && dev->ops->apply_req) { + if ((dev->ops) && (dev->ops->apply_req) && + (!slot->ops.is_applied)) { rc = dev->ops->apply_req(&apply_req); if (rc) { *failed_dev = dev; return rc; } - CAM_DBG(CAM_REQ, - "SEND: link_hdl: %x pd: %d req_id %lld", - link->link_hdl, pd, apply_req.request_id); - slot->skip_next_frame = false; - slot->is_applied = true; + } + + CAM_DBG(CAM_REQ, + "SEND: link_hdl: %x pd: %d req_id %lld", + link->link_hdl, pd, apply_req.request_id); + + if (trigger == CAM_TRIGGER_POINT_SOF && + slot->ops.skip_next_frame) { + slot->ops.skip_next_frame = false; + slot->ops.is_applied = true; return -EAGAIN; + } else if ((trigger == CAM_TRIGGER_POINT_EOF) && + (slot->ops.apply_at_eof)) { + slot->ops.apply_at_eof = false; + if (atomic_read(&link->eof_event_cnt) > 0) + atomic_dec(&link->eof_event_cnt); + CAM_DBG(CAM_REQ, + "Req_id: %llu eof_event_cnt : %d", + link->req.apply_data[pd].req_id, + link->eof_event_cnt); + return 0; } } + /* For regular send requests */ for (i = 0; i < link->num_devs; i++) { dev = &link->l_dev[i]; if (dev) { @@ -739,12 +792,29 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, apply_req.report_if_bubble = in_q->slot[idx].recover; - if ((slot->dev_hdl == dev->dev_hdl) && - (slot->is_applied == true)) { - slot->is_applied = false; + if ((slot->ops.dev_hdl == dev->dev_hdl) && + (slot->ops.is_applied)) { + slot->ops.is_applied = false; continue; } + /* + * If apply_at_eof is enabled do not apply at SOF + * e.x. Flash device + */ + if ((trigger == CAM_TRIGGER_POINT_SOF) && + (dev->dev_hdl == slot->ops.dev_hdl) && + (slot->ops.apply_at_eof)) + continue; + + /* + * If apply_at_eof is not enabled ignore EOF + */ + if ((trigger == CAM_TRIGGER_POINT_EOF) && + (dev->dev_hdl == slot->ops.dev_hdl) && + (!slot->ops.apply_at_eof)) + continue; + apply_req.trigger_point = trigger; CAM_DBG(CAM_REQ, "SEND: link_hdl: %x pd %d req_id %lld", @@ -1507,6 +1577,13 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, if (link->trigger_mask == link->subscribe_event) { slot->status = CRM_SLOT_STATUS_REQ_APPLIED; link->trigger_mask = 0; + if (!(atomic_read(&link->eof_event_cnt)) && + (trigger == CAM_TRIGGER_POINT_EOF)) { + link->subscribe_event &= ~CAM_TRIGGER_POINT_EOF; + CAM_DBG(CAM_CRM, + "Update link subscribe_event: %d", + link->subscribe_event); + } CAM_DBG(CAM_CRM, "req %d is applied on link %x", slot->req_id, link->link_hdl); @@ -1591,11 +1668,19 @@ static void __cam_req_mgr_add_tbl_to_link(struct cam_req_mgr_req_tbl **l_tbl, */ static struct cam_req_mgr_req_tbl *__cam_req_mgr_create_pd_tbl(int32_t delay) { + int i = 0; + struct cam_req_mgr_req_tbl *tbl = kzalloc(sizeof(struct cam_req_mgr_req_tbl), GFP_KERNEL); if (tbl != NULL) { tbl->num_slots = MAX_REQ_SLOTS; CAM_DBG(CAM_CRM, "pd= %d slots= %d", delay, tbl->num_slots); + for (i = 0; i < MAX_REQ_SLOTS; i++) { + tbl->slot[i].ops.apply_at_eof = false; + tbl->slot[i].ops.skip_next_frame = false; + tbl->slot[i].ops.dev_hdl = -1; + tbl->slot[i].ops.is_applied = false; + } } return tbl; @@ -2310,17 +2395,27 @@ int cam_req_mgr_process_add_req(void *priv, void *data) } slot = &tbl->slot[idx]; - slot->is_applied = false; + slot->ops.is_applied = false; if ((add_req->skip_before_applying & 0xFF) > slot->inject_delay) { slot->inject_delay = (add_req->skip_before_applying & 0xFF); - slot->dev_hdl = add_req->dev_hdl; - if (add_req->skip_before_applying & SKIP_NEXT_FRAME) - slot->skip_next_frame = true; + if (add_req->skip_before_applying & SKIP_NEXT_FRAME) { + slot->ops.skip_next_frame = true; + slot->ops.dev_hdl = add_req->dev_hdl; + } CAM_DBG(CAM_CRM, "Req_id %llu injecting delay %llu", add_req->req_id, (add_req->skip_before_applying & 0xFF)); } + /* Used when Precise Flash is enabled */ + if ((add_req->trigger_eof) && (!add_req->skip_before_applying)) { + slot->ops.apply_at_eof = true; + slot->ops.dev_hdl = add_req->dev_hdl; + CAM_DBG(CAM_REQ, + "Req_id %llu added for EOF tigger for Device: %s", + add_req->req_id, device->dev_info.name); + } + if (slot->state != CRM_REQ_STATE_PENDING && slot->state != CRM_REQ_STATE_EMPTY) { CAM_WARN(CAM_CRM, @@ -2658,9 +2753,10 @@ static int cam_req_mgr_cb_add_req(struct cam_req_mgr_add_request *add_req) return -EINVAL; } - CAM_DBG(CAM_REQ, "dev name %s dev_hdl %d dev req %lld", + CAM_DBG(CAM_REQ, + "dev name %s dev_hdl %d dev req %lld, trigger_eof: %d", __cam_req_mgr_dev_handle_to_name(add_req->dev_hdl, link), - add_req->dev_hdl, add_req->req_id); + add_req->dev_hdl, add_req->req_id, add_req->trigger_eof); mutex_lock(&link->lock); spin_lock_bh(&link->link_state_spin_lock); @@ -2695,6 +2791,16 @@ static int cam_req_mgr_cb_add_req(struct cam_req_mgr_add_request *add_req) dev_req->link_hdl = add_req->link_hdl; dev_req->dev_hdl = add_req->dev_hdl; dev_req->skip_before_applying = add_req->skip_before_applying; + dev_req->trigger_eof = add_req->trigger_eof; + if (dev_req->trigger_eof) { + link->subscribe_event |= CAM_TRIGGER_POINT_EOF; + atomic_inc(&link->eof_event_cnt); + CAM_DBG(CAM_REQ, + "Req_id: %llu, eof_event_cnt: %d, link subscribe event: %d", + dev_req->req_id, link->eof_event_cnt, + link->subscribe_event); + } + task->process_cb = &cam_req_mgr_process_add_req; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); CAM_DBG(CAM_CRM, "X: dev %x dev req %lld", @@ -2935,6 +3041,12 @@ static int cam_req_mgr_cb_notify_trigger( trigger_id = trigger_data->trigger_id; + if ((!atomic_read(&link->eof_event_cnt)) && + (trigger_data->trigger == CAM_TRIGGER_POINT_EOF)) { + CAM_DBG(CAM_CRM, "Not any request to schedule at EOF"); + goto end; + } + spin_lock_bh(&link->link_state_spin_lock); if (link->state < CAM_CRM_LINK_STATE_READY) { CAM_WARN(CAM_CRM, "invalid link state:%d", link->state); @@ -2943,7 +3055,8 @@ static int cam_req_mgr_cb_notify_trigger( goto end; } - if ((link->watchdog) && (link->watchdog->pause_timer)) + if ((link->watchdog) && (link->watchdog->pause_timer) && + (trigger_data->trigger == CAM_TRIGGER_POINT_SOF)) link->watchdog->pause_timer = false; if (link->dual_trigger) { @@ -2963,7 +3076,9 @@ static int cam_req_mgr_cb_notify_trigger( } } - crm_timer_reset(link->watchdog); + if (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) + crm_timer_reset(link->watchdog); + spin_unlock_bh(&link->link_state_spin_lock); task = cam_req_mgr_workq_get_task(link->workq); @@ -2974,7 +3089,8 @@ static int cam_req_mgr_cb_notify_trigger( goto end; } task_data = (struct crm_task_payload *)task->payload; - task_data->type = CRM_WORKQ_TASK_NOTIFY_SOF; + task_data->type = (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) ? + CRM_WORKQ_TASK_NOTIFY_SOF : CRM_WORKQ_TASK_NOTIFY_EOF; notify_trigger = (struct cam_req_mgr_trigger_notify *)&task_data->u; notify_trigger->frame_id = trigger_data->frame_id; notify_trigger->link_hdl = trigger_data->link_hdl; @@ -3022,8 +3138,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) return -EPERM; - } - else if (link_info->version == VERSION_2) { + } else if (link_info->version == VERSION_2) { if (link_info->u.link_info_v2.num_devices > CAM_REQ_MGR_MAX_HANDLES_V2) return -EPERM; diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.h b/drivers/cam_req_mgr/cam_req_mgr_core.h index df2d921e7c19..e406590c9499 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -49,6 +49,7 @@ enum crm_workq_task_type { CRM_WORKQ_TASK_DEV_ADD_REQ, CRM_WORKQ_TASK_APPLY_REQ, CRM_WORKQ_TASK_NOTIFY_SOF, + CRM_WORKQ_TASK_NOTIFY_EOF, CRM_WORKQ_TASK_NOTIFY_ERR, CRM_WORKQ_TASK_NOTIFY_FREEZE, CRM_WORKQ_TASK_SCHED_REQ, @@ -178,25 +179,39 @@ struct cam_req_mgr_apply { int32_t skip_idx; }; +/** + * struct crm_tbl_slot_special_ops + * @dev_hdl : Device handle who requested for special ops + * @apply_at_eof : Boolean Identifier for request to be applied at EOF + * @skip_next_frame : Flag to drop the frame after skip_before_apply frame + * @is_applied : Flag to identify if request is already applied to device + * in previous frame + */ +struct crm_tbl_slot_special_ops { + int32_t dev_hdl; + bool apply_at_eof; + bool skip_next_frame; + bool is_applied; +}; + /** * struct cam_req_mgr_tbl_slot * @idx : slot index * @req_ready_map : mask tracking which all devices have request ready * @state : state machine for life cycle of a slot * @inject_delay : insert extra bubbling for flash type of use cases - * @dev_hdl : stores the dev_hdl, who is having higher inject delay - * @skip_next_frame : flag to drop the frame after skip_before_apply frame - * @is_applied : flag to identify if request is already applied to - * device. + * @ops : special operation for the table slot + * e.g. + * skip_next frame: in case of applying one device + * and skip others + * apply_at_eof: device that needs to apply at EOF */ struct cam_req_mgr_tbl_slot { - int32_t idx; - uint32_t req_ready_map; - enum crm_req_state state; - uint32_t inject_delay; - int32_t dev_hdl; - bool skip_next_frame; - bool is_applied; + int32_t idx; + uint32_t req_ready_map; + enum crm_req_state state; + uint32_t inject_delay; + struct crm_tbl_slot_special_ops ops; }; /** @@ -348,6 +363,7 @@ struct cam_req_mgr_connected_device { * @dual_trigger : Links needs to wait for two triggers prior to * applying the settings * @trigger_cnt : trigger count value per device initiating the trigger + * @eof_event_cnt : Atomic variable to track the number of EOF requests */ struct cam_req_mgr_core_link { int32_t link_hdl; @@ -380,7 +396,7 @@ struct cam_req_mgr_core_link { uint64_t prev_sof_timestamp; bool dual_trigger; uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS]; - + atomic_t eof_event_cnt; }; /** diff --git a/drivers/cam_req_mgr/cam_req_mgr_interface.h b/drivers/cam_req_mgr/cam_req_mgr_interface.h index 4957bda64865..c40a479419e7 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/cam_req_mgr/cam_req_mgr_interface.h @@ -186,12 +186,13 @@ enum cam_req_mgr_device_id { /** * enum cam_req_mgr_link_evt_type - * @CAM_REQ_MGR_LINK_EVT_ERR : error on the link from any of the - * connected devices - * @CAM_REQ_MGR_LINK_EVT_PAUSE : to pause the link - * @CAM_REQ_MGR_LINK_EVT_RESUME : resumes the link which was paused - * @CAM_REQ_MGR_LINK_EVT_SOF_FREEZE : request manager has detected an sof freeze - * @CAM_REQ_MGR_LINK_EVT_MAX : invalid event type + * @CAM_REQ_MGR_LINK_EVT_ERR : error on the link from any of the + * connected devices + * @CAM_REQ_MGR_LINK_EVT_PAUSE : to pause the link + * @CAM_REQ_MGR_LINK_EVT_RESUME : resumes the link which was paused + * @CAM_REQ_MGR_LINK_EVT_SOF_FREEZE : request manager has detected an + * sof freeze + * @CAM_REQ_MGR_LINK_EVT_MAX : invalid event type */ enum cam_req_mgr_link_evt_type { CAM_REQ_MGR_LINK_EVT_ERR, @@ -261,12 +262,15 @@ struct cam_req_mgr_error_notify { * @req_id : req id which device is ready to process * @skip_before_applying : before applying req mgr introduce bubble * by not sending request to devices. ex: IFE and Flash + * @trigger_eof : to identify that one of the device at this slot needs + * to be apply at EOF */ struct cam_req_mgr_add_request { int32_t link_hdl; int32_t dev_hdl; uint64_t req_id; uint32_t skip_before_applying; + bool trigger_eof; }; @@ -355,15 +359,14 @@ struct cam_req_mgr_flush_request { /** * struct cam_req_mgr_event_data - * @link_hdl : link handle - * @req_id : request id - * @evt_type : link event + * @link_hdl : link handle + * @req_id : request id + * @evt_type : link event */ struct cam_req_mgr_link_evt_data { int32_t link_hdl; int32_t dev_hdl; uint64_t req_id; - enum cam_req_mgr_link_evt_type evt_type; union { enum cam_req_mgr_device_error error; diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index 0b6e25572e90..06f98a01d1df 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -370,6 +370,7 @@ static void cam_actuator_update_req_mgr( add_req.req_id = csl_packet->header.request_id; add_req.dev_hdl = a_ctrl->bridge_intf.device_hdl; add_req.skip_before_applying = 0; + add_req.trigger_eof = false; if (a_ctrl->bridge_intf.crm_cb && a_ctrl->bridge_intf.crm_cb->add_req) { diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index da32761b5488..0e60442c4a75 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -11,6 +11,9 @@ #include "cam_common_util.h" #include "cam_packet_util.h" +static uint default_on_timer = 2; +module_param(default_on_timer, uint, 0644); + int cam_flash_led_prepare(struct led_trigger *trigger, int options, int *max_current, bool is_wled) { @@ -396,7 +399,8 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl, cam_res_mgr_led_trigger_event( flash_ctrl->torch_trigger[i], curr); } - } else if (op == CAMERA_SENSOR_FLASH_OP_FIREHIGH) { + } else if ((op == CAMERA_SENSOR_FLASH_OP_FIREHIGH) || + (op == CAMERA_SENSOR_FLASH_OP_FIREDURATION)) { for (i = 0; i < flash_ctrl->flash_num_sources; i++) { if (flash_ctrl->flash_trigger[i]) { max_current = soc_private->flash_max_current[i]; @@ -416,10 +420,39 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl, return -EINVAL; } - if (flash_ctrl->switch_trigger) + if (flash_ctrl->switch_trigger) { +#if IS_ENABLED(CONFIG_LEDS_QTI_FLASH) + int rc = 0; + + if (op == CAMERA_SENSOR_FLASH_OP_FIREDURATION) { + struct flash_led_param param; + + param.off_time_ms = + flash_data->flash_active_time_ms; + /* This is to dynamically change the turn on time */ + param.on_time_ms = default_on_timer; + CAM_DBG(CAM_FLASH, + "Precise flash_on time: %u, Precise flash_off time: %u", + param.on_time_ms, param.off_time_ms); + rc = qti_flash_led_set_param( + flash_ctrl->switch_trigger, + param); + if (rc) { + CAM_ERR(CAM_FLASH, + "LED set param fail rc= %d", rc); + return rc; + } + } +#else + if (op == CAMERA_SENSOR_FLASH_OP_FIREDURATION) { + CAM_ERR(CAM_FLASH, "FIREDURATION op not supported"); + return -EINVAL; + } +#endif cam_res_mgr_led_trigger_event( flash_ctrl->switch_trigger, (enum led_brightness)LED_SWITCH_ON); + } return 0; } @@ -489,6 +522,30 @@ static int cam_flash_high( return rc; } +static int cam_flash_duration(struct cam_flash_ctrl *fctrl, + struct cam_flash_frame_setting *flash_data) +{ + int i = 0, rc = 0; + + if (!flash_data) { + CAM_ERR(CAM_FLASH, "Flash Data NULL"); + return -EINVAL; + } + + for (i = 0; i < fctrl->torch_num_sources; i++) + if (fctrl->torch_trigger[i]) + cam_res_mgr_led_trigger_event( + fctrl->torch_trigger[i], + LED_OFF); + + rc = cam_flash_ops(fctrl, flash_data, + CAMERA_SENSOR_FLASH_OP_FIREDURATION); + if (rc) + CAM_ERR(CAM_FLASH, "Fire PreciseFlash Failed: %d", rc); + + return rc; +} + static int cam_flash_i2c_delete_req(struct cam_flash_ctrl *fctrl, uint64_t req_id) { @@ -850,6 +907,19 @@ int cam_flash_pmic_apply_setting(struct cam_flash_ctrl *fctrl, "Flash off failed %d", rc); goto apply_setting_err; } + } else if ((flash_data->opcode == + CAMERA_SENSOR_FLASH_OP_FIREDURATION) && + (flash_data->cmn_attr.is_settings_valid) && + (flash_data->cmn_attr.request_id == req_id)) { + if (fctrl->flash_state == CAM_FLASH_STATE_START) { + rc = cam_flash_duration(fctrl, flash_data); + if (rc) { + CAM_ERR(CAM_FLASH, + "PreciaseFlash op failed:%d", + rc); + goto apply_setting_err; + } + } } else if (flash_data->opcode == CAM_PKT_NOP_OPCODE) { CAM_DBG(CAM_FLASH, "NOP Packet"); } else { @@ -1473,6 +1543,18 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) if (flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) add_req.skip_before_applying |= SKIP_NEXT_FRAME; + + if (flash_data->opcode == + CAMERA_SENSOR_FLASH_OP_FIREDURATION) { + add_req.trigger_eof = true; + /* Active time for the preflash */ + flash_data->flash_active_time_ms = + (flash_operation_info->time_on_duration_ns) + / 1000000; + CAM_DBG(CAM_FLASH, + "PRECISE FLASH: active_time: %llu", + flash_data->flash_active_time_ms); + } } break; default: @@ -1660,15 +1742,24 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) add_req.dev_hdl = fctrl->bridge_intf.device_hdl; if ((csl_packet->header.op_code & 0xFFFFF) == - CAM_FLASH_PACKET_OPCODE_SET_OPS) - add_req.skip_before_applying |= 1; - else + CAM_FLASH_PACKET_OPCODE_SET_OPS) { + if ((flash_data->opcode != + CAMERA_SENSOR_FLASH_OP_FIREDURATION)) + add_req.skip_before_applying |= 1; + else if (flash_data->opcode == + CAMERA_SENSOR_FLASH_OP_FIREDURATION) + add_req.trigger_eof = true; + else + add_req.skip_before_applying = 0; + } else { add_req.skip_before_applying = 0; - + } + CAM_DBG(CAM_FLASH, + "add req to req_mgr= %lld:: trigger_eof: %d", + add_req.req_id, add_req.trigger_eof); if (fctrl->bridge_intf.crm_cb && fctrl->bridge_intf.crm_cb->add_req) fctrl->bridge_intf.crm_cb->add_req(&add_req); - CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id); } return rc; diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h index 64bb25308d41..b8416cd15d8b 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.h @@ -108,13 +108,13 @@ struct cam_flash_init_packet { /** * struct flash_frame_setting - * @cmn_attr : Provides common attributes - * @num_iterations : Iterations used to perform RER - * @led_on_delay_ms : LED on time in milisec - * @led_off_delay_ms : LED off time in milisec - * @opcode : Command buffer opcode - * @led_current_ma[] : LED current array in miliamps - * + * @cmn_attr : Provides common attributes + * @num_iterations : Iterations used to perform RER + * @led_on_delay_ms : LED on time in milisec + * @led_off_delay_ms : LED off time in milisec + * @opcode : Command buffer opcode + * @led_current_ma[] : LED current array in miliamps + * @flash_active_time_ms : Flash_On time with precise flash */ struct cam_flash_frame_setting { struct cam_flash_common_attr cmn_attr; @@ -123,6 +123,7 @@ struct cam_flash_frame_setting { uint16_t led_off_delay_ms; int8_t opcode; uint32_t led_current_ma[CAM_FLASH_MAX_LED_TRIGGERS]; + uint64_t flash_active_time_ms; }; /** diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 696bbd3b90cb..762b0a65e0c2 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -25,6 +25,7 @@ static void cam_sensor_update_req_mgr( csl_packet->header.request_id); add_req.dev_hdl = s_ctrl->bridge_intf.device_hdl; add_req.skip_before_applying = 0; + add_req.trigger_eof = false; if (s_ctrl->bridge_intf.crm_cb && s_ctrl->bridge_intf.crm_cb->add_req) s_ctrl->bridge_intf.crm_cb->add_req(&add_req); diff --git a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h index 09d100c8f0a8..5889243dd38e 100644 --- a/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h +++ b/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h @@ -77,6 +77,7 @@ enum camera_flash_opcode { CAMERA_SENSOR_FLASH_OP_OFF, CAMERA_SENSOR_FLASH_OP_FIRELOW, CAMERA_SENSOR_FLASH_OP_FIREHIGH, + CAMERA_SENSOR_FLASH_OP_FIREDURATION, CAMERA_SENSOR_FLASH_OP_MAX, };