diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-04-02 09:41:22 (GMT) |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-20 12:27:16 (GMT) |
commit | 9448ab7dec30489d5318f786d0faee08354ef3d5 (patch) | |
tree | 0b77b5beed4edce688b12ba5cddbd82f0e0dd1a7 /drivers/media/video/s5p-fimc/fimc-core.c | |
parent | 0c9204d3427015a22fa90b865b6317fed337810b (diff) | |
download | linux-9448ab7dec30489d5318f786d0faee08354ef3d5.tar.xz |
[media] s5p-fimc: Add color effect control
Add support for V4L2_CID_COLORFX control at the mem-to-mem and capture
video nodes.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-core.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 127 |
1 files changed, 99 insertions, 28 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index bad9ad0..fedcd56 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -463,11 +463,53 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); } +int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx) +{ + struct fimc_effect *effect = &ctx->effect; + + switch (colorfx) { + case V4L2_COLORFX_NONE: + effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS; + break; + case V4L2_COLORFX_BW: + effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY; + effect->pat_cb = 128; + effect->pat_cr = 128; + break; + case V4L2_COLORFX_SEPIA: + effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY; + effect->pat_cb = 115; + effect->pat_cr = 145; + break; + case V4L2_COLORFX_NEGATIVE: + effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE; + break; + case V4L2_COLORFX_EMBOSS: + effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING; + break; + case V4L2_COLORFX_ART_FREEZE: + effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE; + break; + case V4L2_COLORFX_SILHOUETTE: + effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE; + break; + case V4L2_COLORFX_SET_CBCR: + effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY; + effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8; + effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff; + break; + default: + return -EINVAL; + } + + return 0; +} + /* * V4L2 controls handling */ #define ctrl_to_ctx(__ctrl) \ - container_of((__ctrl)->handler, struct fimc_ctx, ctrl_handler) + container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler) static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) { @@ -507,7 +549,14 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) case V4L2_CID_ALPHA_COMPONENT: ctx->d_frame.alpha = ctrl->val; break; + + case V4L2_CID_COLORFX: + ret = fimc_set_color_effect(ctx, ctrl->val); + if (ret) + return ret; + break; } + ctx->state |= FIMC_PARAMS; set_bit(ST_CAPT_APPLY_CFG, &fimc->state); return 0; @@ -534,69 +583,91 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) { struct fimc_variant *variant = ctx->fimc_dev->variant; unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt); + struct fimc_ctrls *ctrls = &ctx->ctrls; + struct v4l2_ctrl_handler *handler = &ctrls->handler; - if (ctx->ctrls_rdy) + if (ctx->ctrls.ready) return 0; - v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); - ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, + v4l2_ctrl_handler_init(handler, 6); + + ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops, V4L2_CID_ROTATE, 0, 270, 90, 0); - ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, + ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); - ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, + ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + if (variant->has_alpha) - ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, - &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, - 0, max_alpha, 1, 0); + ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops, + V4L2_CID_ALPHA_COMPONENT, + 0, max_alpha, 1, 0); else - ctx->ctrl_alpha = NULL; + ctrls->alpha = NULL; + + ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops, + V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR, + ~0x983f, V4L2_COLORFX_NONE); + + ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops, + V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0); - ctx->ctrls_rdy = ctx->ctrl_handler.error == 0; + ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; - return ctx->ctrl_handler.error; + if (!handler->error) { + v4l2_ctrl_cluster(3, &ctrls->colorfx); + ctrls->ready = true; + } + + return handler->error; } void fimc_ctrls_delete(struct fimc_ctx *ctx) { - if (ctx->ctrls_rdy) { - v4l2_ctrl_handler_free(&ctx->ctrl_handler); - ctx->ctrls_rdy = false; - ctx->ctrl_alpha = NULL; + struct fimc_ctrls *ctrls = &ctx->ctrls; + + if (ctrls->ready) { + v4l2_ctrl_handler_free(&ctrls->handler); + ctrls->ready = false; + ctrls->alpha = NULL; } } void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) { unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA; + struct fimc_ctrls *ctrls = &ctx->ctrls; - if (!ctx->ctrls_rdy) + if (!ctrls->ready) return; - mutex_lock(&ctx->ctrl_handler.lock); - v4l2_ctrl_activate(ctx->ctrl_rotate, active); - v4l2_ctrl_activate(ctx->ctrl_hflip, active); - v4l2_ctrl_activate(ctx->ctrl_vflip, active); - if (ctx->ctrl_alpha) - v4l2_ctrl_activate(ctx->ctrl_alpha, active && has_alpha); + mutex_lock(&ctrls->handler.lock); + v4l2_ctrl_activate(ctrls->rotate, active); + v4l2_ctrl_activate(ctrls->hflip, active); + v4l2_ctrl_activate(ctrls->vflip, active); + v4l2_ctrl_activate(ctrls->colorfx, active); + if (ctrls->alpha) + v4l2_ctrl_activate(ctrls->alpha, active && has_alpha); if (active) { - ctx->rotation = ctx->ctrl_rotate->val; - ctx->hflip = ctx->ctrl_hflip->val; - ctx->vflip = ctx->ctrl_vflip->val; + fimc_set_color_effect(ctx, ctrls->colorfx->cur.val); + ctx->rotation = ctrls->rotate->val; + ctx->hflip = ctrls->hflip->val; + ctx->vflip = ctrls->vflip->val; } else { + ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; ctx->rotation = 0; ctx->hflip = 0; ctx->vflip = 0; } - mutex_unlock(&ctx->ctrl_handler.lock); + mutex_unlock(&ctrls->handler.lock); } /* Update maximum value of the alpha color control */ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx) { struct fimc_dev *fimc = ctx->fimc_dev; - struct v4l2_ctrl *ctrl = ctx->ctrl_alpha; + struct v4l2_ctrl *ctrl = ctx->ctrls.alpha; if (ctrl == NULL || !fimc->variant->has_alpha) return; |