aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/ov772x.c88
-rw-r--r--include/media/ov772x.h5
2 files changed, 89 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
546static 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
677static 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
693static 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
653static int ov772x_get_chip_id(struct soc_camera_device *icd, 720static 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,
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
index e391d55edb95..57db48dd85b8 100644
--- a/include/media/ov772x.h
+++ b/include/media/ov772x.h
@@ -13,8 +13,13 @@
13 13
14#include <media/soc_camera.h> 14#include <media/soc_camera.h>
15 15
16/* for flags */
17#define OV772X_FLAG_VFLIP 0x00000001 /* Vertical flip image */
18#define OV772X_FLAG_HFLIP 0x00000002 /* Horizontal flip image */
19
16struct ov772x_camera_info { 20struct ov772x_camera_info {
17 unsigned long buswidth; 21 unsigned long buswidth;
22 unsigned long flags;
18 struct soc_camera_link link; 23 struct soc_camera_link link;
19}; 24};
20 25