summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0471-media-i2c-ov10640-add-fps-setup.patch
blob: cf009e51b6b208525abf9619d0f0c0f867d7a203 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
From 969dff5e0dbd9ad6b289073410dbd3013ccd5e31 Mon Sep 17 00:00:00 2001
From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
Date: Mon, 10 Feb 2020 21:09:29 +0300
Subject: [PATCH] media: i2c: ov10640: add fps setup

This adds framerate change support for OV10640 imager

Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
---
 drivers/media/i2c/soc_camera/ov10640.c | 50 ++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/media/i2c/soc_camera/ov10640.c b/drivers/media/i2c/soc_camera/ov10640.c
index fab2c0d..0af091e 100644
--- a/drivers/media/i2c/soc_camera/ov10640.c
+++ b/drivers/media/i2c/soc_camera/ov10640.c
@@ -38,6 +38,7 @@ struct ov10640_priv {
 	struct media_pad		pad;
 	struct v4l2_rect		rect;
 	int				subsampling;
+	int				fps_numerator;
 	int				fps_denominator;
 	int				init_complete;
 	u8				id[6];
@@ -51,6 +52,7 @@ struct ov10640_priv {
 	int				port;
 	int				gpio_resetb;
 	int				gpio_fsin;
+	int				vts;
 };
 
 static inline struct ov10640_priv *to_ov10640(const struct i2c_client *client)
@@ -276,6 +278,51 @@ static int ov10640_g_mbus_config(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int ov10640_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov10640_priv *priv = to_ov10640(client);
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memset(cp, 0, sizeof(struct v4l2_captureparm));
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+	cp->timeperframe.numerator = priv->fps_numerator;
+	cp->timeperframe.denominator = priv->fps_denominator;
+
+	return 0;
+}
+
+static int ov10640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov10640_priv *priv = to_ov10640(client);
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+	int ret = 0;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (cp->extendedmode != 0)
+		return -EINVAL;
+
+	if (priv->fps_denominator != cp->timeperframe.denominator ||
+	    priv->fps_numerator != cp->timeperframe.numerator) {
+		priv->vts = (OV10640_SENSOR_HEIGHT + 208) * 30 * cp->timeperframe.numerator / cp->timeperframe.denominator;
+
+		reg16_write(client, 0x3012, 0);
+		reg16_write(client, 0x3082, priv->vts >> 8);
+		reg16_write(client, 0x3083, priv->vts & 0xff);
+		ret = reg16_write(client, 0x3012, 1);
+
+		priv->fps_denominator = cp->timeperframe.numerator;
+		priv->fps_denominator = cp->timeperframe.denominator;
+	}
+
+	return ret;
+}
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov10640_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
@@ -417,6 +464,8 @@ static const struct v4l2_ctrl_ops ov10640_ctrl_ops = {
 static struct v4l2_subdev_video_ops ov10640_video_ops = {
 	.s_stream	= ov10640_s_stream,
 	.g_mbus_config	= ov10640_g_mbus_config,
+	.g_parm		= ov10640_g_parm,
+	.s_parm		= ov10640_s_parm,
 };
 
 static const struct v4l2_subdev_pad_ops ov10640_subdev_pad_ops = {
@@ -643,6 +692,7 @@ static int ov10640_probe(struct i2c_client *client,
 	priv->rect.top = 0;
 	priv->rect.width = OV10640_DEFAULT_WIDTH;
 	priv->rect.height = OV10640_DEFAULT_HEIGHT;
+	priv->fps_numerator = 1;
 	priv->fps_denominator = 30;
 
 	v4l2_ctrl_handler_init(&priv->hdl, 4);
-- 
2.7.4