static int fimc_is_scc_video_open(struct file *file) { int ret = 0; struct fimc_is_core *core = video_drvdata(file); struct fimc_is_device_ischain *ischain = core->ischain[core->ischain_index]; struct fimc_is_group *group = &ischain->group_isp; struct fimc_is_subdev *scc = &ischain->scc; struct fimc_is_video_ctx *video_ctx = NULL; dbg_scc("%s\n", __func__); video_ctx = kzalloc(sizeof *video_ctx, GFP_KERNEL); if (video_ctx == NULL) { dev_err(&(core->pdev->dev), "%s:: Failed to kzalloc\n", __func__); ret = -ENOMEM; goto exit; } file->private_data = video_ctx; fimc_is_video_open(video_ctx, ischain, VIDEO_SCC_READY_BUFFERS, &(core->video_scc.common), V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &fimc_is_scc_qops, core->mem.vb2->ops); fimc_is_subdev_open(scc, group, ENTRY_SCALERC, video_ctx, NULL); exit: return ret; }
static int fimc_is_scc_start_streaming(struct vb2_queue *q, unsigned int count) { int ret = 0; struct fimc_is_video_ctx *video_ctx = q->drv_priv; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; dbg_scc("%s\n", __func__); if (!test_bit(FIMC_IS_VIDEO_STREAM_ON, &video_ctx->state) && test_bit(FIMC_IS_VIDEO_BUFFER_READY, &video_ctx->state)) { set_bit(FIMC_IS_VIDEO_STREAM_ON, &video_ctx->state); fimc_is_subdev_start(scc); } else { err("already stream on or buffer is not ready(%ld)", video_ctx->state); clear_bit(FIMC_IS_VIDEO_BUFFER_READY, &video_ctx->state); clear_bit(FIMC_IS_VIDEO_BUFFER_PREPARED, &video_ctx->state); fimc_is_subdev_stop(scc); ret = -EINVAL; } return ret; }
static int fimc_is_scc_stop_streaming(struct vb2_queue *q) { int ret = 0; unsigned long flags; struct fimc_is_video_ctx *video_ctx = q->drv_priv; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; struct fimc_is_framemgr *framemgr = &scc->framemgr; dbg_scc("%s\n", __func__); if (test_bit(FIMC_IS_VIDEO_STREAM_ON, &video_ctx->state)) { framemgr_e_barrier_irqs(framemgr, 0, flags); ret = framemgr->frame_process_cnt; framemgr_x_barrier_irqr(framemgr, 0, flags); if (ret) { err("being processed, can't stop"); ret = -EINVAL; goto exit; } clear_bit(FIMC_IS_VIDEO_STREAM_ON, &video_ctx->state); clear_bit(FIMC_IS_VIDEO_BUFFER_READY, &video_ctx->state); clear_bit(FIMC_IS_VIDEO_BUFFER_PREPARED, &video_ctx->state); fimc_is_subdev_stop(scc); } else { err("already stream off"); ret = -EINVAL; } exit: return ret; }
static int fimc_is_scc_video_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { int ret = 0; struct fimc_is_video_ctx *video_ctx = file->private_data; dbg_scc("%s\n", __func__); ret = fimc_is_video_streamoff(video_ctx, type); return ret; }
static int fimc_is_scc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { int ret = 0; struct fimc_is_video_ctx *video_ctx = vq->drv_priv; dbg_scc("%s\n", __func__); ret = fimc_is_video_queue_setup(video_ctx, num_planes, sizes, allocators); dbg_scc("(num_planes : %d)(size : %d)\n", (int)*num_planes, (int)sizes[0]); return ret; }
static void fimc_is_scc_buffer_queue(struct vb2_buffer *vb) { struct fimc_is_video_ctx *video_ctx = vb->vb2_queue->drv_priv; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; #ifdef DBG_STREAMING dbg_scc("%s\n", __func__); #endif fimc_is_video_buffer_queue(video_ctx, vb, &scc->framemgr); fimc_is_subdev_buffer_queue(scc, vb->v4l2_buf.index); }
static int fimc_is_scc_buffer_finish(struct vb2_buffer *vb) { int ret = 0; struct fimc_is_video_ctx *video_ctx = vb->vb2_queue->drv_priv; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; #ifdef DBG_STREAMING dbg_scc("%s(%d)\n", __func__, vb->v4l2_buf.index); #endif ret = fimc_is_subdev_buffer_finish(scc, vb->v4l2_buf.index); return ret; }
static void fimc_is_scc_buffer_queue(struct vb2_buffer *vb) { struct fimc_is_video_ctx *vctx = vb->vb2_queue->drv_priv; struct fimc_is_queue *queue = &vctx->q_dst; struct fimc_is_video *video = vctx->video; struct fimc_is_device_ischain *ischain = vctx->device; struct fimc_is_subdev *scc = &ischain->scc; #ifdef DBG_STREAMING dbg_scc("%s\n", __func__); #endif fimc_is_queue_buffer_queue(queue, video->vb2, vb); fimc_is_subdev_buffer_queue(scc, vb->v4l2_buf.index); }
static int fimc_is_scc_video_set_format_mplane(struct file *file, void *fh, struct v4l2_format *format) { int ret = 0; struct fimc_is_video_ctx *video_ctx = file->private_data; dbg_scp("%s\n", __func__); ret = fimc_is_video_set_format_mplane(video_ctx, format); dbg_scc("req w : %d req h : %d\n", video_ctx->frame.width, video_ctx->frame.height); return ret; }
static int fimc_is_scc_video_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { int ret = 0; unsigned long flags; struct fimc_is_video_ctx *video_ctx = file->private_data; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; struct fimc_is_framemgr *framemgr = &scc->framemgr; struct fimc_is_frame_shot *frame; dbg_scc("%s\n", __func__); switch (ctrl->id) { case V4L2_CID_IS_FORCE_DONE: if (framemgr->frame_process_cnt) { err("force done can be performed(process count %d)", framemgr->frame_process_cnt); ret = -EINVAL; } else if (!framemgr->frame_request_cnt) { err("force done can be performed(request count %d)", framemgr->frame_request_cnt); ret = -EINVAL; } else { framemgr_e_barrier_irqs(framemgr, 0, flags); fimc_is_frame_request_head(framemgr, &frame); if (frame) { fimc_is_frame_trans_req_to_com(framemgr, frame); buffer_done(video_ctx, frame->index); } else { err("frame is NULL"); ret = -EINVAL; } framemgr_x_barrier_irqr(framemgr, 0, flags); } break; default: err("unsupported ioctl(%d)\n", ctrl->id); ret = -EINVAL; break; } return ret; }
int fimc_is_scc_video_probe(void *core_data) { int ret = 0; struct fimc_is_core *core = (struct fimc_is_core *)core_data; struct fimc_is_video_scc *video = &core->video_scc; dbg_scc("%s\n", __func__); ret = fimc_is_video_probe(&video->common, core_data, FIMC_IS_VIDEO_SCALERC_NAME, FIMC_IS_VIDEO_NUM_SCALERC, &fimc_is_scc_video_fops, &fimc_is_scc_video_ioctl_ops); if (ret != 0) dev_err(&(core->pdev->dev), "%s::Failed to fimc_is_video_probe()\n", __func__); return ret; }
static int fimc_is_scc_video_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { int ret = 0; struct fimc_is_video_ctx *vctx = file->private_data; struct fimc_is_framemgr *framemgr = GET_DST_FRAMEMGR(vctx); dbg_scc("%s\n", __func__); switch (ctrl->id) { case V4L2_CID_IS_G_COMPLETES: ctrl->value = framemgr->frame_com_cnt; break; default: err("unsupported ioctl(%d)\n", ctrl->id); ret = -EINVAL; break; } return ret; }
static int fimc_is_scc_video_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { int ret = 0; struct fimc_is_video_ctx *video_ctx = file->private_data; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; struct fimc_is_framemgr *framemgr = &scc->framemgr; dbg_scc("%s\n", __func__); switch (ctrl->id) { case V4L2_CID_IS_G_COMPLETES: ctrl->value = framemgr->frame_complete_cnt; break; default: err("unsupported ioctl(%d)\n", ctrl->id); ret = -EINVAL; break; } return ret; }
static int fimc_is_scc_video_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *buf) { int ret = 0; struct fimc_is_video_ctx *video_ctx = file->private_data; struct fimc_is_device_ischain *ischain = video_ctx->device; struct fimc_is_subdev *scc = &ischain->scc; struct fimc_is_subdev *leader = scc->leader; dbg_scc("%s(buffers : %d)\n", __func__, buf->count); if (test_bit(FIMC_IS_ISDEV_DSTART, &leader->state)) { err("leader still running, not applied"); ret = -EINVAL; goto exit; } ret = fimc_is_video_reqbufs(video_ctx, &scc->framemgr, buf); if (ret) err("fimc_is_video_reqbufs is fail(error %d)", ret); exit: return ret; }