aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-04-02 05:41:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-20 08:27:16 -0400
commit9448ab7dec30489d5318f786d0faee08354ef3d5 (patch)
tree0b77b5beed4edce688b12ba5cddbd82f0e0dd1a7
parent0c9204d3427015a22fa90b865b6317fed337810b (diff)
[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>
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c11
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c127
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h38
-rw-r--r--drivers/media/video/s5p-fimc/fimc-m2m.c4
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c4
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.h2
6 files changed, 136 insertions, 50 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 6d079ac7089e..12415e7383d4 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -62,7 +62,7 @@ static int fimc_capture_hw_init(struct fimc_dev *fimc)
62 fimc_hw_set_mainscaler(ctx); 62 fimc_hw_set_mainscaler(ctx);
63 fimc_hw_set_target_format(ctx); 63 fimc_hw_set_target_format(ctx);
64 fimc_hw_set_rotation(ctx); 64 fimc_hw_set_rotation(ctx);
65 fimc_hw_set_effect(ctx, false); 65 fimc_hw_set_effect(ctx);
66 fimc_hw_set_output_path(ctx); 66 fimc_hw_set_output_path(ctx);
67 fimc_hw_set_out_dma(ctx); 67 fimc_hw_set_out_dma(ctx);
68 if (fimc->variant->has_alpha) 68 if (fimc->variant->has_alpha)
@@ -164,6 +164,7 @@ static int fimc_capture_config_update(struct fimc_ctx *ctx)
164 fimc_hw_set_mainscaler(ctx); 164 fimc_hw_set_mainscaler(ctx);
165 fimc_hw_set_target_format(ctx); 165 fimc_hw_set_target_format(ctx);
166 fimc_hw_set_rotation(ctx); 166 fimc_hw_set_rotation(ctx);
167 fimc_hw_set_effect(ctx);
167 fimc_prepare_dma_offset(ctx, &ctx->d_frame); 168 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
168 fimc_hw_set_out_dma(ctx); 169 fimc_hw_set_out_dma(ctx);
169 if (fimc->variant->has_alpha) 170 if (fimc->variant->has_alpha)
@@ -462,14 +463,14 @@ int fimc_capture_ctrls_create(struct fimc_dev *fimc)
462 463
463 if (WARN_ON(vid_cap->ctx == NULL)) 464 if (WARN_ON(vid_cap->ctx == NULL))
464 return -ENXIO; 465 return -ENXIO;
465 if (vid_cap->ctx->ctrls_rdy) 466 if (vid_cap->ctx->ctrls.ready)
466 return 0; 467 return 0;
467 468
468 ret = fimc_ctrls_create(vid_cap->ctx); 469 ret = fimc_ctrls_create(vid_cap->ctx);
469 if (ret || vid_cap->user_subdev_api) 470 if (ret || vid_cap->user_subdev_api || !vid_cap->ctx->ctrls.ready)
470 return ret; 471 return ret;
471 472
472 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrl_handler, 473 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
473 fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler); 474 fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
474} 475}
475 476
@@ -1588,7 +1589,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
1588 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", 1589 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
1589 vfd->name, video_device_node_name(vfd)); 1590 vfd->name, video_device_node_name(vfd));
1590 1591
1591 vfd->ctrl_handler = &ctx->ctrl_handler; 1592 vfd->ctrl_handler = &ctx->ctrls.handler;
1592 return 0; 1593 return 0;
1593 1594
1594err_vd: 1595err_vd:
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index bad9ad018baa..fedcd561ba27 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)
463 f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); 463 f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
464} 464}
465 465
466int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
467{
468 struct fimc_effect *effect = &ctx->effect;
469
470 switch (colorfx) {
471 case V4L2_COLORFX_NONE:
472 effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
473 break;
474 case V4L2_COLORFX_BW:
475 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
476 effect->pat_cb = 128;
477 effect->pat_cr = 128;
478 break;
479 case V4L2_COLORFX_SEPIA:
480 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
481 effect->pat_cb = 115;
482 effect->pat_cr = 145;
483 break;
484 case V4L2_COLORFX_NEGATIVE:
485 effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE;
486 break;
487 case V4L2_COLORFX_EMBOSS:
488 effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING;
489 break;
490 case V4L2_COLORFX_ART_FREEZE:
491 effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE;
492 break;
493 case V4L2_COLORFX_SILHOUETTE:
494 effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE;
495 break;
496 case V4L2_COLORFX_SET_CBCR:
497 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
498 effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8;
499 effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff;
500 break;
501 default:
502 return -EINVAL;
503 }
504
505 return 0;
506}
507
466/* 508/*
467 * V4L2 controls handling 509 * V4L2 controls handling
468 */ 510 */
469#define ctrl_to_ctx(__ctrl) \ 511#define ctrl_to_ctx(__ctrl) \
470 container_of((__ctrl)->handler, struct fimc_ctx, ctrl_handler) 512 container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler)
471 513
472static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) 514static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
473{ 515{
@@ -507,7 +549,14 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
507 case V4L2_CID_ALPHA_COMPONENT: 549 case V4L2_CID_ALPHA_COMPONENT:
508 ctx->d_frame.alpha = ctrl->val; 550 ctx->d_frame.alpha = ctrl->val;
509 break; 551 break;
552
553 case V4L2_CID_COLORFX:
554 ret = fimc_set_color_effect(ctx, ctrl->val);
555 if (ret)
556 return ret;
557 break;
510 } 558 }
559
511 ctx->state |= FIMC_PARAMS; 560 ctx->state |= FIMC_PARAMS;
512 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 561 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
513 return 0; 562 return 0;
@@ -534,69 +583,91 @@ int fimc_ctrls_create(struct fimc_ctx *ctx)
534{ 583{
535 struct fimc_variant *variant = ctx->fimc_dev->variant; 584 struct fimc_variant *variant = ctx->fimc_dev->variant;
536 unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt); 585 unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
586 struct fimc_ctrls *ctrls = &ctx->ctrls;
587 struct v4l2_ctrl_handler *handler = &ctrls->handler;
537 588
538 if (ctx->ctrls_rdy) 589 if (ctx->ctrls.ready)
539 return 0; 590 return 0;
540 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
541 591
542 ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 592 v4l2_ctrl_handler_init(handler, 6);
593
594 ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
543 V4L2_CID_ROTATE, 0, 270, 90, 0); 595 V4L2_CID_ROTATE, 0, 270, 90, 0);
544 ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 596 ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
545 V4L2_CID_HFLIP, 0, 1, 1, 0); 597 V4L2_CID_HFLIP, 0, 1, 1, 0);
546 ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 598 ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
547 V4L2_CID_VFLIP, 0, 1, 1, 0); 599 V4L2_CID_VFLIP, 0, 1, 1, 0);
600
548 if (variant->has_alpha) 601 if (variant->has_alpha)
549 ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, 602 ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
550 &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, 603 V4L2_CID_ALPHA_COMPONENT,
551 0, max_alpha, 1, 0); 604 0, max_alpha, 1, 0);
552 else 605 else
553 ctx->ctrl_alpha = NULL; 606 ctrls->alpha = NULL;
607
608 ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops,
609 V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
610 ~0x983f, V4L2_COLORFX_NONE);
611
612 ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
613 V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
554 614
555 ctx->ctrls_rdy = ctx->ctrl_handler.error == 0; 615 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
556 616
557 return ctx->ctrl_handler.error; 617 if (!handler->error) {
618 v4l2_ctrl_cluster(3, &ctrls->colorfx);
619 ctrls->ready = true;
620 }
621
622 return handler->error;
558} 623}
559 624
560void fimc_ctrls_delete(struct fimc_ctx *ctx) 625void fimc_ctrls_delete(struct fimc_ctx *ctx)
561{ 626{
562 if (ctx->ctrls_rdy) { 627 struct fimc_ctrls *ctrls = &ctx->ctrls;
563 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 628
564 ctx->ctrls_rdy = false; 629 if (ctrls->ready) {
565 ctx->ctrl_alpha = NULL; 630 v4l2_ctrl_handler_free(&ctrls->handler);
631 ctrls->ready = false;
632 ctrls->alpha = NULL;
566 } 633 }
567} 634}
568 635
569void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) 636void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
570{ 637{
571 unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA; 638 unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
639 struct fimc_ctrls *ctrls = &ctx->ctrls;
572 640
573 if (!ctx->ctrls_rdy) 641 if (!ctrls->ready)
574 return; 642 return;
575 643
576 mutex_lock(&ctx->ctrl_handler.lock); 644 mutex_lock(&ctrls->handler.lock);
577 v4l2_ctrl_activate(ctx->ctrl_rotate, active); 645 v4l2_ctrl_activate(ctrls->rotate, active);
578 v4l2_ctrl_activate(ctx->ctrl_hflip, active); 646 v4l2_ctrl_activate(ctrls->hflip, active);
579 v4l2_ctrl_activate(ctx->ctrl_vflip, active); 647 v4l2_ctrl_activate(ctrls->vflip, active);
580 if (ctx->ctrl_alpha) 648 v4l2_ctrl_activate(ctrls->colorfx, active);
581 v4l2_ctrl_activate(ctx->ctrl_alpha, active && has_alpha); 649 if (ctrls->alpha)
650 v4l2_ctrl_activate(ctrls->alpha, active && has_alpha);
582 651
583 if (active) { 652 if (active) {
584 ctx->rotation = ctx->ctrl_rotate->val; 653 fimc_set_color_effect(ctx, ctrls->colorfx->cur.val);
585 ctx->hflip = ctx->ctrl_hflip->val; 654 ctx->rotation = ctrls->rotate->val;
586 ctx->vflip = ctx->ctrl_vflip->val; 655 ctx->hflip = ctrls->hflip->val;
656 ctx->vflip = ctrls->vflip->val;
587 } else { 657 } else {
658 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
588 ctx->rotation = 0; 659 ctx->rotation = 0;
589 ctx->hflip = 0; 660 ctx->hflip = 0;
590 ctx->vflip = 0; 661 ctx->vflip = 0;
591 } 662 }
592 mutex_unlock(&ctx->ctrl_handler.lock); 663 mutex_unlock(&ctrls->handler.lock);
593} 664}
594 665
595/* Update maximum value of the alpha color control */ 666/* Update maximum value of the alpha color control */
596void fimc_alpha_ctrl_update(struct fimc_ctx *ctx) 667void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
597{ 668{
598 struct fimc_dev *fimc = ctx->fimc_dev; 669 struct fimc_dev *fimc = ctx->fimc_dev;
599 struct v4l2_ctrl *ctrl = ctx->ctrl_alpha; 670 struct v4l2_ctrl *ctrl = ctx->ctrls.alpha;
600 671
601 if (ctrl == NULL || !fimc->variant->has_alpha) 672 if (ctrl == NULL || !fimc->variant->has_alpha)
602 return; 673 return;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 3ca8c2682e0e..794c496d6811 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -446,6 +446,30 @@ struct fimc_dev {
446}; 446};
447 447
448/** 448/**
449 * struct fimc_ctrls - v4l2 controls structure
450 * @handler: the control handler
451 * @colorfx: image effect control
452 * @colorfx_cbcr: Cb/Cr coefficients control
453 * @rotate: image rotation control
454 * @hflip: horizontal flip control
455 * @vflip: vertical flip control
456 * @alpha: RGB alpha control
457 * @ready: true if @handler is initialized
458 */
459struct fimc_ctrls {
460 struct v4l2_ctrl_handler handler;
461 struct {
462 struct v4l2_ctrl *colorfx;
463 struct v4l2_ctrl *colorfx_cbcr;
464 };
465 struct v4l2_ctrl *rotate;
466 struct v4l2_ctrl *hflip;
467 struct v4l2_ctrl *vflip;
468 struct v4l2_ctrl *alpha;
469 bool ready;
470};
471
472/**
449 * fimc_ctx - the device context data 473 * fimc_ctx - the device context data
450 * @s_frame: source frame properties 474 * @s_frame: source frame properties
451 * @d_frame: destination frame properties 475 * @d_frame: destination frame properties
@@ -465,12 +489,7 @@ struct fimc_dev {
465 * @fimc_dev: the FIMC device this context applies to 489 * @fimc_dev: the FIMC device this context applies to
466 * @m2m_ctx: memory-to-memory device context 490 * @m2m_ctx: memory-to-memory device context
467 * @fh: v4l2 file handle 491 * @fh: v4l2 file handle
468 * @ctrl_handler: v4l2 controls handler 492 * @ctrls: v4l2 controls structure
469 * @ctrl_rotate image rotation control
470 * @ctrl_hflip horizontal flip control
471 * @ctrl_vflip vertical flip control
472 * @ctrl_alpha RGB alpha control
473 * @ctrls_rdy: true if the control handler is initialized
474 */ 493 */
475struct fimc_ctx { 494struct fimc_ctx {
476 struct fimc_frame s_frame; 495 struct fimc_frame s_frame;
@@ -491,12 +510,7 @@ struct fimc_ctx {
491 struct fimc_dev *fimc_dev; 510 struct fimc_dev *fimc_dev;
492 struct v4l2_m2m_ctx *m2m_ctx; 511 struct v4l2_m2m_ctx *m2m_ctx;
493 struct v4l2_fh fh; 512 struct v4l2_fh fh;
494 struct v4l2_ctrl_handler ctrl_handler; 513 struct fimc_ctrls ctrls;
495 struct v4l2_ctrl *ctrl_rotate;
496 struct v4l2_ctrl *ctrl_hflip;
497 struct v4l2_ctrl *ctrl_vflip;
498 struct v4l2_ctrl *ctrl_alpha;
499 bool ctrls_rdy;
500}; 514};
501 515
502#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh) 516#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c
index 3de22b0db66f..4c58e0570962 100644
--- a/drivers/media/video/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/video/s5p-fimc/fimc-m2m.c
@@ -150,7 +150,7 @@ static void fimc_device_run(void *priv)
150 fimc_hw_set_mainscaler(ctx); 150 fimc_hw_set_mainscaler(ctx);
151 fimc_hw_set_target_format(ctx); 151 fimc_hw_set_target_format(ctx);
152 fimc_hw_set_rotation(ctx); 152 fimc_hw_set_rotation(ctx);
153 fimc_hw_set_effect(ctx, false); 153 fimc_hw_set_effect(ctx);
154 fimc_hw_set_out_dma(ctx); 154 fimc_hw_set_out_dma(ctx);
155 if (fimc->variant->has_alpha) 155 if (fimc->variant->has_alpha)
156 fimc_hw_set_rgb_alpha(ctx); 156 fimc_hw_set_rgb_alpha(ctx);
@@ -669,7 +669,7 @@ static int fimc_m2m_open(struct file *file)
669 goto error_fh; 669 goto error_fh;
670 670
671 /* Use separate control handler per file handle */ 671 /* Use separate control handler per file handle */
672 ctx->fh.ctrl_handler = &ctx->ctrl_handler; 672 ctx->fh.ctrl_handler = &ctx->ctrls.handler;
673 file->private_data = &ctx->fh; 673 file->private_data = &ctx->fh;
674 v4l2_fh_add(&ctx->fh); 674 v4l2_fh_add(&ctx->fh);
675 675
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index 78c95d7ddde7..1fc4ce8446f5 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -368,13 +368,13 @@ void fimc_hw_en_capture(struct fimc_ctx *ctx)
368 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT); 368 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
369} 369}
370 370
371void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active) 371void fimc_hw_set_effect(struct fimc_ctx *ctx)
372{ 372{
373 struct fimc_dev *dev = ctx->fimc_dev; 373 struct fimc_dev *dev = ctx->fimc_dev;
374 struct fimc_effect *effect = &ctx->effect; 374 struct fimc_effect *effect = &ctx->effect;
375 u32 cfg = 0; 375 u32 cfg = 0;
376 376
377 if (active) { 377 if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
378 cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER | 378 cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
379 FIMC_REG_CIIMGEFF_IE_ENABLE; 379 FIMC_REG_CIIMGEFF_IE_ENABLE;
380 cfg |= effect->type; 380 cfg |= effect->type;
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.h b/drivers/media/video/s5p-fimc/fimc-reg.h
index 1472880b94ff..579ac8ac03de 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.h
+++ b/drivers/media/video/s5p-fimc/fimc-reg.h
@@ -288,7 +288,7 @@ void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
288void fimc_hw_set_prescaler(struct fimc_ctx *ctx); 288void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
289void fimc_hw_set_mainscaler(struct fimc_ctx *ctx); 289void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
290void fimc_hw_en_capture(struct fimc_ctx *ctx); 290void fimc_hw_en_capture(struct fimc_ctx *ctx);
291void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active); 291void fimc_hw_set_effect(struct fimc_ctx *ctx);
292void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx); 292void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
293void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 293void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
294void fimc_hw_set_input_path(struct fimc_ctx *ctx); 294void fimc_hw_set_input_path(struct fimc_ctx *ctx);