diff options
author | Kuninori Morimoto <morimoto.kuninori@renesas.com> | 2009-02-23 10:12:58 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:52 -0400 |
commit | 051489119affd527f2834e9f8ba3e2a71bf1ca23 (patch) | |
tree | 12dedd6fdd441df9c903a3239649ecdff6b293fc /drivers/media/video/ov772x.c | |
parent | 66b46e68a52114e7065f0bfd0016276ae5925e70 (diff) |
V4L/DVB (10669): ov772x: Add image flip support
o ov772x_camera_info :: flags supports default image flip.
o V4L2_CID_VFLIP/HFLIP supports image flip for user side.
Thank Magnus for advice.
Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r-- | drivers/media/video/ov772x.c | 88 |
1 files changed, 84 insertions, 4 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 6b18da7c3c0a..880e51f0e9fd 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -217,10 +217,11 @@ | |||
217 | #define OCAP_4x 0x03 /* 4x */ | 217 | #define OCAP_4x 0x03 /* 4x */ |
218 | 218 | ||
219 | /* COM3 */ | 219 | /* COM3 */ |
220 | #define SWAP_MASK 0x38 | 220 | #define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML) |
221 | #define IMG_MASK (VFLIP_IMG | HFLIP_IMG) | ||
221 | 222 | ||
222 | #define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */ | 223 | #define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */ |
223 | #define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */ | 224 | #define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */ |
224 | #define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */ | 225 | #define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */ |
225 | #define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */ | 226 | #define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */ |
226 | #define SWAP_ML 0x08 /* Swap output MSB/LSB */ | 227 | #define SWAP_ML 0x08 /* Swap output MSB/LSB */ |
@@ -395,6 +396,8 @@ struct ov772x_priv { | |||
395 | const struct ov772x_color_format *fmt; | 396 | const struct ov772x_color_format *fmt; |
396 | const struct ov772x_win_size *win; | 397 | const struct ov772x_win_size *win; |
397 | int model; | 398 | int model; |
399 | unsigned int flag_vflip:1; | ||
400 | unsigned int flag_hflip:1; | ||
398 | }; | 401 | }; |
399 | 402 | ||
400 | #define ENDMARKER { 0xff, 0xff } | 403 | #define ENDMARKER { 0xff, 0xff } |
@@ -540,6 +543,27 @@ static const struct ov772x_win_size ov772x_win_qvga = { | |||
540 | .regs = ov772x_qvga_regs, | 543 | .regs = ov772x_qvga_regs, |
541 | }; | 544 | }; |
542 | 545 | ||
546 | static const struct v4l2_queryctrl ov772x_controls[] = { | ||
547 | { | ||
548 | .id = V4L2_CID_VFLIP, | ||
549 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
550 | .name = "Flip Vertically", | ||
551 | .minimum = 0, | ||
552 | .maximum = 1, | ||
553 | .step = 1, | ||
554 | .default_value = 0, | ||
555 | }, | ||
556 | { | ||
557 | .id = V4L2_CID_HFLIP, | ||
558 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
559 | .name = "Flip Horizontally", | ||
560 | .minimum = 0, | ||
561 | .maximum = 1, | ||
562 | .step = 1, | ||
563 | .default_value = 0, | ||
564 | }, | ||
565 | }; | ||
566 | |||
543 | 567 | ||
544 | /* | 568 | /* |
545 | * general function | 569 | * general function |
@@ -650,6 +674,49 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) | |||
650 | return soc_camera_apply_sensor_flags(icl, flags); | 674 | return soc_camera_apply_sensor_flags(icl, flags); |
651 | } | 675 | } |
652 | 676 | ||
677 | static int ov772x_get_control(struct soc_camera_device *icd, | ||
678 | struct v4l2_control *ctrl) | ||
679 | { | ||
680 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); | ||
681 | |||
682 | switch (ctrl->id) { | ||
683 | case V4L2_CID_VFLIP: | ||
684 | ctrl->value = priv->flag_vflip; | ||
685 | break; | ||
686 | case V4L2_CID_HFLIP: | ||
687 | ctrl->value = priv->flag_hflip; | ||
688 | break; | ||
689 | } | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int ov772x_set_control(struct soc_camera_device *icd, | ||
694 | struct v4l2_control *ctrl) | ||
695 | { | ||
696 | struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); | ||
697 | int ret = 0; | ||
698 | u8 val; | ||
699 | |||
700 | switch (ctrl->id) { | ||
701 | case V4L2_CID_VFLIP: | ||
702 | val = ctrl->value ? VFLIP_IMG : 0x00; | ||
703 | priv->flag_vflip = ctrl->value; | ||
704 | if (priv->info->flags & OV772X_FLAG_VFLIP) | ||
705 | val ^= VFLIP_IMG; | ||
706 | ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val); | ||
707 | break; | ||
708 | case V4L2_CID_HFLIP: | ||
709 | val = ctrl->value ? HFLIP_IMG : 0x00; | ||
710 | priv->flag_hflip = ctrl->value; | ||
711 | if (priv->info->flags & OV772X_FLAG_HFLIP) | ||
712 | val ^= HFLIP_IMG; | ||
713 | ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val); | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | return ret; | ||
718 | } | ||
719 | |||
653 | static int ov772x_get_chip_id(struct soc_camera_device *icd, | 720 | static int ov772x_get_chip_id(struct soc_camera_device *icd, |
654 | struct v4l2_dbg_chip_ident *id) | 721 | struct v4l2_dbg_chip_ident *id) |
655 | { | 722 | { |
@@ -768,8 +835,17 @@ static int ov772x_set_fmt(struct soc_camera_device *icd, | |||
768 | * set COM3 | 835 | * set COM3 |
769 | */ | 836 | */ |
770 | val = priv->fmt->com3; | 837 | val = priv->fmt->com3; |
838 | if (priv->info->flags & OV772X_FLAG_VFLIP) | ||
839 | val |= VFLIP_IMG; | ||
840 | if (priv->info->flags & OV772X_FLAG_HFLIP) | ||
841 | val |= HFLIP_IMG; | ||
842 | if (priv->flag_vflip) | ||
843 | val ^= VFLIP_IMG; | ||
844 | if (priv->flag_hflip) | ||
845 | val ^= HFLIP_IMG; | ||
846 | |||
771 | ret = ov772x_mask_set(priv->client, | 847 | ret = ov772x_mask_set(priv->client, |
772 | COM3, SWAP_MASK, val); | 848 | COM3, SWAP_MASK | IMG_MASK, val); |
773 | if (ret < 0) | 849 | if (ret < 0) |
774 | goto ov772x_set_fmt_error; | 850 | goto ov772x_set_fmt_error; |
775 | 851 | ||
@@ -887,6 +963,10 @@ static struct soc_camera_ops ov772x_ops = { | |||
887 | .try_fmt = ov772x_try_fmt, | 963 | .try_fmt = ov772x_try_fmt, |
888 | .set_bus_param = ov772x_set_bus_param, | 964 | .set_bus_param = ov772x_set_bus_param, |
889 | .query_bus_param = ov772x_query_bus_param, | 965 | .query_bus_param = ov772x_query_bus_param, |
966 | .controls = ov772x_controls, | ||
967 | .num_controls = ARRAY_SIZE(ov772x_controls), | ||
968 | .get_control = ov772x_get_control, | ||
969 | .set_control = ov772x_set_control, | ||
890 | .get_chip_id = ov772x_get_chip_id, | 970 | .get_chip_id = ov772x_get_chip_id, |
891 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 971 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
892 | .get_register = ov772x_get_register, | 972 | .get_register = ov772x_get_register, |