bcm27xx: switch to 5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.10 / 950-0271-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch
1 From e8ad74c090f54cf8ce845b627e4312b6166059fd Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 11 Jun 2020 18:09:12 +0100
4 Subject: [PATCH] media: i2c: imx290: Add support for V4L2_CID_VBLANK
5
6 In order to calculate framerate and durations userspace needs
7 the vertical blanking information. This can be configurable,
8 and indeed the datasheet lists different values for VBLANK for
9 the 1080p and 720p modes.
10
11 Add the new control, and adopt the datasheet values for each mode.
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
14 ---
15 drivers/media/i2c/imx290.c | 38 ++++++++++++++++++++++++++++++++++++--
16 1 file changed, 36 insertions(+), 2 deletions(-)
17
18 --- a/drivers/media/i2c/imx290.c
19 +++ b/drivers/media/i2c/imx290.c
20 @@ -38,6 +38,8 @@ enum imx290_clk_index {
21 #define IMX290_BLKLEVEL_LOW 0x300a
22 #define IMX290_BLKLEVEL_HIGH 0x300b
23 #define IMX290_GAIN 0x3014
24 +#define IMX290_VMAX_LOW 0x3018
25 +#define IMX290_VMAX_MAX 0x3fff
26 #define IMX290_HMAX_LOW 0x301c
27 #define IMX290_HMAX_HIGH 0x301d
28 #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */
29 @@ -68,6 +70,7 @@ struct imx290_mode {
30 u32 width;
31 u32 height;
32 u32 hmax;
33 + u32 vmax;
34 u8 link_freq_index;
35
36 const struct imx290_regval *data;
37 @@ -99,6 +102,7 @@ struct imx290 {
38 struct v4l2_ctrl *link_freq;
39 struct v4l2_ctrl *pixel_rate;
40 struct v4l2_ctrl *hblank;
41 + struct v4l2_ctrl *vblank;
42
43 struct mutex lock;
44 };
45 @@ -132,8 +136,6 @@ static const char * const imx290_test_pa
46
47 static const struct imx290_regval imx290_global_init_settings[] = {
48 { 0x3007, 0x00 },
49 - { 0x3018, 0x65 },
50 - { 0x3019, 0x04 },
51 { 0x301a, 0x00 },
52 { 0x303a, 0x0c },
53 { 0x3040, 0x00 },
54 @@ -360,6 +362,7 @@ static const struct imx290_mode imx290_m
55 .width = 1920,
56 .height = 1080,
57 .hmax = 0x1130,
58 + .vmax = 0x0465,
59 .link_freq_index = FREQ_INDEX_1080P,
60 .data = imx290_1080p_settings,
61 .data_size = ARRAY_SIZE(imx290_1080p_settings),
62 @@ -373,6 +376,7 @@ static const struct imx290_mode imx290_m
63 .width = 1280,
64 .height = 720,
65 .hmax = 0x19c8,
66 + .vmax = 0x02ee,
67 .link_freq_index = FREQ_INDEX_720P,
68 .data = imx290_720p_settings,
69 .data_size = ARRAY_SIZE(imx290_720p_settings),
70 @@ -389,6 +393,7 @@ static const struct imx290_mode imx290_m
71 .width = 1920,
72 .height = 1080,
73 .hmax = 0x0898,
74 + .vmax = 0x0465,
75 .link_freq_index = FREQ_INDEX_1080P,
76 .data = imx290_1080p_settings,
77 .data_size = ARRAY_SIZE(imx290_1080p_settings),
78 @@ -402,6 +407,7 @@ static const struct imx290_mode imx290_m
79 .width = 1280,
80 .height = 720,
81 .hmax = 0x0ce4,
82 + .vmax = 0x02ee,
83 .link_freq_index = FREQ_INDEX_720P,
84 .data = imx290_720p_settings,
85 .data_size = ARRAY_SIZE(imx290_720p_settings),
86 @@ -543,6 +549,19 @@ static int imx290_set_hmax(struct imx290
87 return 0;
88 }
89
90 +static int imx290_set_vmax(struct imx290 *imx290, u32 val)
91 +{
92 + u32 vmax = val + imx290->current_mode->height;
93 + int ret;
94 +
95 + ret = imx290_write_buffered_reg(imx290, IMX290_VMAX_LOW, 3,
96 + vmax);
97 + if (ret)
98 + dev_err(imx290->dev, "Unable to write vmax\n");
99 +
100 + return ret;
101 +}
102 +
103 /* Stop streaming */
104 static int imx290_stop_streaming(struct imx290 *imx290)
105 {
106 @@ -574,6 +593,9 @@ static int imx290_set_ctrl(struct v4l2_c
107 case V4L2_CID_HBLANK:
108 ret = imx290_set_hmax(imx290, ctrl->val);
109 break;
110 + case V4L2_CID_VBLANK:
111 + ret = imx290_set_vmax(imx290, ctrl->val);
112 + break;
113 case V4L2_CID_TEST_PATTERN:
114 if (ctrl->val) {
115 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
116 @@ -736,6 +758,12 @@ static int imx290_set_fmt(struct v4l2_su
117 imx290->hmax_min - mode->width,
118 IMX290_HMAX_MAX - mode->width,
119 1, mode->hmax - mode->width);
120 + if (imx290->vblank)
121 + __v4l2_ctrl_modify_range(imx290->vblank,
122 + mode->vmax - mode->height,
123 + IMX290_VMAX_MAX - mode->height,
124 + 1,
125 + mode->vmax - mode->height);
126 }
127
128 *format = fmt->format;
129 @@ -1148,6 +1176,12 @@ static int imx290_probe(struct i2c_clien
130 IMX290_HMAX_MAX - mode->width, 1,
131 mode->hmax - mode->width);
132
133 + imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
134 + V4L2_CID_VBLANK,
135 + mode->vmax - mode->height,
136 + IMX290_VMAX_MAX - mode->height, 1,
137 + mode->vmax - mode->height);
138 +
139 imx290->link_freq =
140 v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
141 V4L2_CID_LINK_FREQ,