static int fimc_m2m_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { struct fimc_ctx *ctx = fh_to_ctx(fh); /* The source and target color format need to be set */ if (V4L2_TYPE_IS_OUTPUT(type)) { if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx)) return -EINVAL; } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) { return -EINVAL; } return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); }
/* Complete the transaction which has been scheduled for execution. */ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; if (!fimc_m2m_pending(fimc)) return; fimc_ctx_state_set(FIMC_CTX_SHUT, ctx); wait_event_timeout(fimc->irq_queue, !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), FIMC_SHUTDOWN_TIMEOUT); }
/* Complete the transaction which has been scheduled for execution. */ static int fimc_m2m_shutdown(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; int ret; if (!fimc_m2m_pending(fimc)) return 0; fimc_ctx_state_set(FIMC_CTX_SHUT, ctx); ret = wait_event_timeout(fimc->irq_queue, !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), FIMC_SHUTDOWN_TIMEOUT); return ret == 0 ? -ETIMEDOUT : ret; }
static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) { struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_dev *fimc = ctx->fimc_dev; struct v4l2_crop cr = *crop; struct fimc_frame *f; int ret; ret = fimc_m2m_try_crop(ctx, &cr); if (ret) return ret; f = (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? &ctx->s_frame : &ctx->d_frame; /* Check to see if scaling ratio is within supported range */ if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) { if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ret = fimc_check_scaler_ratio(ctx, cr.c.width, cr.c.height, ctx->d_frame.width, ctx->d_frame.height, ctx->rotation); } else { ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, ctx->s_frame.height, cr.c.width, cr.c.height, ctx->rotation); } if (ret) { v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); return -EINVAL; } } f->offs_h = cr.c.left; f->offs_v = cr.c.top; f->width = cr.c.width; f->height = cr.c.height; fimc_ctx_state_set(FIMC_PARAMS, ctx); return 0; }
/* Complete the transaction which has been scheduled for execution. */ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; int ret; if (!fimc_m2m_pending(fimc)) return; fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx); ret = wait_event_timeout(fimc->irq_queue, !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx), FIMC_SHUTDOWN_TIMEOUT); /* * In case of a timeout the buffers are not released in the interrupt * handler so return them here with the error flag set, if there are * any on the queue. */ if (ret == 0) fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); }