28682d4574b8c356c6741e868cec8f90fe41b03d
[openwrt/staging/neocturne.git] /
1 From 98105970373a9e79dcaa4291f2802b1dd9fe909e Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 16 Feb 2023 00:29:57 +0200
4 Subject: [PATCH] media: i2c: imx290: Convert V4L2_CID_HBLANK to
5 read/write
6
7 Should be upstream commit 8cab2bd86307
8
9 The driver exposed V4L2_CID_HBLANK as a read only control to allow
10 for exposure calculations and determination of the frame rate.
11
12 Convert to a read/write control so that the frame rate can be
13 controlled.
14
15 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
17 Reviewed-by: Alexander Stein <alexander.stein@ew.tq-group.com>
18 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
19 Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
20 ---
21 drivers/media/i2c/imx290.c | 33 +++++++++++++++++++--------------
22 1 file changed, 19 insertions(+), 14 deletions(-)
23
24 --- a/drivers/media/i2c/imx290.c
25 +++ b/drivers/media/i2c/imx290.c
26 @@ -50,6 +50,7 @@
27 #define IMX290_GAIN IMX290_REG_8BIT(0x3014)
28 #define IMX290_VMAX IMX290_REG_24BIT(0x3018)
29 #define IMX290_HMAX IMX290_REG_16BIT(0x301c)
30 +#define IMX290_HMAX_MAX 0xffff
31 #define IMX290_SHS1 IMX290_REG_24BIT(0x3020)
32 #define IMX290_WINWV_OB IMX290_REG_8BIT(0x303a)
33 #define IMX290_WINPV IMX290_REG_16BIT(0x303c)
34 @@ -186,7 +187,7 @@ struct imx290_regval {
35 struct imx290_mode {
36 u32 width;
37 u32 height;
38 - u32 hmax;
39 + u32 hmax_min;
40 u8 link_freq_index;
41
42 const struct imx290_regval *data;
43 @@ -429,7 +430,7 @@ static const struct imx290_mode imx290_m
44 {
45 .width = 1920,
46 .height = 1080,
47 - .hmax = 2200,
48 + .hmax_min = 2200,
49 .link_freq_index = FREQ_INDEX_1080P,
50 .data = imx290_1080p_settings,
51 .data_size = ARRAY_SIZE(imx290_1080p_settings),
52 @@ -437,7 +438,7 @@ static const struct imx290_mode imx290_m
53 {
54 .width = 1280,
55 .height = 720,
56 - .hmax = 3300,
57 + .hmax_min = 3300,
58 .link_freq_index = FREQ_INDEX_720P,
59 .data = imx290_720p_settings,
60 .data_size = ARRAY_SIZE(imx290_720p_settings),
61 @@ -448,7 +449,7 @@ static const struct imx290_mode imx290_m
62 {
63 .width = 1920,
64 .height = 1080,
65 - .hmax = 2200,
66 + .hmax_min = 2200,
67 .link_freq_index = FREQ_INDEX_1080P,
68 .data = imx290_1080p_settings,
69 .data_size = ARRAY_SIZE(imx290_1080p_settings),
70 @@ -456,7 +457,7 @@ static const struct imx290_mode imx290_m
71 {
72 .width = 1280,
73 .height = 720,
74 - .hmax = 3300,
75 + .hmax_min = 3300,
76 .link_freq_index = FREQ_INDEX_720P,
77 .data = imx290_720p_settings,
78 .data_size = ARRAY_SIZE(imx290_720p_settings),
79 @@ -712,6 +713,12 @@ static int imx290_set_ctrl(struct v4l2_c
80 }
81 break;
82
83 + case V4L2_CID_HBLANK:
84 + ret = imx290_write(imx290, IMX290_HMAX,
85 + ctrl->val + imx290->current_mode->width,
86 + NULL);
87 + break;
88 +
89 default:
90 ret = -EINVAL;
91 break;
92 @@ -742,12 +749,14 @@ static void imx290_ctrl_update(struct im
93 const struct v4l2_mbus_framefmt *format,
94 const struct imx290_mode *mode)
95 {
96 - unsigned int hblank = mode->hmax - mode->width;
97 + unsigned int hblank_min = mode->hmax_min - mode->width;
98 + unsigned int hblank_max = IMX290_HMAX_MAX - mode->width;
99 unsigned int vblank = IMX290_VMAX_DEFAULT - mode->height;
100
101 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
102
103 - __v4l2_ctrl_modify_range(imx290->hblank, hblank, hblank, 1, hblank);
104 + __v4l2_ctrl_modify_range(imx290->hblank, hblank_min, hblank_max, 1,
105 + hblank_min);
106 __v4l2_ctrl_modify_range(imx290->vblank, vblank, vblank, 1, vblank);
107 }
108
109 @@ -804,10 +813,11 @@ static int imx290_ctrl_init(struct imx29
110 ARRAY_SIZE(imx290_test_pattern_menu) - 1,
111 0, 0, imx290_test_pattern_menu);
112
113 + /*
114 + * Actual range will be set from imx290_ctrl_update later in the probe.
115 + */
116 imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
117 V4L2_CID_HBLANK, 1, 1, 1, 1);
118 - if (imx290->hblank)
119 - imx290->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
120
121 imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
122 V4L2_CID_VBLANK, 1, 1, 1, 1);
123 @@ -876,11 +886,6 @@ static int imx290_start_streaming(struct
124 return ret;
125 }
126
127 - ret = imx290_write(imx290, IMX290_HMAX, imx290->current_mode->hmax,
128 - NULL);
129 - if (ret)
130 - return ret;
131 -
132 /* Apply customized values from user */
133 ret = __v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
134 if (ret) {