V4L/DVB (10666): ov772x: move configuration from start_capture() to set_fmt()

soc_camera framework requires, that camera configuration is performed in
set_fmt, and start_capture and stop_capture only turn the camera on/off.
This patch modifies ov772x to comply to this requirement.

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>
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 4d8ac6f..4d54e18 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -500,9 +500,8 @@
 /*
  * color format list
  */
-#define T_YUYV 0
 static const struct ov772x_color_format ov772x_cfmts[] = {
-	[T_YUYV] = {
+	{
 		SETFOURCC(YUYV),
 		.regs   = ov772x_YYUV_regs,
 	},
@@ -635,74 +634,20 @@
 static int ov772x_start_capture(struct soc_camera_device *icd)
 {
 	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	int                 ret;
 
-	if (!priv->win)
-		priv->win = &ov772x_win_vga;
-	if (!priv->fmt)
-		priv->fmt = &ov772x_cfmts[T_YUYV];
-
-	/*
-	 * reset hardware
-	 */
-	ov772x_reset(priv->client);
-
-	/*
-	 * set color format
-	 */
-	ret = ov772x_write_array(priv->client, priv->fmt->regs);
-	if (ret < 0)
-		goto start_end;
-
-	/*
-	 * set size format
-	 */
-	ret = ov772x_write_array(priv->client, priv->win->regs);
-	if (ret < 0)
-		goto start_end;
-
-	/*
-	 * set COM7 bit ( QVGA or VGA )
-	 */
-	ret = ov772x_mask_set(priv->client,
-			      COM7, SLCT_MASK, priv->win->com7_bit);
-	if (ret < 0)
-		goto start_end;
-
-	/*
-	 * set UV setting
-	 */
-	if (priv->fmt->option & OP_UV) {
-		ret = ov772x_mask_set(priv->client,
-				      DSP_CTRL3, UV_MASK, UV_ON);
-		if (ret < 0)
-			goto start_end;
-	}
-
-	/*
-	 * set SWAP setting
-	 */
-	if (priv->fmt->option & OP_SWAP_RGB) {
-		ret = ov772x_mask_set(priv->client,
-				      COM3, SWAP_MASK, SWAP_RGB);
-		if (ret < 0)
-			goto start_end;
+	if (!priv->win || !priv->fmt) {
+		dev_err(&icd->dev, "norm or win select error\n");
+		return -EPERM;
 	}
 
 	dev_dbg(&icd->dev,
 		 "format %s, win %s\n", priv->fmt->name, priv->win->name);
 
-start_end:
-	priv->fmt = NULL;
-	priv->win = NULL;
-
-	return ret;
+	return 0;
 }
 
 static int ov772x_stop_capture(struct soc_camera_device *icd)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	ov772x_reset(priv->client);
 	return 0;
 }
 
@@ -787,7 +732,6 @@
 	return win;
 }
 
-
 static int ov772x_set_fmt(struct soc_camera_device *icd,
 			  __u32                     pixfmt,
 			  struct v4l2_rect         *rect)
@@ -803,16 +747,72 @@
 	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
 		if (pixfmt == ov772x_cfmts[i].fourcc) {
 			priv->fmt = ov772x_cfmts + i;
-			ret = 0;
 			break;
 		}
 	}
+	if (!priv->fmt)
+		goto ov772x_set_fmt_error;
 
 	/*
 	 * select win
 	 */
 	priv->win = ov772x_select_win(rect->width, rect->height);
 
+	/*
+	 * reset hardware
+	 */
+	ov772x_reset(priv->client);
+
+	/*
+	 * set color format
+	 */
+	ret = ov772x_write_array(priv->client, priv->fmt->regs);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	/*
+	 * set size format
+	 */
+	ret = ov772x_write_array(priv->client, priv->win->regs);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	/*
+	 * set COM7 bit ( QVGA or VGA )
+	 */
+	ret = ov772x_mask_set(priv->client,
+			      COM7, SLCT_MASK, priv->win->com7_bit);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	/*
+	 * set UV setting
+	 */
+	if (priv->fmt->option & OP_UV) {
+		ret = ov772x_mask_set(priv->client,
+				      DSP_CTRL3, UV_MASK, UV_ON);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	/*
+	 * set SWAP setting
+	 */
+	if (priv->fmt->option & OP_SWAP_RGB) {
+		ret = ov772x_mask_set(priv->client,
+				      COM3, SWAP_MASK, SWAP_RGB);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	return ret;
+
+ov772x_set_fmt_error:
+
+	ov772x_reset(priv->client);
+	priv->win = NULL;
+	priv->fmt = NULL;
+
 	return ret;
 }
 
@@ -889,7 +889,6 @@
 		 i2c_smbus_read_byte_data(priv->client, MIDH),
 		 i2c_smbus_read_byte_data(priv->client, MIDL));
 
-
 	return soc_camera_video_start(icd);
 }