From cd57e1598e397112261dc8a997c5229e608d6eb6 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Date: Tue, 31 Mar 2009 08:32:33 +0200
Subject: [PATCH] ov772x: add edge contrl support

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/media/video/ov772x.c |   63 +++++++++++++++++++++++++++++++++++++++--
 include/media/ov772x.h       |   35 +++++++++++++++++++++++
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 34c9819..c0d9112 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -169,11 +169,11 @@
 #define GAM15       0x8C /* Gamma Curve 15th segment input end point */
 #define SLOP        0x8D /* Gamma curve highest segment slope */
 #define DNSTH       0x8E /* De-noise threshold */
-#define EDGE0       0x8F /* Edge enhancement control 0 */
-#define EDGE1       0x90 /* Edge enhancement control 1 */
+#define EDGE_STRNGT 0x8F /* Edge strength  control when manual mode */
+#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
 #define DNSOFF      0x91 /* Auto De-noise threshold control */
-#define EDGE2       0x92 /* Edge enhancement strength low  point control */
-#define EDGE3       0x93 /* Edge enhancement strength high point control */
+#define EDGE_UPPER  0x92 /* Edge strength upper limit when Auto mode */
+#define EDGE_LOWER  0x93 /* Edge strength lower limit when Auto mode */
 #define MTX1        0x94 /* Matrix coefficient 1 */
 #define MTX2        0x95 /* Matrix coefficient 2 */
 #define MTX3        0x96 /* Matrix coefficient 3 */
@@ -358,6 +358,14 @@
 #define VOSZ_VGA        0xF0
 #define VOSZ_QVGA       0x78
 
+/* DSPAUTO (DSP Auto Function ON/OFF Control) */
+#define AWB_ACTRL       0x80 /* AWB auto threshold control */
+#define DENOISE_ACTRL   0x40 /* De-noise auto threshold control */
+#define EDGE_ACTRL      0x20 /* Edge enhancement auto strength control */
+#define UV_ACTRL        0x10 /* UV adjust auto slope control */
+#define SCAL0_ACTRL     0x08 /* Auto scaling factor control */
+#define SCAL1_2_ACTRL   0x04 /* Auto scaling factor control */
+
 /*
  * ID
  */
@@ -816,6 +824,53 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	ov772x_reset(priv->client);
 
 	/*
+	 * Edge Ctrl
+	 */
+	if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
+
+		/*
+		 * Manual Edge Control Mode
+		 *
+		 * Edge auto strength bit is set by default.
+		 * Remove it when manual mode.
+		 */
+
+		ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
+				      priv->info->edgectrl.threshold);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_STRNGT, EDGE_STRENGTH_MASK,
+				      priv->info->edgectrl.strength);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+	} else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
+		/*
+		 * Auto Edge Control Mode
+		 *
+		 * set upper and lower limit
+		 */
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_UPPER, EDGE_UPPER_MASK,
+				      priv->info->edgectrl.upper);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_LOWER, EDGE_LOWER_MASK,
+				      priv->info->edgectrl.lower);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	/*
 	 * set size format
 	 */
 	ret = ov772x_write_array(priv->client, priv->win->regs);
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
index 57db48d..30d9629 100644
--- a/include/media/ov772x.h
+++ b/include/media/ov772x.h
@@ -17,10 +17,45 @@
 #define OV772X_FLAG_VFLIP     0x00000001 /* Vertical flip image */
 #define OV772X_FLAG_HFLIP     0x00000002 /* Horizontal flip image */
 
+/*
+ * for Edge ctrl
+ *
+ * strength also control Auto or Manual Edge Control Mode
+ * see also OV772X_MANUAL_EDGE_CTRL
+ */
+struct ov772x_edge_ctrl {
+	unsigned char strength;
+	unsigned char threshold;
+	unsigned char upper;
+	unsigned char lower;
+};
+
+#define OV772X_MANUAL_EDGE_CTRL	0x80 /* un-used bit of strength */
+#define EDGE_STRENGTH_MASK	0x1F
+#define EDGE_THRESHOLD_MASK	0x0F
+#define EDGE_UPPER_MASK		0xFF
+#define EDGE_LOWER_MASK		0xFF
+
+#define OV772X_AUTO_EDGECTRL(u, l)	\
+{					\
+	.upper = (u & EDGE_UPPER_MASK),	\
+	.lower = (l & EDGE_LOWER_MASK),	\
+}
+
+#define OV772X_MANUAL_EDGECTRL(s, t)					\
+{									\
+	.strength  = (s & EDGE_STRENGTH_MASK) | OV772X_MANUAL_EDGE_CTRL,\
+	.threshold = (t & EDGE_THRESHOLD_MASK),				\
+}
+
+/*
+ * ov772x camera info
+ */
 struct ov772x_camera_info {
 	unsigned long          buswidth;
 	unsigned long          flags;
 	struct soc_camera_link link;
+	struct ov772x_edge_ctrl edgectrl;
 };
 
 #endif /* __OV772X_H__ */
-- 
1.5.4

