1 From e3c6ec43e950d9e08715e2c693771080c7d078a3 Mon Sep 17 00:00:00 2001
2 From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
3 Date: Fri, 12 Jun 2020 15:53:50 +0200
4 Subject: [PATCH] media: i2c: imx290: Add configurable link frequency
7 Commit 98e0500eadb772e1be32d8e369fcc3b7bcac93ed upstream.
9 IMX290 operates with multiple link frequency and pixel rate combinations.
10 The initial driver used a single setting for both but since we now have
11 the lane count support in place, let's add configurable link frequency
14 Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
15 Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
16 Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
17 Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
19 drivers/media/i2c/imx290.c | 148 +++++++++++++++++++++++++++----------
20 1 file changed, 109 insertions(+), 39 deletions(-)
22 --- a/drivers/media/i2c/imx290.c
23 +++ b/drivers/media/i2c/imx290.c
25 #define IMX290_PHY_LANE_NUM 0x3407
26 #define IMX290_CSI_LANE_MODE 0x3443
28 -#define IMX290_DEFAULT_LINK_FREQ 445500000
30 static const char * const imx290_supply_name[] = {
33 @@ -51,8 +49,7 @@ struct imx290_mode {
38 - u32 link_freq_index;
41 const struct imx290_regval *data;
43 @@ -243,9 +240,36 @@ static const struct imx290_regval imx290
46 /* supported link frequencies */
47 -static const s64 imx290_link_freq[] = {
48 - IMX290_DEFAULT_LINK_FREQ,
50 +#define FREQ_INDEX_1080P 0
51 +#define FREQ_INDEX_720P 1
52 +static const s64 imx290_link_freq_2lanes[] = {
53 + [FREQ_INDEX_1080P] = 445500000,
54 + [FREQ_INDEX_720P] = 297000000,
56 +static const s64 imx290_link_freq_4lanes[] = {
57 + [FREQ_INDEX_1080P] = 222750000,
58 + [FREQ_INDEX_720P] = 148500000,
62 + * In this function and in the similar ones below We rely on imx290_probe()
63 + * to ensure that nlanes is either 2 or 4.
65 +static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290)
67 + if (imx290->nlanes == 2)
68 + return imx290_link_freq_2lanes;
70 + return imx290_link_freq_4lanes;
73 +static inline int imx290_link_freqs_num(const struct imx290 *imx290)
75 + if (imx290->nlanes == 2)
76 + return ARRAY_SIZE(imx290_link_freq_2lanes);
78 + return ARRAY_SIZE(imx290_link_freq_4lanes);
82 static const struct imx290_mode imx290_modes_2lanes[] = {
83 @@ -253,19 +277,17 @@ static const struct imx290_mode imx290_m
87 + .link_freq_index = FREQ_INDEX_1080P,
88 .data = imx290_1080p_settings,
89 .data_size = ARRAY_SIZE(imx290_1080p_settings),
90 - .pixel_rate = 178200000,
91 - .link_freq_index = 0,
97 + .link_freq_index = FREQ_INDEX_720P,
98 .data = imx290_720p_settings,
99 .data_size = ARRAY_SIZE(imx290_720p_settings),
100 - .pixel_rate = 178200000,
101 - .link_freq_index = 0,
105 @@ -274,25 +296,22 @@ static const struct imx290_mode imx290_m
109 + .link_freq_index = FREQ_INDEX_1080P,
110 .data = imx290_1080p_settings,
111 .data_size = ARRAY_SIZE(imx290_1080p_settings),
112 - .pixel_rate = 178200000,
113 - .link_freq_index = 0,
119 + .link_freq_index = FREQ_INDEX_720P,
120 .data = imx290_720p_settings,
121 .data_size = ARRAY_SIZE(imx290_720p_settings),
122 - .pixel_rate = 178200000,
123 - .link_freq_index = 0,
127 static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
129 - /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */
130 if (imx290->nlanes == 2)
131 return imx290_modes_2lanes;
133 @@ -477,6 +496,30 @@ static int imx290_get_fmt(struct v4l2_su
137 +static inline u8 imx290_get_link_freq_index(struct imx290 *imx290)
139 + return imx290->current_mode->link_freq_index;
142 +static s64 imx290_get_link_freq(struct imx290 *imx290)
144 + u8 index = imx290_get_link_freq_index(imx290);
146 + return *(imx290_link_freqs_ptr(imx290) + index);
149 +static u64 imx290_calc_pixel_rate(struct imx290 *imx290)
151 + s64 link_freq = imx290_get_link_freq(imx290);
152 + u8 nlanes = imx290->nlanes;
155 + /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
156 + pixel_rate = link_freq * 2 * nlanes;
157 + do_div(pixel_rate, 10);
161 static int imx290_set_fmt(struct v4l2_subdev *sd,
162 struct v4l2_subdev_pad_config *cfg,
163 struct v4l2_subdev_format *fmt)
164 @@ -509,10 +552,14 @@ static int imx290_set_fmt(struct v4l2_su
165 format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
167 format = &imx290->current_format;
168 - __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
169 - __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate);
171 imx290->current_mode = mode;
173 + if (imx290->link_freq)
174 + __v4l2_ctrl_s_ctrl(imx290->link_freq,
175 + imx290_get_link_freq_index(imx290));
176 + if (imx290->pixel_rate)
177 + __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate,
178 + imx290_calc_pixel_rate(imx290));
181 *format = fmt->format;
182 @@ -536,12 +583,11 @@ static int imx290_entity_init_cfg(struct
186 -static int imx290_write_current_format(struct imx290 *imx290,
187 - struct v4l2_mbus_framefmt *format)
188 +static int imx290_write_current_format(struct imx290 *imx290)
192 - switch (format->code) {
193 + switch (imx290->current_format.code) {
194 case MEDIA_BUS_FMT_SRGGB10_1X10:
195 ret = imx290_set_register_array(imx290, imx290_10bit_settings,
197 @@ -592,8 +638,8 @@ static int imx290_start_streaming(struct
201 - /* Set current frame format */
202 - ret = imx290_write_current_format(imx290, &imx290->current_format);
203 + /* Apply the register values related to current frame format */
204 + ret = imx290_write_current_format(imx290);
206 dev_err(imx290->dev, "Could not set frame format\n");
208 @@ -776,13 +822,34 @@ static const struct media_entity_operati
209 .link_validate = v4l2_subdev_link_validate,
213 + * Returns 0 if all link frequencies used by the driver for the given number
214 + * of MIPI data lanes are mentioned in the device tree, or the value of the
215 + * first missing frequency otherwise.
217 +static s64 imx290_check_link_freqs(const struct imx290 *imx290)
220 + const s64 *freqs = imx290_link_freqs_ptr(imx290);
221 + int freqs_count = imx290_link_freqs_num(imx290);
223 + for (i = 0; i < freqs_count; i++) {
224 + for (j = 0; j < imx290->ep.nr_of_link_frequencies; j++)
225 + if (freqs[i] == imx290->ep.link_frequencies[j])
227 + if (j == imx290->ep.nr_of_link_frequencies)
233 static int imx290_probe(struct i2c_client *client)
235 struct device *dev = &client->dev;
236 struct fwnode_handle *endpoint;
237 struct imx290 *imx290;
239 - u32 default_pixel_rate;
243 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
244 @@ -825,8 +892,10 @@ static int imx290_probe(struct i2c_clien
248 - if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) {
249 - dev_err(dev, "Unsupported link frequency\n");
250 + /* Check that link frequences for all the modes are in device tree */
251 + fq = imx290_check_link_freqs(imx290);
253 + dev_err(dev, "Link frequency of %lld is not supported\n", fq);
257 @@ -883,26 +952,30 @@ static int imx290_probe(struct i2c_clien
259 mutex_init(&imx290->lock);
262 + * Initialize the frame format. In particular, imx290->current_mode
263 + * and imx290->bpp are set to defaults: imx290_calc_pixel_rate() call
264 + * below relies on these fields.
266 + imx290_entity_init_cfg(&imx290->sd, NULL);
268 v4l2_ctrl_handler_init(&imx290->ctrls, 3);
270 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
271 V4L2_CID_GAIN, 0, 72, 1, 0);
274 - v4l2_ctrl_new_int_menu(&imx290->ctrls,
276 + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
278 - ARRAY_SIZE(imx290_link_freq) - 1,
279 - 0, imx290_link_freq);
280 + imx290_link_freqs_num(imx290) - 1, 0,
281 + imx290_link_freqs_ptr(imx290));
282 if (imx290->link_freq)
283 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
285 - default_pixel_rate = imx290->nlanes == 2 ?
286 - imx290_modes_2lanes[0].pixel_rate :
287 - imx290_modes_4lanes[0].pixel_rate;
288 imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
289 - V4L2_CID_PIXEL_RATE, 1,
291 - default_pixel_rate);
292 + V4L2_CID_PIXEL_RATE,
294 + imx290_calc_pixel_rate(imx290));
296 imx290->sd.ctrl_handler = &imx290->ctrls;
298 @@ -926,9 +999,6 @@ static int imx290_probe(struct i2c_clien
302 - /* Initialize the frame format (this also sets imx290->current_mode) */
303 - imx290_entity_init_cfg(&imx290->sd, NULL);
305 ret = v4l2_async_register_subdev(&imx290->sd);
307 dev_err(dev, "Could not register v4l2 device\n");