f07e572f64
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
142 lines
4.3 KiB
Diff
142 lines
4.3 KiB
Diff
From 12a04a18c7a56dbd2943b6666c7978b09499fc4b Mon Sep 17 00:00:00 2001
|
|
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|
Date: Thu, 11 Jun 2020 18:09:12 +0100
|
|
Subject: [PATCH] media: i2c: imx290: Add support for V4L2_CID_VBLANK
|
|
|
|
In order to calculate framerate and durations userspace needs
|
|
the vertical blanking information. This can be configurable,
|
|
and indeed the datasheet lists different values for VBLANK for
|
|
the 1080p and 720p modes.
|
|
|
|
Add the new control, and adopt the datasheet values for each mode.
|
|
|
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|
---
|
|
drivers/media/i2c/imx290.c | 38 ++++++++++++++++++++++++++++++++++++--
|
|
1 file changed, 36 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/media/i2c/imx290.c
|
|
+++ b/drivers/media/i2c/imx290.c
|
|
@@ -38,6 +38,8 @@ enum imx290_clk_index {
|
|
#define IMX290_BLKLEVEL_LOW 0x300a
|
|
#define IMX290_BLKLEVEL_HIGH 0x300b
|
|
#define IMX290_GAIN 0x3014
|
|
+#define IMX290_VMAX_LOW 0x3018
|
|
+#define IMX290_VMAX_MAX 0x3fff
|
|
#define IMX290_HMAX_LOW 0x301c
|
|
#define IMX290_HMAX_HIGH 0x301d
|
|
#define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */
|
|
@@ -68,6 +70,7 @@ struct imx290_mode {
|
|
u32 width;
|
|
u32 height;
|
|
u32 hmax;
|
|
+ u32 vmax;
|
|
u8 link_freq_index;
|
|
|
|
const struct imx290_regval *data;
|
|
@@ -99,6 +102,7 @@ struct imx290 {
|
|
struct v4l2_ctrl *link_freq;
|
|
struct v4l2_ctrl *pixel_rate;
|
|
struct v4l2_ctrl *hblank;
|
|
+ struct v4l2_ctrl *vblank;
|
|
|
|
struct mutex lock;
|
|
};
|
|
@@ -132,8 +136,6 @@ static const char * const imx290_test_pa
|
|
|
|
static const struct imx290_regval imx290_global_init_settings[] = {
|
|
{ 0x3007, 0x00 },
|
|
- { 0x3018, 0x65 },
|
|
- { 0x3019, 0x04 },
|
|
{ 0x301a, 0x00 },
|
|
{ 0x303a, 0x0c },
|
|
{ 0x3040, 0x00 },
|
|
@@ -360,6 +362,7 @@ static const struct imx290_mode imx290_m
|
|
.width = 1920,
|
|
.height = 1080,
|
|
.hmax = 0x1130,
|
|
+ .vmax = 0x0465,
|
|
.link_freq_index = FREQ_INDEX_1080P,
|
|
.data = imx290_1080p_settings,
|
|
.data_size = ARRAY_SIZE(imx290_1080p_settings),
|
|
@@ -373,6 +376,7 @@ static const struct imx290_mode imx290_m
|
|
.width = 1280,
|
|
.height = 720,
|
|
.hmax = 0x19c8,
|
|
+ .vmax = 0x02ee,
|
|
.link_freq_index = FREQ_INDEX_720P,
|
|
.data = imx290_720p_settings,
|
|
.data_size = ARRAY_SIZE(imx290_720p_settings),
|
|
@@ -389,6 +393,7 @@ static const struct imx290_mode imx290_m
|
|
.width = 1920,
|
|
.height = 1080,
|
|
.hmax = 0x0898,
|
|
+ .vmax = 0x0465,
|
|
.link_freq_index = FREQ_INDEX_1080P,
|
|
.data = imx290_1080p_settings,
|
|
.data_size = ARRAY_SIZE(imx290_1080p_settings),
|
|
@@ -402,6 +407,7 @@ static const struct imx290_mode imx290_m
|
|
.width = 1280,
|
|
.height = 720,
|
|
.hmax = 0x0ce4,
|
|
+ .vmax = 0x02ee,
|
|
.link_freq_index = FREQ_INDEX_720P,
|
|
.data = imx290_720p_settings,
|
|
.data_size = ARRAY_SIZE(imx290_720p_settings),
|
|
@@ -543,6 +549,19 @@ static int imx290_set_hmax(struct imx290
|
|
return 0;
|
|
}
|
|
|
|
+static int imx290_set_vmax(struct imx290 *imx290, u32 val)
|
|
+{
|
|
+ u32 vmax = val + imx290->current_mode->height;
|
|
+ int ret;
|
|
+
|
|
+ ret = imx290_write_buffered_reg(imx290, IMX290_VMAX_LOW, 3,
|
|
+ vmax);
|
|
+ if (ret)
|
|
+ dev_err(imx290->dev, "Unable to write vmax\n");
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/* Stop streaming */
|
|
static int imx290_stop_streaming(struct imx290 *imx290)
|
|
{
|
|
@@ -574,6 +593,9 @@ static int imx290_set_ctrl(struct v4l2_c
|
|
case V4L2_CID_HBLANK:
|
|
ret = imx290_set_hmax(imx290, ctrl->val);
|
|
break;
|
|
+ case V4L2_CID_VBLANK:
|
|
+ ret = imx290_set_vmax(imx290, ctrl->val);
|
|
+ break;
|
|
case V4L2_CID_TEST_PATTERN:
|
|
if (ctrl->val) {
|
|
imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
|
|
@@ -736,6 +758,12 @@ static int imx290_set_fmt(struct v4l2_su
|
|
imx290->hmax_min - mode->width,
|
|
IMX290_HMAX_MAX - mode->width,
|
|
1, mode->hmax - mode->width);
|
|
+ if (imx290->vblank)
|
|
+ __v4l2_ctrl_modify_range(imx290->vblank,
|
|
+ mode->vmax - mode->height,
|
|
+ IMX290_VMAX_MAX - mode->height,
|
|
+ 1,
|
|
+ mode->vmax - mode->height);
|
|
}
|
|
|
|
*format = fmt->format;
|
|
@@ -1148,6 +1176,12 @@ static int imx290_probe(struct i2c_clien
|
|
IMX290_HMAX_MAX - mode->width, 1,
|
|
mode->hmax - mode->width);
|
|
|
|
+ imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
|
|
+ V4L2_CID_VBLANK,
|
|
+ mode->vmax - mode->height,
|
|
+ IMX290_VMAX_MAX - mode->height, 1,
|
|
+ mode->vmax - mode->height);
|
|
+
|
|
imx290->link_freq =
|
|
v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
|
|
V4L2_CID_LINK_FREQ,
|