b4154c9cca85b8e96faad30498e517dcba903001
[openwrt/staging/neocturne.git] /
1 From e97a08baa18802bb3704e1dfda87193417d5fa58 Mon Sep 17 00:00:00 2001
2 From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
3 Date: Thu, 22 Dec 2022 13:59:33 +0000
4 Subject: [PATCH] media/i2c: Add a driver for the Sony IMX708 image
5 sensor
6
7 The imx708 is a 12MP MIPI sensor with a 16:9 aspect ratio, here using
8 two CSI-2 lanes. It is a "quad Bayer" sensor with all 3 modes offering
9 10-bit output:
10
11 12MP: 4608x2592 up to 14.35fps (full FoV)
12 1080p: 2304x1296 up to 56.02fps (full FoV)
13 720p: 1536x864 up to 120.12fps (cropped)
14
15 This imx708 sensor driver is based heavily on the imx477 driver and
16 has been tested on the Raspberry Pi platform using libcamera.
17
18 Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
19 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
20 ---
21 drivers/media/i2c/Kconfig | 13 +
22 drivers/media/i2c/Makefile | 1 +
23 drivers/media/i2c/imx708.c | 1984 ++++++++++++++++++++++++++++++++++++
24 3 files changed, 1998 insertions(+)
25 create mode 100644 drivers/media/i2c/imx708.c
26
27 --- a/drivers/media/i2c/Kconfig
28 +++ b/drivers/media/i2c/Kconfig
29 @@ -268,6 +268,19 @@ config VIDEO_IMX519
30 To compile this driver as a module, choose M here: the
31 module will be called IMX519.
32
33 +config VIDEO_IMX708
34 + tristate "Sony IMX708 sensor support"
35 + depends on I2C && VIDEO_DEV
36 + select MEDIA_CONTROLLER
37 + select VIDEO_V4L2_SUBDEV_API
38 + select V4L2_FWNODE
39 + help
40 + This is a Video4Linux2 sensor driver for the Sony
41 + IMX708 camera.
42 +
43 + To compile this driver as a module, choose M here: the
44 + module will be called imx708.
45 +
46 config VIDEO_MAX9271_LIB
47 tristate
48
49 --- a/drivers/media/i2c/Makefile
50 +++ b/drivers/media/i2c/Makefile
51 @@ -53,6 +53,7 @@ obj-$(CONFIG_VIDEO_IMX355) += imx355.o
52 obj-$(CONFIG_VIDEO_IMX412) += imx412.o
53 obj-$(CONFIG_VIDEO_IMX477) += imx477.o
54 obj-$(CONFIG_VIDEO_IMX519) += imx519.o
55 +obj-$(CONFIG_VIDEO_IMX708) += imx708.o
56 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
57 obj-$(CONFIG_VIDEO_IRS1125) += irs1125.o
58 obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
59 --- /dev/null
60 +++ b/drivers/media/i2c/imx708.c
61 @@ -0,0 +1,1984 @@
62 +// SPDX-License-Identifier: GPL-2.0
63 +/*
64 + * A V4L2 driver for Sony IMX708 cameras.
65 + * Copyright (C) 2022, Raspberry Pi Ltd
66 + *
67 + * Based on Sony imx477 camera driver
68 + * Copyright (C) 2020 Raspberry Pi Ltd
69 + */
70 +#include <asm/unaligned.h>
71 +#include <linux/clk.h>
72 +#include <linux/delay.h>
73 +#include <linux/gpio/consumer.h>
74 +#include <linux/i2c.h>
75 +#include <linux/module.h>
76 +#include <linux/pm_runtime.h>
77 +#include <linux/regulator/consumer.h>
78 +#include <media/v4l2-ctrls.h>
79 +#include <media/v4l2-device.h>
80 +#include <media/v4l2-event.h>
81 +#include <media/v4l2-fwnode.h>
82 +#include <media/v4l2-mediabus.h>
83 +
84 +#define IMX708_REG_VALUE_08BIT 1
85 +#define IMX708_REG_VALUE_16BIT 2
86 +
87 +/* Chip ID */
88 +#define IMX708_REG_CHIP_ID 0x0016
89 +#define IMX708_CHIP_ID 0x0708
90 +
91 +#define IMX708_REG_MODE_SELECT 0x0100
92 +#define IMX708_MODE_STANDBY 0x00
93 +#define IMX708_MODE_STREAMING 0x01
94 +
95 +#define IMX708_REG_ORIENTATION 0x101
96 +
97 +#define IMX708_XCLK_FREQ 24000000
98 +
99 +#define IMX708_DEFAULT_LINK_FREQ 450000000
100 +
101 +/* Default initial pixel rate, will get updated for each mode. */
102 +#define IMX708_INITIAL_PIXEL_RATE 590000000
103 +
104 +/* V_TIMING internal */
105 +#define IMX708_REG_FRAME_LENGTH 0x0340
106 +#define IMX708_FRAME_LENGTH_MAX 0xffff
107 +
108 +/* Exposure control */
109 +#define IMX708_REG_EXPOSURE 0x0202
110 +#define IMX708_EXPOSURE_OFFSET 48
111 +#define IMX708_EXPOSURE_DEFAULT 0x640
112 +#define IMX708_EXPOSURE_STEP 1
113 +#define IMX708_EXPOSURE_MIN 1
114 +#define IMX708_EXPOSURE_MAX (IMX708_FRAME_LENGTH_MAX - \
115 + IMX708_EXPOSURE_OFFSET)
116 +
117 +/* Analog gain control */
118 +#define IMX708_REG_ANALOG_GAIN 0x0204
119 +#define IMX708_ANA_GAIN_MIN 112
120 +#define IMX708_ANA_GAIN_MAX 960
121 +#define IMX708_ANA_GAIN_STEP 1
122 +#define IMX708_ANA_GAIN_DEFAULT IMX708_ANA_GAIN_MIN
123 +
124 +/* Digital gain control */
125 +#define IMX708_REG_DIGITAL_GAIN 0x020e
126 +#define IMX708_DGTL_GAIN_MIN 0x0100
127 +#define IMX708_DGTL_GAIN_MAX 0xffff
128 +#define IMX708_DGTL_GAIN_DEFAULT 0x0100
129 +#define IMX708_DGTL_GAIN_STEP 1
130 +
131 +/* Colour balance controls */
132 +#define IMX708_REG_COLOUR_BALANCE_RED 0x0b90
133 +#define IMX708_REG_COLOUR_BALANCE_BLUE 0x0b92
134 +#define IMX708_COLOUR_BALANCE_MIN 0x01
135 +#define IMX708_COLOUR_BALANCE_MAX 0xffff
136 +#define IMX708_COLOUR_BALANCE_STEP 0x01
137 +#define IMX708_COLOUR_BALANCE_DEFAULT 0x100
138 +
139 +/* Test Pattern Control */
140 +#define IMX708_REG_TEST_PATTERN 0x0600
141 +#define IMX708_TEST_PATTERN_DISABLE 0
142 +#define IMX708_TEST_PATTERN_SOLID_COLOR 1
143 +#define IMX708_TEST_PATTERN_COLOR_BARS 2
144 +#define IMX708_TEST_PATTERN_GREY_COLOR 3
145 +#define IMX708_TEST_PATTERN_PN9 4
146 +
147 +/* Test pattern colour components */
148 +#define IMX708_REG_TEST_PATTERN_R 0x0602
149 +#define IMX708_REG_TEST_PATTERN_GR 0x0604
150 +#define IMX708_REG_TEST_PATTERN_B 0x0606
151 +#define IMX708_REG_TEST_PATTERN_GB 0x0608
152 +#define IMX708_TEST_PATTERN_COLOUR_MIN 0
153 +#define IMX708_TEST_PATTERN_COLOUR_MAX 0x0fff
154 +#define IMX708_TEST_PATTERN_COLOUR_STEP 1
155 +
156 +#define IMX708_REG_BASE_SPC_GAINS_L 0x7b10
157 +#define IMX708_REG_BASE_SPC_GAINS_R 0x7c00
158 +
159 +/* HDR exposure ratio (long:med == med:short) */
160 +#define IMX708_HDR_EXPOSURE_RATIO 4
161 +#define IMX708_REG_MID_EXPOSURE 0x3116
162 +#define IMX708_REG_SHT_EXPOSURE 0x0224
163 +#define IMX708_REG_MID_ANALOG_GAIN 0x3118
164 +#define IMX708_REG_SHT_ANALOG_GAIN 0x0216
165 +
166 +/*
167 + * Metadata buffer holds a variety of data, all sent with the same VC/DT (0x12).
168 + * It comprises two scanlines (of up to 5760 bytes each, for 4608 pixels)
169 + * of embedded data, one line of PDAF data, and two lines of AE-HIST data
170 + * (AE histograms are valid for HDR mode and empty in non-HDR modes).
171 + */
172 +#define IMX708_EMBEDDED_LINE_WIDTH (5 * 5760)
173 +#define IMX708_NUM_EMBEDDED_LINES 1
174 +
175 +enum pad_types {
176 + IMAGE_PAD,
177 + METADATA_PAD,
178 + NUM_PADS
179 +};
180 +
181 +/* IMX708 native and active pixel array size. */
182 +#define IMX708_NATIVE_WIDTH 4640U
183 +#define IMX708_NATIVE_HEIGHT 2658U
184 +#define IMX708_PIXEL_ARRAY_LEFT 16U
185 +#define IMX708_PIXEL_ARRAY_TOP 24U
186 +#define IMX708_PIXEL_ARRAY_WIDTH 4608U
187 +#define IMX708_PIXEL_ARRAY_HEIGHT 2592U
188 +
189 +struct imx708_reg {
190 + u16 address;
191 + u8 val;
192 +};
193 +
194 +struct imx708_reg_list {
195 + unsigned int num_of_regs;
196 + const struct imx708_reg *regs;
197 +};
198 +
199 +/* Mode : resolution and related config&values */
200 +struct imx708_mode {
201 + /* Frame width */
202 + unsigned int width;
203 +
204 + /* Frame height */
205 + unsigned int height;
206 +
207 + /* H-timing in pixels */
208 + unsigned int line_length_pix;
209 +
210 + /* Analog crop rectangle. */
211 + struct v4l2_rect crop;
212 +
213 + /* Highest possible framerate. */
214 + unsigned int vblank_min;
215 +
216 + /* Default framerate. */
217 + unsigned int vblank_default;
218 +
219 + /* Default register values */
220 + struct imx708_reg_list reg_list;
221 +
222 + /* Not all modes have the same pixel rate. */
223 + u64 pixel_rate;
224 +
225 + /* Not all modes have the same minimum exposure. */
226 + u32 exposure_lines_min;
227 +
228 + /* Not all modes have the same exposure lines step. */
229 + u32 exposure_lines_step;
230 +
231 + /* HDR flag, currently not used at runtime */
232 + bool hdr;
233 +};
234 +
235 +/* Default PDAF pixel correction gains */
236 +static const u8 pdaf_gains[2][9] = {
237 + { 0x4c, 0x4c, 0x4c, 0x46, 0x3e, 0x38, 0x35, 0x35, 0x35 },
238 + { 0x35, 0x35, 0x35, 0x38, 0x3e, 0x46, 0x4c, 0x4c, 0x4c }
239 +};
240 +
241 +static const struct imx708_reg mode_common_regs[] = {
242 + {0x0100, 0x00},
243 + {0x0136, 0x18},
244 + {0x0137, 0x00},
245 + {0x33F0, 0x02},
246 + {0x33F1, 0x05},
247 + {0x3062, 0x00},
248 + {0x3063, 0x12},
249 + {0x3068, 0x00},
250 + {0x3069, 0x12},
251 + {0x306A, 0x00},
252 + {0x306B, 0x30},
253 + {0x3076, 0x00},
254 + {0x3077, 0x30},
255 + {0x3078, 0x00},
256 + {0x3079, 0x30},
257 + {0x5E54, 0x0C},
258 + {0x6E44, 0x00},
259 + {0xB0B6, 0x01},
260 + {0xE829, 0x00},
261 + {0xF001, 0x08},
262 + {0xF003, 0x08},
263 + {0xF00D, 0x10},
264 + {0xF00F, 0x10},
265 + {0xF031, 0x08},
266 + {0xF033, 0x08},
267 + {0xF03D, 0x10},
268 + {0xF03F, 0x10},
269 + {0x0112, 0x0A},
270 + {0x0113, 0x0A},
271 + {0x0114, 0x01},
272 + {0x0B8E, 0x01},
273 + {0x0B8F, 0x00},
274 + {0x0B94, 0x01},
275 + {0x0B95, 0x00},
276 + {0x3400, 0x01},
277 + {0x3478, 0x01},
278 + {0x3479, 0x1c},
279 + {0x3091, 0x01},
280 + {0x3092, 0x00},
281 + {0x3419, 0x00},
282 + {0xBCF1, 0x02},
283 + {0x3094, 0x01},
284 + {0x3095, 0x01},
285 + {0x3362, 0x00},
286 + {0x3363, 0x00},
287 + {0x3364, 0x00},
288 + {0x3365, 0x00},
289 + {0x0138, 0x01},
290 +};
291 +
292 +/* 10-bit. */
293 +static const struct imx708_reg mode_4608x2592_regs[] = {
294 + {0x0342, 0x3D},
295 + {0x0343, 0x20},
296 + {0x0340, 0x0A},
297 + {0x0341, 0x59},
298 + {0x0344, 0x00},
299 + {0x0345, 0x00},
300 + {0x0346, 0x00},
301 + {0x0347, 0x00},
302 + {0x0348, 0x11},
303 + {0x0349, 0xFF},
304 + {0x034A, 0X0A},
305 + {0x034B, 0x1F},
306 + {0x0220, 0x62},
307 + {0x0222, 0x01},
308 + {0x0900, 0x00},
309 + {0x0901, 0x11},
310 + {0x0902, 0x0A},
311 + {0x3200, 0x01},
312 + {0x3201, 0x01},
313 + {0x32D5, 0x01},
314 + {0x32D6, 0x00},
315 + {0x32DB, 0x01},
316 + {0x32DF, 0x00},
317 + {0x350C, 0x00},
318 + {0x350D, 0x00},
319 + {0x0408, 0x00},
320 + {0x0409, 0x00},
321 + {0x040A, 0x00},
322 + {0x040B, 0x00},
323 + {0x040C, 0x12},
324 + {0x040D, 0x00},
325 + {0x040E, 0x0A},
326 + {0x040F, 0x20},
327 + {0x034C, 0x12},
328 + {0x034D, 0x00},
329 + {0x034E, 0x0A},
330 + {0x034F, 0x20},
331 + {0x0301, 0x05},
332 + {0x0303, 0x02},
333 + {0x0305, 0x02},
334 + {0x0306, 0x00},
335 + {0x0307, 0x7C},
336 + {0x030B, 0x02},
337 + {0x030D, 0x04},
338 + {0x030E, 0x01},
339 + {0x030F, 0x2C},
340 + {0x0310, 0x01},
341 + {0x3CA0, 0x00},
342 + {0x3CA1, 0x64},
343 + {0x3CA4, 0x00},
344 + {0x3CA5, 0x00},
345 + {0x3CA6, 0x00},
346 + {0x3CA7, 0x00},
347 + {0x3CAA, 0x00},
348 + {0x3CAB, 0x00},
349 + {0x3CB8, 0x00},
350 + {0x3CB9, 0x08},
351 + {0x3CBA, 0x00},
352 + {0x3CBB, 0x00},
353 + {0x3CBC, 0x00},
354 + {0x3CBD, 0x3C},
355 + {0x3CBE, 0x00},
356 + {0x3CBF, 0x00},
357 + {0x0202, 0x0A},
358 + {0x0203, 0x29},
359 + {0x0224, 0x01},
360 + {0x0225, 0xF4},
361 + {0x3116, 0x01},
362 + {0x3117, 0xF4},
363 + {0x0204, 0x00},
364 + {0x0205, 0x00},
365 + {0x0216, 0x00},
366 + {0x0217, 0x00},
367 + {0x0218, 0x01},
368 + {0x0219, 0x00},
369 + {0x020E, 0x01},
370 + {0x020F, 0x00},
371 + {0x3118, 0x00},
372 + {0x3119, 0x00},
373 + {0x311A, 0x01},
374 + {0x311B, 0x00},
375 + {0x341a, 0x00},
376 + {0x341b, 0x00},
377 + {0x341c, 0x00},
378 + {0x341d, 0x00},
379 + {0x341e, 0x01},
380 + {0x341f, 0x20},
381 + {0x3420, 0x00},
382 + {0x3421, 0xd8},
383 + {0xC428, 0x00},
384 + {0xC429, 0x04},
385 + {0x3366, 0x00},
386 + {0x3367, 0x00},
387 + {0x3368, 0x00},
388 + {0x3369, 0x00},
389 +};
390 +
391 +static const struct imx708_reg mode_2x2binned_regs[] = {
392 + {0x0342, 0x1E},
393 + {0x0343, 0x90},
394 + {0x0340, 0x05},
395 + {0x0341, 0x38},
396 + {0x0344, 0x00},
397 + {0x0345, 0x00},
398 + {0x0346, 0x00},
399 + {0x0347, 0x00},
400 + {0x0348, 0x11},
401 + {0x0349, 0xFF},
402 + {0x034A, 0X0A},
403 + {0x034B, 0x1F},
404 + {0x0220, 0x62},
405 + {0x0222, 0x01},
406 + {0x0900, 0x01},
407 + {0x0901, 0x22},
408 + {0x0902, 0x08},
409 + {0x3200, 0x41},
410 + {0x3201, 0x41},
411 + {0x32D5, 0x00},
412 + {0x32D6, 0x00},
413 + {0x32DB, 0x01},
414 + {0x32DF, 0x00},
415 + {0x350C, 0x00},
416 + {0x350D, 0x00},
417 + {0x0408, 0x00},
418 + {0x0409, 0x00},
419 + {0x040A, 0x00},
420 + {0x040B, 0x00},
421 + {0x040C, 0x09},
422 + {0x040D, 0x00},
423 + {0x040E, 0x05},
424 + {0x040F, 0x10},
425 + {0x034C, 0x09},
426 + {0x034D, 0x00},
427 + {0x034E, 0x05},
428 + {0x034F, 0x10},
429 + {0x0301, 0x05},
430 + {0x0303, 0x02},
431 + {0x0305, 0x02},
432 + {0x0306, 0x00},
433 + {0x0307, 0x7A},
434 + {0x030B, 0x02},
435 + {0x030D, 0x04},
436 + {0x030E, 0x01},
437 + {0x030F, 0x2C},
438 + {0x0310, 0x01},
439 + {0x3CA0, 0x00},
440 + {0x3CA1, 0x3C},
441 + {0x3CA4, 0x00},
442 + {0x3CA5, 0x3C},
443 + {0x3CA6, 0x00},
444 + {0x3CA7, 0x00},
445 + {0x3CAA, 0x00},
446 + {0x3CAB, 0x00},
447 + {0x3CB8, 0x00},
448 + {0x3CB9, 0x1C},
449 + {0x3CBA, 0x00},
450 + {0x3CBB, 0x08},
451 + {0x3CBC, 0x00},
452 + {0x3CBD, 0x1E},
453 + {0x3CBE, 0x00},
454 + {0x3CBF, 0x0A},
455 + {0x0202, 0x05},
456 + {0x0203, 0x08},
457 + {0x0224, 0x01},
458 + {0x0225, 0xF4},
459 + {0x3116, 0x01},
460 + {0x3117, 0xF4},
461 + {0x0204, 0x00},
462 + {0x0205, 0x70},
463 + {0x0216, 0x00},
464 + {0x0217, 0x70},
465 + {0x0218, 0x01},
466 + {0x0219, 0x00},
467 + {0x020E, 0x01},
468 + {0x020F, 0x00},
469 + {0x3118, 0x00},
470 + {0x3119, 0x70},
471 + {0x311A, 0x01},
472 + {0x311B, 0x00},
473 + {0x341a, 0x00},
474 + {0x341b, 0x00},
475 + {0x341c, 0x00},
476 + {0x341d, 0x00},
477 + {0x341e, 0x00},
478 + {0x341f, 0x90},
479 + {0x3420, 0x00},
480 + {0x3421, 0x6c},
481 + {0x3366, 0x00},
482 + {0x3367, 0x00},
483 + {0x3368, 0x00},
484 + {0x3369, 0x00},
485 +};
486 +
487 +static const struct imx708_reg mode_2x2binned_720p_regs[] = {
488 + {0x0342, 0x14},
489 + {0x0343, 0x60},
490 + {0x0340, 0x04},
491 + {0x0341, 0xB6},
492 + {0x0344, 0x03},
493 + {0x0345, 0x00},
494 + {0x0346, 0x01},
495 + {0x0347, 0xB0},
496 + {0x0348, 0x0E},
497 + {0x0349, 0xFF},
498 + {0x034A, 0x08},
499 + {0x034B, 0x6F},
500 + {0x0220, 0x62},
501 + {0x0222, 0x01},
502 + {0x0900, 0x01},
503 + {0x0901, 0x22},
504 + {0x0902, 0x08},
505 + {0x3200, 0x41},
506 + {0x3201, 0x41},
507 + {0x32D5, 0x00},
508 + {0x32D6, 0x00},
509 + {0x32DB, 0x01},
510 + {0x32DF, 0x01},
511 + {0x350C, 0x00},
512 + {0x350D, 0x00},
513 + {0x0408, 0x00},
514 + {0x0409, 0x00},
515 + {0x040A, 0x00},
516 + {0x040B, 0x00},
517 + {0x040C, 0x06},
518 + {0x040D, 0x00},
519 + {0x040E, 0x03},
520 + {0x040F, 0x60},
521 + {0x034C, 0x06},
522 + {0x034D, 0x00},
523 + {0x034E, 0x03},
524 + {0x034F, 0x60},
525 + {0x0301, 0x05},
526 + {0x0303, 0x02},
527 + {0x0305, 0x02},
528 + {0x0306, 0x00},
529 + {0x0307, 0x76},
530 + {0x030B, 0x02},
531 + {0x030D, 0x04},
532 + {0x030E, 0x01},
533 + {0x030F, 0x2C},
534 + {0x0310, 0x01},
535 + {0x3CA0, 0x00},
536 + {0x3CA1, 0x3C},
537 + {0x3CA4, 0x01},
538 + {0x3CA5, 0x5E},
539 + {0x3CA6, 0x00},
540 + {0x3CA7, 0x00},
541 + {0x3CAA, 0x00},
542 + {0x3CAB, 0x00},
543 + {0x3CB8, 0x00},
544 + {0x3CB9, 0x0C},
545 + {0x3CBA, 0x00},
546 + {0x3CBB, 0x04},
547 + {0x3CBC, 0x00},
548 + {0x3CBD, 0x1E},
549 + {0x3CBE, 0x00},
550 + {0x3CBF, 0x05},
551 + {0x0202, 0x04},
552 + {0x0203, 0x86},
553 + {0x0224, 0x01},
554 + {0x0225, 0xF4},
555 + {0x3116, 0x01},
556 + {0x3117, 0xF4},
557 + {0x0204, 0x00},
558 + {0x0205, 0x70},
559 + {0x0216, 0x00},
560 + {0x0217, 0x70},
561 + {0x0218, 0x01},
562 + {0x0219, 0x00},
563 + {0x020E, 0x01},
564 + {0x020F, 0x00},
565 + {0x3118, 0x00},
566 + {0x3119, 0x70},
567 + {0x311A, 0x01},
568 + {0x311B, 0x00},
569 + {0x341a, 0x00},
570 + {0x341b, 0x00},
571 + {0x341c, 0x00},
572 + {0x341d, 0x00},
573 + {0x341e, 0x00},
574 + {0x341f, 0x60},
575 + {0x3420, 0x00},
576 + {0x3421, 0x48},
577 + {0x3366, 0x00},
578 + {0x3367, 0x00},
579 + {0x3368, 0x00},
580 + {0x3369, 0x00},
581 +};
582 +
583 +static const struct imx708_reg mode_hdr_regs[] = {
584 + {0x0342, 0x14},
585 + {0x0343, 0x60},
586 + {0x0340, 0x0A},
587 + {0x0341, 0x5B},
588 + {0x0344, 0x00},
589 + {0x0345, 0x00},
590 + {0x0346, 0x00},
591 + {0x0347, 0x00},
592 + {0x0348, 0x11},
593 + {0x0349, 0xFF},
594 + {0x034A, 0X0A},
595 + {0x034B, 0x1F},
596 + {0x0220, 0x01},
597 + {0x0222, IMX708_HDR_EXPOSURE_RATIO},
598 + {0x0900, 0x00},
599 + {0x0901, 0x11},
600 + {0x0902, 0x0A},
601 + {0x3200, 0x01},
602 + {0x3201, 0x01},
603 + {0x32D5, 0x00},
604 + {0x32D6, 0x00},
605 + {0x32DB, 0x01},
606 + {0x32DF, 0x00},
607 + {0x350C, 0x00},
608 + {0x350D, 0x00},
609 + {0x0408, 0x00},
610 + {0x0409, 0x00},
611 + {0x040A, 0x00},
612 + {0x040B, 0x00},
613 + {0x040C, 0x09},
614 + {0x040D, 0x00},
615 + {0x040E, 0x05},
616 + {0x040F, 0x10},
617 + {0x034C, 0x09},
618 + {0x034D, 0x00},
619 + {0x034E, 0x05},
620 + {0x034F, 0x10},
621 + {0x0301, 0x05},
622 + {0x0303, 0x02},
623 + {0x0305, 0x02},
624 + {0x0306, 0x00},
625 + {0x0307, 0xA2},
626 + {0x030B, 0x02},
627 + {0x030D, 0x04},
628 + {0x030E, 0x01},
629 + {0x030F, 0x2C},
630 + {0x0310, 0x01},
631 + {0x3CA0, 0x00},
632 + {0x3CA1, 0x00},
633 + {0x3CA4, 0x00},
634 + {0x3CA5, 0x00},
635 + {0x3CA6, 0x00},
636 + {0x3CA7, 0x28},
637 + {0x3CAA, 0x00},
638 + {0x3CAB, 0x00},
639 + {0x3CB8, 0x00},
640 + {0x3CB9, 0x30},
641 + {0x3CBA, 0x00},
642 + {0x3CBB, 0x00},
643 + {0x3CBC, 0x00},
644 + {0x3CBD, 0x32},
645 + {0x3CBE, 0x00},
646 + {0x3CBF, 0x00},
647 + {0x0202, 0x0A},
648 + {0x0203, 0x2B},
649 + {0x0224, 0x0A},
650 + {0x0225, 0x2B},
651 + {0x3116, 0x0A},
652 + {0x3117, 0x2B},
653 + {0x0204, 0x00},
654 + {0x0205, 0x00},
655 + {0x0216, 0x00},
656 + {0x0217, 0x00},
657 + {0x0218, 0x01},
658 + {0x0219, 0x00},
659 + {0x020E, 0x01},
660 + {0x020F, 0x00},
661 + {0x3118, 0x00},
662 + {0x3119, 0x00},
663 + {0x311A, 0x01},
664 + {0x311B, 0x00},
665 + {0x341a, 0x00},
666 + {0x341b, 0x00},
667 + {0x341c, 0x00},
668 + {0x341d, 0x00},
669 + {0x341e, 0x00},
670 + {0x341f, 0x90},
671 + {0x3420, 0x00},
672 + {0x3421, 0x6c},
673 + {0x3360, 0x01},
674 + {0x3361, 0x01},
675 + {0x3366, 0x09},
676 + {0x3367, 0x00},
677 + {0x3368, 0x05},
678 + {0x3369, 0x10},
679 +};
680 +
681 +/* Mode configs. Keep separate lists for when HDR is enabled or not. */
682 +static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
683 + {
684 + /* Full resolution. */
685 + .width = 4608,
686 + .height = 2592,
687 + .line_length_pix = 0x3d20,
688 + .crop = {
689 + .left = IMX708_PIXEL_ARRAY_LEFT,
690 + .top = IMX708_PIXEL_ARRAY_TOP,
691 + .width = 4608,
692 + .height = 2592,
693 + },
694 + .vblank_min = 58,
695 + .vblank_default = 58,
696 + .reg_list = {
697 + .num_of_regs = ARRAY_SIZE(mode_4608x2592_regs),
698 + .regs = mode_4608x2592_regs,
699 + },
700 + .pixel_rate = 595200000,
701 + .exposure_lines_min = 8,
702 + .exposure_lines_step = 1,
703 + .hdr = false
704 + },
705 + {
706 + /* regular 2x2 binned. */
707 + .width = 2304,
708 + .height = 1296,
709 + .line_length_pix = 0x1e90,
710 + .crop = {
711 + .left = IMX708_PIXEL_ARRAY_LEFT,
712 + .top = IMX708_PIXEL_ARRAY_TOP,
713 + .width = 4608,
714 + .height = 2592,
715 + },
716 + .vblank_min = 40,
717 + .vblank_default = 1198,
718 + .reg_list = {
719 + .num_of_regs = ARRAY_SIZE(mode_2x2binned_regs),
720 + .regs = mode_2x2binned_regs,
721 + },
722 + .pixel_rate = 585600000,
723 + .exposure_lines_min = 4,
724 + .exposure_lines_step = 2,
725 + .hdr = false
726 + },
727 + {
728 + /* 2x2 binned and cropped for 720p. */
729 + .width = 1536,
730 + .height = 864,
731 + .line_length_pix = 0x1460,
732 + .crop = {
733 + .left = IMX708_PIXEL_ARRAY_LEFT,
734 + .top = IMX708_PIXEL_ARRAY_TOP,
735 + .width = 4608,
736 + .height = 2592,
737 + },
738 + .vblank_min = 40,
739 + .vblank_default = 2755,
740 + .reg_list = {
741 + .num_of_regs = ARRAY_SIZE(mode_2x2binned_720p_regs),
742 + .regs = mode_2x2binned_720p_regs,
743 + },
744 + .pixel_rate = 566400000,
745 + .exposure_lines_min = 4,
746 + .exposure_lines_step = 2,
747 + .hdr = false
748 + },
749 +};
750 +
751 +static const struct imx708_mode supported_modes_10bit_hdr[] = {
752 + {
753 + /* There's only one HDR mode, which is 2x2 downscaled */
754 + .width = 2304,
755 + .height = 1296,
756 + .line_length_pix = 0x1460,
757 + .crop = {
758 + .left = IMX708_PIXEL_ARRAY_LEFT,
759 + .top = IMX708_PIXEL_ARRAY_TOP,
760 + .width = 4608,
761 + .height = 2592,
762 + },
763 + .vblank_min = 3673,
764 + .vblank_default = 3673,
765 + .reg_list = {
766 + .num_of_regs = ARRAY_SIZE(mode_hdr_regs),
767 + .regs = mode_hdr_regs,
768 + },
769 + .pixel_rate = 777600000,
770 + .exposure_lines_min = 8 * IMX708_HDR_EXPOSURE_RATIO * IMX708_HDR_EXPOSURE_RATIO,
771 + .exposure_lines_step = 2 * IMX708_HDR_EXPOSURE_RATIO * IMX708_HDR_EXPOSURE_RATIO,
772 + .hdr = true
773 + }
774 +};
775 +
776 +/*
777 + * The supported formats.
778 + * This table MUST contain 4 entries per format, to cover the various flip
779 + * combinations in the order
780 + * - no flip
781 + * - h flip
782 + * - v flip
783 + * - h&v flips
784 + */
785 +static const u32 codes[] = {
786 + /* 10-bit modes. */
787 + MEDIA_BUS_FMT_SRGGB10_1X10,
788 + MEDIA_BUS_FMT_SGRBG10_1X10,
789 + MEDIA_BUS_FMT_SGBRG10_1X10,
790 + MEDIA_BUS_FMT_SBGGR10_1X10,
791 +};
792 +
793 +static const char * const imx708_test_pattern_menu[] = {
794 + "Disabled",
795 + "Color Bars",
796 + "Solid Color",
797 + "Grey Color Bars",
798 + "PN9"
799 +};
800 +
801 +static const int imx708_test_pattern_val[] = {
802 + IMX708_TEST_PATTERN_DISABLE,
803 + IMX708_TEST_PATTERN_COLOR_BARS,
804 + IMX708_TEST_PATTERN_SOLID_COLOR,
805 + IMX708_TEST_PATTERN_GREY_COLOR,
806 + IMX708_TEST_PATTERN_PN9,
807 +};
808 +
809 +/* regulator supplies */
810 +static const char * const imx708_supply_name[] = {
811 + /* Supplies can be enabled in any order */
812 + "VANA1", /* Analog1 (2.8V) supply */
813 + "VANA2", /* Analog2 (1.8V) supply */
814 + "VDIG", /* Digital Core (1.1V) supply */
815 + "VDDL", /* IF (1.8V) supply */
816 +};
817 +
818 +#define IMX708_NUM_SUPPLIES ARRAY_SIZE(imx708_supply_name)
819 +
820 +/*
821 + * Initialisation delay between XCLR low->high and the moment when the sensor
822 + * can start capture (i.e. can leave software standby), given by T7 in the
823 + * datasheet is 8ms. This does include I2C setup time as well.
824 + *
825 + * Note, that delay between XCLR low->high and reading the CCI ID register (T6
826 + * in the datasheet) is much smaller - 600us.
827 + */
828 +#define IMX708_XCLR_MIN_DELAY_US 8000
829 +#define IMX708_XCLR_DELAY_RANGE_US 1000
830 +
831 +struct imx708 {
832 + struct v4l2_subdev sd;
833 + struct media_pad pad[NUM_PADS];
834 +
835 + struct v4l2_mbus_framefmt fmt;
836 +
837 + struct clk *xclk;
838 + u32 xclk_freq;
839 +
840 + struct gpio_desc *reset_gpio;
841 + struct regulator_bulk_data supplies[IMX708_NUM_SUPPLIES];
842 +
843 + struct v4l2_ctrl_handler ctrl_handler;
844 + /* V4L2 Controls */
845 + struct v4l2_ctrl *pixel_rate;
846 + struct v4l2_ctrl *exposure;
847 + struct v4l2_ctrl *vflip;
848 + struct v4l2_ctrl *hflip;
849 + struct v4l2_ctrl *vblank;
850 + struct v4l2_ctrl *hblank;
851 + struct v4l2_ctrl *red_balance;
852 + struct v4l2_ctrl *blue_balance;
853 + struct v4l2_ctrl *notify_gains;
854 + struct v4l2_ctrl *hdr_mode;
855 +
856 + /* Current mode */
857 + const struct imx708_mode *mode;
858 +
859 + /*
860 + * Mutex for serialized access:
861 + * Protect sensor module set pad format and start/stop streaming safely.
862 + */
863 + struct mutex mutex;
864 +
865 + /* Streaming on/off */
866 + bool streaming;
867 +
868 + /* Rewrite common registers on stream on? */
869 + bool common_regs_written;
870 +};
871 +
872 +static inline struct imx708 *to_imx708(struct v4l2_subdev *_sd)
873 +{
874 + return container_of(_sd, struct imx708, sd);
875 +}
876 +
877 +static inline void get_mode_table(unsigned int code,
878 + const struct imx708_mode **mode_list,
879 + unsigned int *num_modes,
880 + bool hdr_enable)
881 +{
882 + switch (code) {
883 + /* 10-bit */
884 + case MEDIA_BUS_FMT_SRGGB10_1X10:
885 + case MEDIA_BUS_FMT_SGRBG10_1X10:
886 + case MEDIA_BUS_FMT_SGBRG10_1X10:
887 + case MEDIA_BUS_FMT_SBGGR10_1X10:
888 + if (hdr_enable) {
889 + *mode_list = supported_modes_10bit_hdr;
890 + *num_modes = ARRAY_SIZE(supported_modes_10bit_hdr);
891 + } else {
892 + *mode_list = supported_modes_10bit_no_hdr;
893 + *num_modes = ARRAY_SIZE(supported_modes_10bit_no_hdr);
894 + }
895 + break;
896 + default:
897 + *mode_list = NULL;
898 + *num_modes = 0;
899 + }
900 +}
901 +
902 +/* Read registers up to 2 at a time */
903 +static int imx708_read_reg(struct imx708 *imx708, u16 reg, u32 len, u32 *val)
904 +{
905 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
906 + struct i2c_msg msgs[2];
907 + u8 addr_buf[2] = { reg >> 8, reg & 0xff };
908 + u8 data_buf[4] = { 0, };
909 + int ret;
910 +
911 + if (len > 4)
912 + return -EINVAL;
913 +
914 + /* Write register address */
915 + msgs[0].addr = client->addr;
916 + msgs[0].flags = 0;
917 + msgs[0].len = ARRAY_SIZE(addr_buf);
918 + msgs[0].buf = addr_buf;
919 +
920 + /* Read data from register */
921 + msgs[1].addr = client->addr;
922 + msgs[1].flags = I2C_M_RD;
923 + msgs[1].len = len;
924 + msgs[1].buf = &data_buf[4 - len];
925 +
926 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
927 + if (ret != ARRAY_SIZE(msgs))
928 + return -EIO;
929 +
930 + *val = get_unaligned_be32(data_buf);
931 +
932 + return 0;
933 +}
934 +
935 +/* Write registers up to 2 at a time */
936 +static int imx708_write_reg(struct imx708 *imx708, u16 reg, u32 len, u32 val)
937 +{
938 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
939 + u8 buf[6];
940 +
941 + if (len > 4)
942 + return -EINVAL;
943 +
944 + put_unaligned_be16(reg, buf);
945 + put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
946 + if (i2c_master_send(client, buf, len + 2) != len + 2)
947 + return -EIO;
948 +
949 + return 0;
950 +}
951 +
952 +/* Write a list of registers */
953 +static int imx708_write_regs(struct imx708 *imx708,
954 + const struct imx708_reg *regs, u32 len)
955 +{
956 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
957 + unsigned int i;
958 + int ret;
959 +
960 + for (i = 0; i < len; i++) {
961 + ret = imx708_write_reg(imx708, regs[i].address, 1, regs[i].val);
962 + if (ret) {
963 + dev_err_ratelimited(&client->dev,
964 + "Failed to write reg 0x%4.4x. error = %d\n",
965 + regs[i].address, ret);
966 +
967 + return ret;
968 + }
969 + }
970 +
971 + return 0;
972 +}
973 +
974 +/* Get bayer order based on flip setting. */
975 +static u32 imx708_get_format_code(struct imx708 *imx708)
976 +{
977 + unsigned int i;
978 +
979 + lockdep_assert_held(&imx708->mutex);
980 +
981 + i = (imx708->vflip->val ? 2 : 0) |
982 + (imx708->hflip->val ? 1 : 0);
983 +
984 + return codes[i];
985 +}
986 +
987 +static void imx708_set_default_format(struct imx708 *imx708)
988 +{
989 + struct v4l2_mbus_framefmt *fmt = &imx708->fmt;
990 +
991 + /* Set default mode to max resolution */
992 + imx708->mode = &supported_modes_10bit_no_hdr[0];
993 +
994 + /* fmt->code not set as it will always be computed based on flips */
995 + fmt->colorspace = V4L2_COLORSPACE_RAW;
996 + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
997 + fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
998 + fmt->colorspace,
999 + fmt->ycbcr_enc);
1000 + fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
1001 + fmt->width = imx708->mode->width;
1002 + fmt->height = imx708->mode->height;
1003 + fmt->field = V4L2_FIELD_NONE;
1004 +}
1005 +
1006 +static int imx708_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1007 +{
1008 + struct imx708 *imx708 = to_imx708(sd);
1009 + struct v4l2_mbus_framefmt *try_fmt_img =
1010 + v4l2_subdev_get_try_format(sd, fh->state, IMAGE_PAD);
1011 + struct v4l2_mbus_framefmt *try_fmt_meta =
1012 + v4l2_subdev_get_try_format(sd, fh->state, METADATA_PAD);
1013 + struct v4l2_rect *try_crop;
1014 +
1015 + mutex_lock(&imx708->mutex);
1016 +
1017 + /* Initialize try_fmt for the image pad */
1018 + if (imx708->hdr_mode->val) {
1019 + try_fmt_img->width = supported_modes_10bit_hdr[0].width;
1020 + try_fmt_img->height = supported_modes_10bit_hdr[0].height;
1021 + } else {
1022 + try_fmt_img->width = supported_modes_10bit_no_hdr[0].width;
1023 + try_fmt_img->height = supported_modes_10bit_no_hdr[0].height;
1024 + }
1025 + try_fmt_img->code = imx708_get_format_code(imx708);
1026 + try_fmt_img->field = V4L2_FIELD_NONE;
1027 +
1028 + /* Initialize try_fmt for the embedded metadata pad */
1029 + try_fmt_meta->width = IMX708_EMBEDDED_LINE_WIDTH;
1030 + try_fmt_meta->height = IMX708_NUM_EMBEDDED_LINES;
1031 + try_fmt_meta->code = MEDIA_BUS_FMT_SENSOR_DATA;
1032 + try_fmt_meta->field = V4L2_FIELD_NONE;
1033 +
1034 + /* Initialize try_crop */
1035 + try_crop = v4l2_subdev_get_try_crop(sd, fh->state, IMAGE_PAD);
1036 + try_crop->left = IMX708_PIXEL_ARRAY_LEFT;
1037 + try_crop->top = IMX708_PIXEL_ARRAY_TOP;
1038 + try_crop->width = IMX708_PIXEL_ARRAY_WIDTH;
1039 + try_crop->height = IMX708_PIXEL_ARRAY_HEIGHT;
1040 +
1041 + mutex_unlock(&imx708->mutex);
1042 +
1043 + return 0;
1044 +}
1045 +
1046 +static int imx708_set_exposure(struct imx708 *imx708, unsigned int val)
1047 +{
1048 + int ret;
1049 +
1050 + val = max(val, imx708->mode->exposure_lines_min);
1051 + val -= val % imx708->mode->exposure_lines_step;
1052 +
1053 + /*
1054 + * In HDR mode this will set the longest exposure. The sensor
1055 + * will automatically divide the medium and short ones by 4,16.
1056 + */
1057 + ret = imx708_write_reg(imx708, IMX708_REG_EXPOSURE,
1058 + IMX708_REG_VALUE_16BIT, val);
1059 +
1060 + return ret;
1061 +}
1062 +
1063 +static void imx708_adjust_exposure_range(struct imx708 *imx708,
1064 + struct v4l2_ctrl *ctrl)
1065 +{
1066 + int exposure_max, exposure_def;
1067 +
1068 + /* Honour the VBLANK limits when setting exposure. */
1069 + exposure_max = imx708->mode->height + imx708->vblank->val -
1070 + IMX708_EXPOSURE_OFFSET;
1071 + exposure_def = min(exposure_max, imx708->exposure->val);
1072 + __v4l2_ctrl_modify_range(imx708->exposure, imx708->exposure->minimum,
1073 + exposure_max, imx708->exposure->step,
1074 + exposure_def);
1075 +}
1076 +
1077 +static int imx708_set_analogue_gain(struct imx708 *imx708, unsigned int val)
1078 +{
1079 + int ret;
1080 +
1081 + /*
1082 + * In HDR mode this will set the gain for the longest exposure,
1083 + * and by default the sensor uses the same gain for all of them.
1084 + */
1085 + ret = imx708_write_reg(imx708, IMX708_REG_ANALOG_GAIN,
1086 + IMX708_REG_VALUE_16BIT, val);
1087 +
1088 + return ret;
1089 +}
1090 +
1091 +static void imx708_set_framing_limits(struct imx708 *imx708)
1092 +{
1093 + unsigned int hblank;
1094 + const struct imx708_mode *mode = imx708->mode;
1095 +
1096 + __v4l2_ctrl_modify_range(imx708->pixel_rate,
1097 + mode->pixel_rate, mode->pixel_rate,
1098 + 1, mode->pixel_rate);
1099 +
1100 + /* Update limits and set FPS to default */
1101 + __v4l2_ctrl_modify_range(imx708->vblank, mode->vblank_min,
1102 + IMX708_FRAME_LENGTH_MAX - mode->height,
1103 + 1, mode->vblank_default);
1104 +
1105 + /*
1106 + * Currently PPL is fixed to the mode specified value, so hblank
1107 + * depends on mode->width only, and is not changeable in any
1108 + * way other than changing the mode.
1109 + */
1110 + hblank = mode->line_length_pix - mode->width;
1111 + __v4l2_ctrl_modify_range(imx708->hblank, hblank, hblank, 1, hblank);
1112 +}
1113 +
1114 +static int imx708_set_ctrl(struct v4l2_ctrl *ctrl)
1115 +{
1116 + struct imx708 *imx708 =
1117 + container_of(ctrl->handler, struct imx708, ctrl_handler);
1118 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1119 + const struct imx708_mode *mode_list;
1120 + unsigned int code, num_modes;
1121 + int ret = 0;
1122 +
1123 + /*
1124 + * The VBLANK control may change the limits of usable exposure, so check
1125 + * and adjust if necessary.
1126 + */
1127 + if (ctrl->id == V4L2_CID_VBLANK)
1128 + imx708_adjust_exposure_range(imx708, ctrl);
1129 +
1130 + /*
1131 + * Applying V4L2 control value only happens
1132 + * when power is up for streaming
1133 + */
1134 + if (pm_runtime_get_if_in_use(&client->dev) == 0)
1135 + return 0;
1136 +
1137 + switch (ctrl->id) {
1138 + case V4L2_CID_ANALOGUE_GAIN:
1139 + imx708_set_analogue_gain(imx708, ctrl->val);
1140 + break;
1141 + case V4L2_CID_EXPOSURE:
1142 + ret = imx708_set_exposure(imx708, ctrl->val);
1143 + break;
1144 + case V4L2_CID_DIGITAL_GAIN:
1145 + ret = imx708_write_reg(imx708, IMX708_REG_DIGITAL_GAIN,
1146 + IMX708_REG_VALUE_16BIT, ctrl->val);
1147 + break;
1148 + case V4L2_CID_TEST_PATTERN:
1149 + ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN,
1150 + IMX708_REG_VALUE_16BIT,
1151 + imx708_test_pattern_val[ctrl->val]);
1152 + break;
1153 + case V4L2_CID_TEST_PATTERN_RED:
1154 + ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_R,
1155 + IMX708_REG_VALUE_16BIT, ctrl->val);
1156 + break;
1157 + case V4L2_CID_TEST_PATTERN_GREENR:
1158 + ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GR,
1159 + IMX708_REG_VALUE_16BIT, ctrl->val);
1160 + break;
1161 + case V4L2_CID_TEST_PATTERN_BLUE:
1162 + ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_B,
1163 + IMX708_REG_VALUE_16BIT, ctrl->val);
1164 + break;
1165 + case V4L2_CID_TEST_PATTERN_GREENB:
1166 + ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GB,
1167 + IMX708_REG_VALUE_16BIT, ctrl->val);
1168 + break;
1169 + case V4L2_CID_HFLIP:
1170 + case V4L2_CID_VFLIP:
1171 + ret = imx708_write_reg(imx708, IMX708_REG_ORIENTATION, 1,
1172 + imx708->hflip->val |
1173 + imx708->vflip->val << 1);
1174 + break;
1175 + case V4L2_CID_VBLANK:
1176 + ret = imx708_write_reg(imx708, IMX708_REG_FRAME_LENGTH,
1177 + IMX708_REG_VALUE_16BIT,
1178 + imx708->mode->height + ctrl->val);
1179 + break;
1180 + case V4L2_CID_NOTIFY_GAINS:
1181 + ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_BLUE,
1182 + IMX708_REG_VALUE_16BIT,
1183 + imx708->notify_gains->p_new.p_u32[0]);
1184 + if (ret)
1185 + break;
1186 + ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_RED,
1187 + IMX708_REG_VALUE_16BIT,
1188 + imx708->notify_gains->p_new.p_u32[3]);
1189 + break;
1190 + case V4L2_CID_WIDE_DYNAMIC_RANGE:
1191 + code = imx708_get_format_code(imx708);
1192 + get_mode_table(code, &mode_list, &num_modes, ctrl->val);
1193 + imx708->mode = v4l2_find_nearest_size(mode_list,
1194 + num_modes,
1195 + width, height,
1196 + imx708->mode->width,
1197 + imx708->mode->height);
1198 + imx708_set_framing_limits(imx708);
1199 + break;
1200 + default:
1201 + dev_info(&client->dev,
1202 + "ctrl(id:0x%x,val:0x%x) is not handled\n",
1203 + ctrl->id, ctrl->val);
1204 + ret = -EINVAL;
1205 + break;
1206 + }
1207 +
1208 + pm_runtime_put(&client->dev);
1209 +
1210 + return ret;
1211 +}
1212 +
1213 +static const struct v4l2_ctrl_ops imx708_ctrl_ops = {
1214 + .s_ctrl = imx708_set_ctrl,
1215 +};
1216 +
1217 +static int imx708_enum_mbus_code(struct v4l2_subdev *sd,
1218 + struct v4l2_subdev_state *sd_state,
1219 + struct v4l2_subdev_mbus_code_enum *code)
1220 +{
1221 + struct imx708 *imx708 = to_imx708(sd);
1222 +
1223 + if (code->pad >= NUM_PADS)
1224 + return -EINVAL;
1225 +
1226 + if (code->pad == IMAGE_PAD) {
1227 + if (code->index >= (ARRAY_SIZE(codes) / 4))
1228 + return -EINVAL;
1229 +
1230 + code->code = imx708_get_format_code(imx708);
1231 + } else {
1232 + if (code->index > 0)
1233 + return -EINVAL;
1234 +
1235 + code->code = MEDIA_BUS_FMT_SENSOR_DATA;
1236 + }
1237 +
1238 + return 0;
1239 +}
1240 +
1241 +static int imx708_enum_frame_size(struct v4l2_subdev *sd,
1242 + struct v4l2_subdev_state *sd_state,
1243 + struct v4l2_subdev_frame_size_enum *fse)
1244 +{
1245 + struct imx708 *imx708 = to_imx708(sd);
1246 +
1247 + if (fse->pad >= NUM_PADS)
1248 + return -EINVAL;
1249 +
1250 + if (fse->pad == IMAGE_PAD) {
1251 + const struct imx708_mode *mode_list;
1252 + unsigned int num_modes;
1253 +
1254 + get_mode_table(fse->code, &mode_list, &num_modes,
1255 + imx708->hdr_mode->val);
1256 +
1257 + if (fse->index >= num_modes)
1258 + return -EINVAL;
1259 +
1260 + if (fse->code != imx708_get_format_code(imx708))
1261 + return -EINVAL;
1262 +
1263 + fse->min_width = mode_list[fse->index].width;
1264 + fse->max_width = fse->min_width;
1265 + fse->min_height = mode_list[fse->index].height;
1266 + fse->max_height = fse->min_height;
1267 + } else {
1268 + if (fse->code != MEDIA_BUS_FMT_SENSOR_DATA || fse->index > 0)
1269 + return -EINVAL;
1270 +
1271 + fse->min_width = IMX708_EMBEDDED_LINE_WIDTH;
1272 + fse->max_width = fse->min_width;
1273 + fse->min_height = IMX708_NUM_EMBEDDED_LINES;
1274 + fse->max_height = fse->min_height;
1275 + }
1276 +
1277 + return 0;
1278 +}
1279 +
1280 +static void imx708_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
1281 +{
1282 + fmt->colorspace = V4L2_COLORSPACE_RAW;
1283 + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
1284 + fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
1285 + fmt->colorspace,
1286 + fmt->ycbcr_enc);
1287 + fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
1288 +}
1289 +
1290 +static void imx708_update_image_pad_format(struct imx708 *imx708,
1291 + const struct imx708_mode *mode,
1292 + struct v4l2_subdev_format *fmt)
1293 +{
1294 + fmt->format.width = mode->width;
1295 + fmt->format.height = mode->height;
1296 + fmt->format.field = V4L2_FIELD_NONE;
1297 + imx708_reset_colorspace(&fmt->format);
1298 +}
1299 +
1300 +static void imx708_update_metadata_pad_format(struct v4l2_subdev_format *fmt)
1301 +{
1302 + fmt->format.width = IMX708_EMBEDDED_LINE_WIDTH;
1303 + fmt->format.height = IMX708_NUM_EMBEDDED_LINES;
1304 + fmt->format.code = MEDIA_BUS_FMT_SENSOR_DATA;
1305 + fmt->format.field = V4L2_FIELD_NONE;
1306 +}
1307 +
1308 +static int imx708_get_pad_format(struct v4l2_subdev *sd,
1309 + struct v4l2_subdev_state *sd_state,
1310 + struct v4l2_subdev_format *fmt)
1311 +{
1312 + struct imx708 *imx708 = to_imx708(sd);
1313 +
1314 + if (fmt->pad >= NUM_PADS)
1315 + return -EINVAL;
1316 +
1317 + mutex_lock(&imx708->mutex);
1318 +
1319 + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1320 + struct v4l2_mbus_framefmt *try_fmt =
1321 + v4l2_subdev_get_try_format(&imx708->sd, sd_state,
1322 + fmt->pad);
1323 + /* update the code which could change due to vflip or hflip */
1324 + try_fmt->code = fmt->pad == IMAGE_PAD ?
1325 + imx708_get_format_code(imx708) :
1326 + MEDIA_BUS_FMT_SENSOR_DATA;
1327 + fmt->format = *try_fmt;
1328 + } else {
1329 + if (fmt->pad == IMAGE_PAD) {
1330 + imx708_update_image_pad_format(imx708, imx708->mode,
1331 + fmt);
1332 + fmt->format.code = imx708_get_format_code(imx708);
1333 + } else {
1334 + imx708_update_metadata_pad_format(fmt);
1335 + }
1336 + }
1337 +
1338 + mutex_unlock(&imx708->mutex);
1339 + return 0;
1340 +}
1341 +
1342 +static int imx708_set_pad_format(struct v4l2_subdev *sd,
1343 + struct v4l2_subdev_state *sd_state,
1344 + struct v4l2_subdev_format *fmt)
1345 +{
1346 + struct v4l2_mbus_framefmt *framefmt;
1347 + const struct imx708_mode *mode;
1348 + struct imx708 *imx708 = to_imx708(sd);
1349 +
1350 + if (fmt->pad >= NUM_PADS)
1351 + return -EINVAL;
1352 +
1353 + mutex_lock(&imx708->mutex);
1354 +
1355 + if (fmt->pad == IMAGE_PAD) {
1356 + const struct imx708_mode *mode_list;
1357 + unsigned int num_modes;
1358 +
1359 + /* Bayer order varies with flips */
1360 + fmt->format.code = imx708_get_format_code(imx708);
1361 +
1362 + get_mode_table(fmt->format.code, &mode_list, &num_modes,
1363 + imx708->hdr_mode->val);
1364 +
1365 + mode = v4l2_find_nearest_size(mode_list,
1366 + num_modes,
1367 + width, height,
1368 + fmt->format.width,
1369 + fmt->format.height);
1370 + imx708_update_image_pad_format(imx708, mode, fmt);
1371 + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1372 + framefmt = v4l2_subdev_get_try_format(sd, sd_state,
1373 + fmt->pad);
1374 + *framefmt = fmt->format;
1375 + } else {
1376 + imx708->mode = mode;
1377 + imx708_set_framing_limits(imx708);
1378 + }
1379 + } else {
1380 + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1381 + framefmt = v4l2_subdev_get_try_format(sd, sd_state,
1382 + fmt->pad);
1383 + *framefmt = fmt->format;
1384 + } else {
1385 + /* Only one embedded data mode is supported */
1386 + imx708_update_metadata_pad_format(fmt);
1387 + }
1388 + }
1389 +
1390 + mutex_unlock(&imx708->mutex);
1391 +
1392 + return 0;
1393 +}
1394 +
1395 +static const struct v4l2_rect *
1396 +__imx708_get_pad_crop(struct imx708 *imx708, struct v4l2_subdev_state *sd_state,
1397 + unsigned int pad, enum v4l2_subdev_format_whence which)
1398 +{
1399 + switch (which) {
1400 + case V4L2_SUBDEV_FORMAT_TRY:
1401 + return v4l2_subdev_get_try_crop(&imx708->sd, sd_state, pad);
1402 + case V4L2_SUBDEV_FORMAT_ACTIVE:
1403 + return &imx708->mode->crop;
1404 + }
1405 +
1406 + return NULL;
1407 +}
1408 +
1409 +static int imx708_get_selection(struct v4l2_subdev *sd,
1410 + struct v4l2_subdev_state *sd_state,
1411 + struct v4l2_subdev_selection *sel)
1412 +{
1413 + switch (sel->target) {
1414 + case V4L2_SEL_TGT_CROP: {
1415 + struct imx708 *imx708 = to_imx708(sd);
1416 +
1417 + mutex_lock(&imx708->mutex);
1418 + sel->r = *__imx708_get_pad_crop(imx708, sd_state, sel->pad,
1419 + sel->which);
1420 + mutex_unlock(&imx708->mutex);
1421 +
1422 + return 0;
1423 + }
1424 +
1425 + case V4L2_SEL_TGT_NATIVE_SIZE:
1426 + sel->r.left = 0;
1427 + sel->r.top = 0;
1428 + sel->r.width = IMX708_NATIVE_WIDTH;
1429 + sel->r.height = IMX708_NATIVE_HEIGHT;
1430 +
1431 + return 0;
1432 +
1433 + case V4L2_SEL_TGT_CROP_DEFAULT:
1434 + case V4L2_SEL_TGT_CROP_BOUNDS:
1435 + sel->r.left = IMX708_PIXEL_ARRAY_LEFT;
1436 + sel->r.top = IMX708_PIXEL_ARRAY_TOP;
1437 + sel->r.width = IMX708_PIXEL_ARRAY_WIDTH;
1438 + sel->r.height = IMX708_PIXEL_ARRAY_HEIGHT;
1439 +
1440 + return 0;
1441 + }
1442 +
1443 + return -EINVAL;
1444 +}
1445 +
1446 +/* Start streaming */
1447 +static int imx708_start_streaming(struct imx708 *imx708)
1448 +{
1449 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1450 + const struct imx708_reg_list *reg_list;
1451 + int i, ret;
1452 + u32 val;
1453 +
1454 + if (!imx708->common_regs_written) {
1455 + ret = imx708_write_regs(imx708, mode_common_regs,
1456 + ARRAY_SIZE(mode_common_regs));
1457 + if (ret) {
1458 + dev_err(&client->dev, "%s failed to set common settings\n",
1459 + __func__);
1460 + return ret;
1461 + }
1462 +
1463 + ret = imx708_read_reg(imx708, IMX708_REG_BASE_SPC_GAINS_L,
1464 + IMX708_REG_VALUE_08BIT, &val);
1465 + if (ret == 0 && val == 0x40) {
1466 + for (i = 0; i < 54 && ret == 0; i++) {
1467 + ret = imx708_write_reg(imx708,
1468 + IMX708_REG_BASE_SPC_GAINS_L + i,
1469 + IMX708_REG_VALUE_08BIT,
1470 + pdaf_gains[0][i % 9]);
1471 + }
1472 + for (i = 0; i < 54 && ret == 0; i++) {
1473 + ret = imx708_write_reg(imx708,
1474 + IMX708_REG_BASE_SPC_GAINS_R + i,
1475 + IMX708_REG_VALUE_08BIT,
1476 + pdaf_gains[1][i % 9]);
1477 + }
1478 + }
1479 + if (ret) {
1480 + dev_err(&client->dev, "%s failed to set PDAF gains\n",
1481 + __func__);
1482 + return ret;
1483 + }
1484 +
1485 + imx708->common_regs_written = true;
1486 + }
1487 +
1488 + /* Apply default values of current mode */
1489 + reg_list = &imx708->mode->reg_list;
1490 + ret = imx708_write_regs(imx708, reg_list->regs, reg_list->num_of_regs);
1491 + if (ret) {
1492 + dev_err(&client->dev, "%s failed to set mode\n", __func__);
1493 + return ret;
1494 + }
1495 +
1496 + /* Apply customized values from user */
1497 + ret = __v4l2_ctrl_handler_setup(imx708->sd.ctrl_handler);
1498 + if (ret)
1499 + return ret;
1500 +
1501 + /* set stream on register */
1502 + return imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
1503 + IMX708_REG_VALUE_08BIT, IMX708_MODE_STREAMING);
1504 +}
1505 +
1506 +/* Stop streaming */
1507 +static void imx708_stop_streaming(struct imx708 *imx708)
1508 +{
1509 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1510 + int ret;
1511 +
1512 + /* set stream off register */
1513 + ret = imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
1514 + IMX708_REG_VALUE_08BIT, IMX708_MODE_STANDBY);
1515 + if (ret)
1516 + dev_err(&client->dev, "%s failed to set stream\n", __func__);
1517 +}
1518 +
1519 +static int imx708_set_stream(struct v4l2_subdev *sd, int enable)
1520 +{
1521 + struct imx708 *imx708 = to_imx708(sd);
1522 + struct i2c_client *client = v4l2_get_subdevdata(sd);
1523 + int ret = 0;
1524 +
1525 + mutex_lock(&imx708->mutex);
1526 + if (imx708->streaming == enable) {
1527 + mutex_unlock(&imx708->mutex);
1528 + return 0;
1529 + }
1530 +
1531 + if (enable) {
1532 + ret = pm_runtime_get_sync(&client->dev);
1533 + if (ret < 0) {
1534 + pm_runtime_put_noidle(&client->dev);
1535 + goto err_unlock;
1536 + }
1537 +
1538 + /*
1539 + * Apply default & customized values
1540 + * and then start streaming.
1541 + */
1542 + ret = imx708_start_streaming(imx708);
1543 + if (ret)
1544 + goto err_rpm_put;
1545 + } else {
1546 + imx708_stop_streaming(imx708);
1547 + pm_runtime_put(&client->dev);
1548 + }
1549 +
1550 + imx708->streaming = enable;
1551 +
1552 + /* vflip/hflip and hdr mode cannot change during streaming */
1553 + __v4l2_ctrl_grab(imx708->vflip, enable);
1554 + __v4l2_ctrl_grab(imx708->hflip, enable);
1555 + __v4l2_ctrl_grab(imx708->hdr_mode, enable);
1556 +
1557 + mutex_unlock(&imx708->mutex);
1558 +
1559 + return ret;
1560 +
1561 +err_rpm_put:
1562 + pm_runtime_put(&client->dev);
1563 +err_unlock:
1564 + mutex_unlock(&imx708->mutex);
1565 +
1566 + return ret;
1567 +}
1568 +
1569 +/* Power/clock management functions */
1570 +static int imx708_power_on(struct device *dev)
1571 +{
1572 + struct i2c_client *client = to_i2c_client(dev);
1573 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
1574 + struct imx708 *imx708 = to_imx708(sd);
1575 + int ret;
1576 +
1577 + ret = regulator_bulk_enable(IMX708_NUM_SUPPLIES,
1578 + imx708->supplies);
1579 + if (ret) {
1580 + dev_err(&client->dev, "%s: failed to enable regulators\n",
1581 + __func__);
1582 + return ret;
1583 + }
1584 +
1585 + ret = clk_prepare_enable(imx708->xclk);
1586 + if (ret) {
1587 + dev_err(&client->dev, "%s: failed to enable clock\n",
1588 + __func__);
1589 + goto reg_off;
1590 + }
1591 +
1592 + gpiod_set_value_cansleep(imx708->reset_gpio, 1);
1593 + usleep_range(IMX708_XCLR_MIN_DELAY_US,
1594 + IMX708_XCLR_MIN_DELAY_US + IMX708_XCLR_DELAY_RANGE_US);
1595 +
1596 + return 0;
1597 +
1598 +reg_off:
1599 + regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
1600 + return ret;
1601 +}
1602 +
1603 +static int imx708_power_off(struct device *dev)
1604 +{
1605 + struct i2c_client *client = to_i2c_client(dev);
1606 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
1607 + struct imx708 *imx708 = to_imx708(sd);
1608 +
1609 + gpiod_set_value_cansleep(imx708->reset_gpio, 0);
1610 + regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
1611 + clk_disable_unprepare(imx708->xclk);
1612 +
1613 + /* Force reprogramming of the common registers when powered up again. */
1614 + imx708->common_regs_written = false;
1615 +
1616 + return 0;
1617 +}
1618 +
1619 +static int __maybe_unused imx708_suspend(struct device *dev)
1620 +{
1621 + struct i2c_client *client = to_i2c_client(dev);
1622 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
1623 + struct imx708 *imx708 = to_imx708(sd);
1624 +
1625 + if (imx708->streaming)
1626 + imx708_stop_streaming(imx708);
1627 +
1628 + return 0;
1629 +}
1630 +
1631 +static int __maybe_unused imx708_resume(struct device *dev)
1632 +{
1633 + struct i2c_client *client = to_i2c_client(dev);
1634 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
1635 + struct imx708 *imx708 = to_imx708(sd);
1636 + int ret;
1637 +
1638 + if (imx708->streaming) {
1639 + ret = imx708_start_streaming(imx708);
1640 + if (ret)
1641 + goto error;
1642 + }
1643 +
1644 + return 0;
1645 +
1646 +error:
1647 + imx708_stop_streaming(imx708);
1648 + imx708->streaming = 0;
1649 + return ret;
1650 +}
1651 +
1652 +static int imx708_get_regulators(struct imx708 *imx708)
1653 +{
1654 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1655 + unsigned int i;
1656 +
1657 + for (i = 0; i < IMX708_NUM_SUPPLIES; i++)
1658 + imx708->supplies[i].supply = imx708_supply_name[i];
1659 +
1660 + return devm_regulator_bulk_get(&client->dev,
1661 + IMX708_NUM_SUPPLIES,
1662 + imx708->supplies);
1663 +}
1664 +
1665 +/* Verify chip ID */
1666 +static int imx708_identify_module(struct imx708 *imx708)
1667 +{
1668 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1669 + int ret;
1670 + u32 val;
1671 +
1672 + ret = imx708_read_reg(imx708, IMX708_REG_CHIP_ID,
1673 + IMX708_REG_VALUE_16BIT, &val);
1674 + if (ret) {
1675 + dev_err(&client->dev, "failed to read chip id %x, with error %d\n",
1676 + IMX708_CHIP_ID, ret);
1677 + return ret;
1678 + }
1679 +
1680 + if (val != IMX708_CHIP_ID) {
1681 + dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1682 + IMX708_CHIP_ID, val);
1683 + return -EIO;
1684 + }
1685 +
1686 + ret = imx708_read_reg(imx708, 0x0000, IMX708_REG_VALUE_16BIT, &val);
1687 + if (!ret) {
1688 + dev_info(&client->dev, "camera module ID 0x%04x\n", val);
1689 + snprintf(imx708->sd.name, sizeof(imx708->sd.name), "imx708%s%s",
1690 + val & 0x02 ? "_wide" : "",
1691 + val & 0x80 ? "_noir" : "");
1692 + }
1693 +
1694 + return 0;
1695 +}
1696 +
1697 +static const struct v4l2_subdev_core_ops imx708_core_ops = {
1698 + .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1699 + .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1700 +};
1701 +
1702 +static const struct v4l2_subdev_video_ops imx708_video_ops = {
1703 + .s_stream = imx708_set_stream,
1704 +};
1705 +
1706 +static const struct v4l2_subdev_pad_ops imx708_pad_ops = {
1707 + .enum_mbus_code = imx708_enum_mbus_code,
1708 + .get_fmt = imx708_get_pad_format,
1709 + .set_fmt = imx708_set_pad_format,
1710 + .get_selection = imx708_get_selection,
1711 + .enum_frame_size = imx708_enum_frame_size,
1712 +};
1713 +
1714 +static const struct v4l2_subdev_ops imx708_subdev_ops = {
1715 + .core = &imx708_core_ops,
1716 + .video = &imx708_video_ops,
1717 + .pad = &imx708_pad_ops,
1718 +};
1719 +
1720 +static const struct v4l2_subdev_internal_ops imx708_internal_ops = {
1721 + .open = imx708_open,
1722 +};
1723 +
1724 +static const struct v4l2_ctrl_config imx708_notify_gains_ctrl = {
1725 + .ops = &imx708_ctrl_ops,
1726 + .id = V4L2_CID_NOTIFY_GAINS,
1727 + .type = V4L2_CTRL_TYPE_U32,
1728 + .min = IMX708_COLOUR_BALANCE_MIN,
1729 + .max = IMX708_COLOUR_BALANCE_MAX,
1730 + .step = IMX708_COLOUR_BALANCE_STEP,
1731 + .def = IMX708_COLOUR_BALANCE_DEFAULT,
1732 + .dims = { 4 },
1733 + .elem_size = sizeof(u32),
1734 +};
1735 +
1736 +/* Initialize control handlers */
1737 +static int imx708_init_controls(struct imx708 *imx708)
1738 +{
1739 + struct v4l2_ctrl_handler *ctrl_hdlr;
1740 + struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
1741 + struct v4l2_fwnode_device_properties props;
1742 + unsigned int i;
1743 + int ret;
1744 +
1745 + ctrl_hdlr = &imx708->ctrl_handler;
1746 + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
1747 + if (ret)
1748 + return ret;
1749 +
1750 + mutex_init(&imx708->mutex);
1751 + ctrl_hdlr->lock = &imx708->mutex;
1752 +
1753 + /* By default, PIXEL_RATE is read only */
1754 + imx708->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1755 + V4L2_CID_PIXEL_RATE,
1756 + IMX708_INITIAL_PIXEL_RATE,
1757 + IMX708_INITIAL_PIXEL_RATE, 1,
1758 + IMX708_INITIAL_PIXEL_RATE);
1759 +
1760 + /*
1761 + * Create the controls here, but mode specific limits are setup
1762 + * in the imx708_set_framing_limits() call below.
1763 + */
1764 + imx708->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1765 + V4L2_CID_VBLANK, 0, 0xffff, 1, 0);
1766 + imx708->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1767 + V4L2_CID_HBLANK, 0, 0xffff, 1, 0);
1768 +
1769 + imx708->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1770 + V4L2_CID_EXPOSURE,
1771 + IMX708_EXPOSURE_MIN,
1772 + IMX708_EXPOSURE_MAX,
1773 + IMX708_EXPOSURE_STEP,
1774 + IMX708_EXPOSURE_DEFAULT);
1775 +
1776 + v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1777 + IMX708_ANA_GAIN_MIN, IMX708_ANA_GAIN_MAX,
1778 + IMX708_ANA_GAIN_STEP, IMX708_ANA_GAIN_DEFAULT);
1779 +
1780 + v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1781 + IMX708_DGTL_GAIN_MIN, IMX708_DGTL_GAIN_MAX,
1782 + IMX708_DGTL_GAIN_STEP, IMX708_DGTL_GAIN_DEFAULT);
1783 +
1784 + imx708->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1785 + V4L2_CID_HFLIP, 0, 1, 1, 0);
1786 +
1787 + imx708->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1788 + V4L2_CID_VFLIP, 0, 1, 1, 0);
1789 +
1790 + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx708_ctrl_ops,
1791 + V4L2_CID_TEST_PATTERN,
1792 + ARRAY_SIZE(imx708_test_pattern_menu) - 1,
1793 + 0, 0, imx708_test_pattern_menu);
1794 + for (i = 0; i < 4; i++) {
1795 + /*
1796 + * The assumption is that
1797 + * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
1798 + * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
1799 + * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
1800 + */
1801 + v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1802 + V4L2_CID_TEST_PATTERN_RED + i,
1803 + IMX708_TEST_PATTERN_COLOUR_MIN,
1804 + IMX708_TEST_PATTERN_COLOUR_MAX,
1805 + IMX708_TEST_PATTERN_COLOUR_STEP,
1806 + IMX708_TEST_PATTERN_COLOUR_MAX);
1807 + /* The "Solid color" pattern is white by default */
1808 + }
1809 +
1810 + imx708->notify_gains = v4l2_ctrl_new_custom(ctrl_hdlr,
1811 + &imx708_notify_gains_ctrl, NULL);
1812 +
1813 + imx708->hdr_mode = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
1814 + V4L2_CID_WIDE_DYNAMIC_RANGE,
1815 + 0, 1, 1, 0);
1816 +
1817 + ret = v4l2_fwnode_device_parse(&client->dev, &props);
1818 + if (ret)
1819 + goto error;
1820 +
1821 + v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx708_ctrl_ops, &props);
1822 +
1823 + if (ctrl_hdlr->error) {
1824 + ret = ctrl_hdlr->error;
1825 + dev_err(&client->dev, "%s control init failed (%d)\n",
1826 + __func__, ret);
1827 + goto error;
1828 + }
1829 +
1830 + imx708->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1831 + imx708->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1832 + imx708->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1833 + imx708->hdr_mode->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1834 +
1835 + imx708->sd.ctrl_handler = ctrl_hdlr;
1836 +
1837 + /* Setup exposure and frame/line length limits. */
1838 + imx708_set_framing_limits(imx708);
1839 +
1840 + return 0;
1841 +
1842 +error:
1843 + v4l2_ctrl_handler_free(ctrl_hdlr);
1844 + mutex_destroy(&imx708->mutex);
1845 +
1846 + return ret;
1847 +}
1848 +
1849 +static void imx708_free_controls(struct imx708 *imx708)
1850 +{
1851 + v4l2_ctrl_handler_free(imx708->sd.ctrl_handler);
1852 + mutex_destroy(&imx708->mutex);
1853 +}
1854 +
1855 +static int imx708_check_hwcfg(struct device *dev)
1856 +{
1857 + struct fwnode_handle *endpoint;
1858 + struct v4l2_fwnode_endpoint ep_cfg = {
1859 + .bus_type = V4L2_MBUS_CSI2_DPHY
1860 + };
1861 + int ret = -EINVAL;
1862 +
1863 + endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
1864 + if (!endpoint) {
1865 + dev_err(dev, "endpoint node not found\n");
1866 + return -EINVAL;
1867 + }
1868 +
1869 + if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
1870 + dev_err(dev, "could not parse endpoint\n");
1871 + goto error_out;
1872 + }
1873 +
1874 + /* Check the number of MIPI CSI2 data lanes */
1875 + if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
1876 + dev_err(dev, "only 2 data lanes are currently supported\n");
1877 + goto error_out;
1878 + }
1879 +
1880 + /* Check the link frequency set in device tree */
1881 + if (!ep_cfg.nr_of_link_frequencies) {
1882 + dev_err(dev, "link-frequency property not found in DT\n");
1883 + goto error_out;
1884 + }
1885 +
1886 + if (ep_cfg.nr_of_link_frequencies != 1 ||
1887 + ep_cfg.link_frequencies[0] != IMX708_DEFAULT_LINK_FREQ) {
1888 + dev_err(dev, "Link frequency not supported: %lld\n",
1889 + ep_cfg.link_frequencies[0]);
1890 + goto error_out;
1891 + }
1892 +
1893 + ret = 0;
1894 +
1895 +error_out:
1896 + v4l2_fwnode_endpoint_free(&ep_cfg);
1897 + fwnode_handle_put(endpoint);
1898 +
1899 + return ret;
1900 +}
1901 +
1902 +static int imx708_probe(struct i2c_client *client)
1903 +{
1904 + struct device *dev = &client->dev;
1905 + struct imx708 *imx708;
1906 + int ret;
1907 +
1908 + imx708 = devm_kzalloc(&client->dev, sizeof(*imx708), GFP_KERNEL);
1909 + if (!imx708)
1910 + return -ENOMEM;
1911 +
1912 + v4l2_i2c_subdev_init(&imx708->sd, client, &imx708_subdev_ops);
1913 +
1914 + /* Check the hardware configuration in device tree */
1915 + if (imx708_check_hwcfg(dev))
1916 + return -EINVAL;
1917 +
1918 + /* Get system clock (xclk) */
1919 + imx708->xclk = devm_clk_get(dev, NULL);
1920 + if (IS_ERR(imx708->xclk)) {
1921 + dev_err(dev, "failed to get xclk\n");
1922 + return PTR_ERR(imx708->xclk);
1923 + }
1924 +
1925 + imx708->xclk_freq = clk_get_rate(imx708->xclk);
1926 + if (imx708->xclk_freq != IMX708_XCLK_FREQ) {
1927 + dev_err(dev, "xclk frequency not supported: %d Hz\n",
1928 + imx708->xclk_freq);
1929 + return -EINVAL;
1930 + }
1931 +
1932 + ret = imx708_get_regulators(imx708);
1933 + if (ret) {
1934 + dev_err(dev, "failed to get regulators\n");
1935 + return ret;
1936 + }
1937 +
1938 + /* Request optional enable pin */
1939 + imx708->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1940 + GPIOD_OUT_HIGH);
1941 +
1942 + /*
1943 + * The sensor must be powered for imx708_identify_module()
1944 + * to be able to read the CHIP_ID register
1945 + */
1946 + ret = imx708_power_on(dev);
1947 + if (ret)
1948 + return ret;
1949 +
1950 + ret = imx708_identify_module(imx708);
1951 + if (ret)
1952 + goto error_power_off;
1953 +
1954 + /* Initialize default format */
1955 + imx708_set_default_format(imx708);
1956 +
1957 + /* Enable runtime PM and turn off the device */
1958 + pm_runtime_set_active(dev);
1959 + pm_runtime_enable(dev);
1960 + pm_runtime_idle(dev);
1961 +
1962 + /* This needs the pm runtime to be registered. */
1963 + ret = imx708_init_controls(imx708);
1964 + if (ret)
1965 + goto error_power_off;
1966 +
1967 + /* Initialize subdev */
1968 + imx708->sd.internal_ops = &imx708_internal_ops;
1969 + imx708->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1970 + V4L2_SUBDEV_FL_HAS_EVENTS;
1971 + imx708->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1972 +
1973 + /* Initialize source pads */
1974 + imx708->pad[IMAGE_PAD].flags = MEDIA_PAD_FL_SOURCE;
1975 + imx708->pad[METADATA_PAD].flags = MEDIA_PAD_FL_SOURCE;
1976 +
1977 + ret = media_entity_pads_init(&imx708->sd.entity, NUM_PADS, imx708->pad);
1978 + if (ret) {
1979 + dev_err(dev, "failed to init entity pads: %d\n", ret);
1980 + goto error_handler_free;
1981 + }
1982 +
1983 + ret = v4l2_async_register_subdev_sensor(&imx708->sd);
1984 + if (ret < 0) {
1985 + dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
1986 + goto error_media_entity;
1987 + }
1988 +
1989 + return 0;
1990 +
1991 +error_media_entity:
1992 + media_entity_cleanup(&imx708->sd.entity);
1993 +
1994 +error_handler_free:
1995 + imx708_free_controls(imx708);
1996 +
1997 +error_power_off:
1998 + pm_runtime_disable(&client->dev);
1999 + pm_runtime_set_suspended(&client->dev);
2000 + imx708_power_off(&client->dev);
2001 +
2002 + return ret;
2003 +}
2004 +
2005 +static void imx708_remove(struct i2c_client *client)
2006 +{
2007 + struct v4l2_subdev *sd = i2c_get_clientdata(client);
2008 + struct imx708 *imx708 = to_imx708(sd);
2009 +
2010 + v4l2_async_unregister_subdev(sd);
2011 + media_entity_cleanup(&sd->entity);
2012 + imx708_free_controls(imx708);
2013 +
2014 + pm_runtime_disable(&client->dev);
2015 + if (!pm_runtime_status_suspended(&client->dev))
2016 + imx708_power_off(&client->dev);
2017 + pm_runtime_set_suspended(&client->dev);
2018 +}
2019 +
2020 +static const struct of_device_id imx708_dt_ids[] = {
2021 + { .compatible = "sony,imx708" },
2022 + { /* sentinel */ }
2023 +};
2024 +MODULE_DEVICE_TABLE(of, imx708_dt_ids);
2025 +
2026 +static const struct dev_pm_ops imx708_pm_ops = {
2027 + SET_SYSTEM_SLEEP_PM_OPS(imx708_suspend, imx708_resume)
2028 + SET_RUNTIME_PM_OPS(imx708_power_off, imx708_power_on, NULL)
2029 +};
2030 +
2031 +static struct i2c_driver imx708_i2c_driver = {
2032 + .driver = {
2033 + .name = "imx708",
2034 + .of_match_table = imx708_dt_ids,
2035 + .pm = &imx708_pm_ops,
2036 + },
2037 + .probe_new = imx708_probe,
2038 + .remove = imx708_remove,
2039 +};
2040 +
2041 +module_i2c_driver(imx708_i2c_driver);
2042 +
2043 +MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
2044 +MODULE_DESCRIPTION("Sony IMX708 sensor driver");
2045 +MODULE_LICENSE("GPL v2");