blob: e90c9656f28c7b853a34a6489737389adda1ff24 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 58483dcbbb5feca6da79970665950b6b43928e60 Mon Sep 17 00:00:00 2001
2From: Naushir Patuck <naush@raspberrypi.com>
3Date: Fri, 8 May 2020 10:00:12 +0100
4Subject: [PATCH] media: i2c: Add driver for Sony IMX477 sensor
5
6Adds a driver for the 12MPix Sony IMX477 CSI2 sensor.
7Whilst the sensor supports 2 or 4 CSI2 data lanes, this driver
8currently only supports 2 lanes.
9
10The following Bayer modes are currently available:
11
124056x3040 12-bit @ 10fps
132028x1520 12-bit (binned) @ 40fps
142028x1050 12-bit (cropped/binned) @ 50fps
151012x760 10-bit (scaled) @ 120 fps
16
17Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
18---
19 MAINTAINERS | 8 +
20 drivers/media/i2c/Kconfig | 11 +
21 drivers/media/i2c/Makefile | 1 +
22 drivers/media/i2c/imx477.c | 2191 ++++++++++++++++++++++++++++++++++++
23 4 files changed, 2211 insertions(+)
24 create mode 100644 drivers/media/i2c/imx477.c
25
26--- a/MAINTAINERS
27+++ b/MAINTAINERS
28@@ -15198,6 +15198,14 @@ T: git git://linuxtv.org/media_tree.git
29 S: Maintained
30 F: drivers/media/i2c/imx355.c
31
32+SONY IMX477 SENSOR DRIVER
33+M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
34+L: linux-media@vger.kernel.org
35+T: git git://linuxtv.org/media_tree.git
36+S: Maintained
37+F: drivers/media/i2c/imx477.c
38+F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
39+
40 SONY MEMORYSTICK SUBSYSTEM
41 M: Maxim Levitsky <maximlevitsky@gmail.com>
42 M: Alex Dubov <oakad@yahoo.com>
43--- a/drivers/media/i2c/Kconfig
44+++ b/drivers/media/i2c/Kconfig
45@@ -609,6 +609,17 @@ config VIDEO_IMX274
46 This is a V4L2 sensor driver for the Sony IMX274
47 CMOS image sensor.
48
49+config VIDEO_IMX477
50+ tristate "Sony IMX477 sensor support"
51+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
52+ depends on MEDIA_CAMERA_SUPPORT
53+ help
54+ This is a Video4Linux2 sensor driver for the Sony
55+ IMX477 camera.
56+
57+ To compile this driver as a module, choose M here: the
58+ module will be called imx477.
59+
60 config VIDEO_IMX319
61 tristate "Sony IMX319 sensor support"
62 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
63--- a/drivers/media/i2c/Makefile
64+++ b/drivers/media/i2c/Makefile
65@@ -114,6 +114,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
66 obj-$(CONFIG_VIDEO_IMX219) += imx219.o
67 obj-$(CONFIG_VIDEO_IMX258) += imx258.o
68 obj-$(CONFIG_VIDEO_IMX274) += imx274.o
69+obj-$(CONFIG_VIDEO_IMX477) += imx477.o
70 obj-$(CONFIG_VIDEO_IMX319) += imx319.o
71 obj-$(CONFIG_VIDEO_IMX355) += imx355.o
72 obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
73--- /dev/null
74+++ b/drivers/media/i2c/imx477.c
75@@ -0,0 +1,2191 @@
76+// SPDX-License-Identifier: GPL-2.0
77+/*
78+ * A V4L2 driver for Sony IMX477 cameras.
79+ * Copyright (C) 2020, Raspberry Pi (Trading) Ltd
80+ *
81+ * Based on Sony imx219 camera driver
82+ * Copyright (C) 2019-2020 Raspberry Pi (Trading) Ltd
83+ */
84+#include <asm/unaligned.h>
85+#include <linux/clk.h>
86+#include <linux/delay.h>
87+#include <linux/gpio/consumer.h>
88+#include <linux/i2c.h>
89+#include <linux/module.h>
90+#include <linux/pm_runtime.h>
91+#include <linux/regulator/consumer.h>
92+#include <media/v4l2-ctrls.h>
93+#include <media/v4l2-device.h>
94+#include <media/v4l2-event.h>
95+#include <media/v4l2-fwnode.h>
96+#include <media/v4l2-mediabus.h>
97+
98+#define IMX477_REG_VALUE_08BIT 1
99+#define IMX477_REG_VALUE_16BIT 2
100+
101+/* Chip ID */
102+#define IMX477_REG_CHIP_ID 0x0016
103+#define IMX477_CHIP_ID 0x0477
104+
105+#define IMX477_REG_MODE_SELECT 0x0100
106+#define IMX477_MODE_STANDBY 0x00
107+#define IMX477_MODE_STREAMING 0x01
108+
109+#define IMX477_REG_ORIENTATION 0x101
110+
111+#define IMX477_XCLK_FREQ 24000000
112+
113+#define IMX477_DEFAULT_LINK_FREQ 450000000
114+
115+/* Pixel rate is fixed at 840MHz for all the modes */
116+#define IMX477_PIXEL_RATE 840000000
117+
118+/* V_TIMING internal */
119+#define IMX477_REG_FRAME_LENGTH 0x0340
120+#define IMX477_FRAME_LENGTH_MAX 0xffdc
121+
122+/* Exposure control */
123+#define IMX477_REG_EXPOSURE 0x0202
124+#define IMX477_EXPOSURE_OFFSET 22
125+#define IMX477_EXPOSURE_MIN 20
126+#define IMX477_EXPOSURE_STEP 1
127+#define IMX477_EXPOSURE_DEFAULT 0x640
128+#define IMX477_EXPOSURE_MAX (IMX477_FRAME_LENGTH_MAX - \
129+ IMX477_EXPOSURE_OFFSET)
130+
131+/* Analog gain control */
132+#define IMX477_REG_ANALOG_GAIN 0x0204
133+#define IMX477_ANA_GAIN_MIN 0
134+#define IMX477_ANA_GAIN_MAX 978
135+#define IMX477_ANA_GAIN_STEP 1
136+#define IMX477_ANA_GAIN_DEFAULT 0x0
137+
138+/* Digital gain control */
139+#define IMX477_REG_DIGITAL_GAIN 0x020e
140+#define IMX477_DGTL_GAIN_MIN 0x0100
141+#define IMX477_DGTL_GAIN_MAX 0xffff
142+#define IMX477_DGTL_GAIN_DEFAULT 0x0100
143+#define IMX477_DGTL_GAIN_STEP 1
144+
145+/* Test Pattern Control */
146+#define IMX477_REG_TEST_PATTERN 0x0600
147+#define IMX477_TEST_PATTERN_DISABLE 0
148+#define IMX477_TEST_PATTERN_SOLID_COLOR 1
149+#define IMX477_TEST_PATTERN_COLOR_BARS 2
150+#define IMX477_TEST_PATTERN_GREY_COLOR 3
151+#define IMX477_TEST_PATTERN_PN9 4
152+
153+/* Test pattern colour components */
154+#define IMX477_REG_TEST_PATTERN_R 0x0602
155+#define IMX477_REG_TEST_PATTERN_GR 0x0604
156+#define IMX477_REG_TEST_PATTERN_B 0x0606
157+#define IMX477_REG_TEST_PATTERN_GB 0x0608
158+#define IMX477_TEST_PATTERN_COLOUR_MIN 0
159+#define IMX477_TEST_PATTERN_COLOUR_MAX 0x0fff
160+#define IMX477_TEST_PATTERN_COLOUR_STEP 1
161+#define IMX477_TEST_PATTERN_R_DEFAULT IMX477_TEST_PATTERN_COLOUR_MAX
162+#define IMX477_TEST_PATTERN_GR_DEFAULT 0
163+#define IMX477_TEST_PATTERN_B_DEFAULT 0
164+#define IMX477_TEST_PATTERN_GB_DEFAULT 0
165+
166+/* Embedded metadata stream structure */
167+#define IMX477_EMBEDDED_LINE_WIDTH 16384
168+#define IMX477_NUM_EMBEDDED_LINES 1
169+
170+enum pad_types {
171+ IMAGE_PAD,
172+ METADATA_PAD,
173+ NUM_PADS
174+};
175+
176+/* IMX477 native and active pixel array size. */
177+#define IMX477_NATIVE_WIDTH 4072U
178+#define IMX477_NATIVE_HEIGHT 3176U
179+#define IMX477_PIXEL_ARRAY_LEFT 8U
180+#define IMX477_PIXEL_ARRAY_TOP 16U
181+#define IMX477_PIXEL_ARRAY_WIDTH 4056U
182+#define IMX477_PIXEL_ARRAY_HEIGHT 3040U
183+
184+struct imx477_reg {
185+ u16 address;
186+ u8 val;
187+};
188+
189+struct imx477_reg_list {
190+ unsigned int num_of_regs;
191+ const struct imx477_reg *regs;
192+};
193+
194+/* Mode : resolution and related config&values */
195+struct imx477_mode {
196+ /* Frame width */
197+ unsigned int width;
198+
199+ /* Frame height */
200+ unsigned int height;
201+
202+ /* H-timing in pixels */
203+ unsigned int line_length_pix;
204+
205+ /* Analog crop rectangle. */
206+ struct v4l2_rect crop;
207+
208+ /* Highest possible framerate. */
209+ struct v4l2_fract timeperframe_min;
210+
211+ /* Default framerate. */
212+ struct v4l2_fract timeperframe_default;
213+
214+ /* Default register values */
215+ struct imx477_reg_list reg_list;
216+};
217+
218+static const struct imx477_reg mode_common_regs[] = {
219+ {0x0136, 0x18},
220+ {0x0137, 0x00},
221+ {0xe000, 0x00},
222+ {0xe07a, 0x01},
223+ {0x0808, 0x02},
224+ {0x4ae9, 0x18},
225+ {0x4aea, 0x08},
226+ {0xf61c, 0x04},
227+ {0xf61e, 0x04},
228+ {0x4ae9, 0x21},
229+ {0x4aea, 0x80},
230+ {0x38a8, 0x1f},
231+ {0x38a9, 0xff},
232+ {0x38aa, 0x1f},
233+ {0x38ab, 0xff},
234+ {0x55d4, 0x00},
235+ {0x55d5, 0x00},
236+ {0x55d6, 0x07},
237+ {0x55d7, 0xff},
238+ {0x55e8, 0x07},
239+ {0x55e9, 0xff},
240+ {0x55ea, 0x00},
241+ {0x55eb, 0x00},
242+ {0x574c, 0x07},
243+ {0x574d, 0xff},
244+ {0x574e, 0x00},
245+ {0x574f, 0x00},
246+ {0x5754, 0x00},
247+ {0x5755, 0x00},
248+ {0x5756, 0x07},
249+ {0x5757, 0xff},
250+ {0x5973, 0x04},
251+ {0x5974, 0x01},
252+ {0x5d13, 0xc3},
253+ {0x5d14, 0x58},
254+ {0x5d15, 0xa3},
255+ {0x5d16, 0x1d},
256+ {0x5d17, 0x65},
257+ {0x5d18, 0x8c},
258+ {0x5d1a, 0x06},
259+ {0x5d1b, 0xa9},
260+ {0x5d1c, 0x45},
261+ {0x5d1d, 0x3a},
262+ {0x5d1e, 0xab},
263+ {0x5d1f, 0x15},
264+ {0x5d21, 0x0e},
265+ {0x5d22, 0x52},
266+ {0x5d23, 0xaa},
267+ {0x5d24, 0x7d},
268+ {0x5d25, 0x57},
269+ {0x5d26, 0xa8},
270+ {0x5d37, 0x5a},
271+ {0x5d38, 0x5a},
272+ {0x5d77, 0x7f},
273+ {0x7b75, 0x0e},
274+ {0x7b76, 0x0b},
275+ {0x7b77, 0x08},
276+ {0x7b78, 0x0a},
277+ {0x7b79, 0x47},
278+ {0x7b7c, 0x00},
279+ {0x7b7d, 0x00},
280+ {0x8d1f, 0x00},
281+ {0x8d27, 0x00},
282+ {0x9004, 0x03},
283+ {0x9200, 0x50},
284+ {0x9201, 0x6c},
285+ {0x9202, 0x71},
286+ {0x9203, 0x00},
287+ {0x9204, 0x71},
288+ {0x9205, 0x01},
289+ {0x9371, 0x6a},
290+ {0x9373, 0x6a},
291+ {0x9375, 0x64},
292+ {0x991a, 0x00},
293+ {0x996b, 0x8c},
294+ {0x996c, 0x64},
295+ {0x996d, 0x50},
296+ {0x9a4c, 0x0d},
297+ {0x9a4d, 0x0d},
298+ {0xa001, 0x0a},
299+ {0xa003, 0x0a},
300+ {0xa005, 0x0a},
301+ {0xa006, 0x01},
302+ {0xa007, 0xc0},
303+ {0xa009, 0xc0},
304+ {0x3d8a, 0x01},
305+ {0x4421, 0x04},
306+ {0x7b3b, 0x01},
307+ {0x7b4c, 0x00},
308+ {0x9905, 0x00},
309+ {0x9907, 0x00},
310+ {0x9909, 0x00},
311+ {0x990b, 0x00},
312+ {0x9944, 0x3c},
313+ {0x9947, 0x3c},
314+ {0x994a, 0x8c},
315+ {0x994b, 0x50},
316+ {0x994c, 0x1b},
317+ {0x994d, 0x8c},
318+ {0x994e, 0x50},
319+ {0x994f, 0x1b},
320+ {0x9950, 0x8c},
321+ {0x9951, 0x1b},
322+ {0x9952, 0x0a},
323+ {0x9953, 0x8c},
324+ {0x9954, 0x1b},
325+ {0x9955, 0x0a},
326+ {0x9a13, 0x04},
327+ {0x9a14, 0x04},
328+ {0x9a19, 0x00},
329+ {0x9a1c, 0x04},
330+ {0x9a1d, 0x04},
331+ {0x9a26, 0x05},
332+ {0x9a27, 0x05},
333+ {0x9a2c, 0x01},
334+ {0x9a2d, 0x03},
335+ {0x9a2f, 0x05},
336+ {0x9a30, 0x05},
337+ {0x9a41, 0x00},
338+ {0x9a46, 0x00},
339+ {0x9a47, 0x00},
340+ {0x9c17, 0x35},
341+ {0x9c1d, 0x31},
342+ {0x9c29, 0x50},
343+ {0x9c3b, 0x2f},
344+ {0x9c41, 0x6b},
345+ {0x9c47, 0x2d},
346+ {0x9c4d, 0x40},
347+ {0x9c6b, 0x00},
348+ {0x9c71, 0xc8},
349+ {0x9c73, 0x32},
350+ {0x9c75, 0x04},
351+ {0x9c7d, 0x2d},
352+ {0x9c83, 0x40},
353+ {0x9c94, 0x3f},
354+ {0x9c95, 0x3f},
355+ {0x9c96, 0x3f},
356+ {0x9c97, 0x00},
357+ {0x9c98, 0x00},
358+ {0x9c99, 0x00},
359+ {0x9c9a, 0x3f},
360+ {0x9c9b, 0x3f},
361+ {0x9c9c, 0x3f},
362+ {0x9ca0, 0x0f},
363+ {0x9ca1, 0x0f},
364+ {0x9ca2, 0x0f},
365+ {0x9ca3, 0x00},
366+ {0x9ca4, 0x00},
367+ {0x9ca5, 0x00},
368+ {0x9ca6, 0x1e},
369+ {0x9ca7, 0x1e},
370+ {0x9ca8, 0x1e},
371+ {0x9ca9, 0x00},
372+ {0x9caa, 0x00},
373+ {0x9cab, 0x00},
374+ {0x9cac, 0x09},
375+ {0x9cad, 0x09},
376+ {0x9cae, 0x09},
377+ {0x9cbd, 0x50},
378+ {0x9cbf, 0x50},
379+ {0x9cc1, 0x50},
380+ {0x9cc3, 0x40},
381+ {0x9cc5, 0x40},
382+ {0x9cc7, 0x40},
383+ {0x9cc9, 0x0a},
384+ {0x9ccb, 0x0a},
385+ {0x9ccd, 0x0a},
386+ {0x9d17, 0x35},
387+ {0x9d1d, 0x31},
388+ {0x9d29, 0x50},
389+ {0x9d3b, 0x2f},
390+ {0x9d41, 0x6b},
391+ {0x9d47, 0x42},
392+ {0x9d4d, 0x5a},
393+ {0x9d6b, 0x00},
394+ {0x9d71, 0xc8},
395+ {0x9d73, 0x32},
396+ {0x9d75, 0x04},
397+ {0x9d7d, 0x42},
398+ {0x9d83, 0x5a},
399+ {0x9d94, 0x3f},
400+ {0x9d95, 0x3f},
401+ {0x9d96, 0x3f},
402+ {0x9d97, 0x00},
403+ {0x9d98, 0x00},
404+ {0x9d99, 0x00},
405+ {0x9d9a, 0x3f},
406+ {0x9d9b, 0x3f},
407+ {0x9d9c, 0x3f},
408+ {0x9d9d, 0x1f},
409+ {0x9d9e, 0x1f},
410+ {0x9d9f, 0x1f},
411+ {0x9da0, 0x0f},
412+ {0x9da1, 0x0f},
413+ {0x9da2, 0x0f},
414+ {0x9da3, 0x00},
415+ {0x9da4, 0x00},
416+ {0x9da5, 0x00},
417+ {0x9da6, 0x1e},
418+ {0x9da7, 0x1e},
419+ {0x9da8, 0x1e},
420+ {0x9da9, 0x00},
421+ {0x9daa, 0x00},
422+ {0x9dab, 0x00},
423+ {0x9dac, 0x09},
424+ {0x9dad, 0x09},
425+ {0x9dae, 0x09},
426+ {0x9dc9, 0x0a},
427+ {0x9dcb, 0x0a},
428+ {0x9dcd, 0x0a},
429+ {0x9e17, 0x35},
430+ {0x9e1d, 0x31},
431+ {0x9e29, 0x50},
432+ {0x9e3b, 0x2f},
433+ {0x9e41, 0x6b},
434+ {0x9e47, 0x2d},
435+ {0x9e4d, 0x40},
436+ {0x9e6b, 0x00},
437+ {0x9e71, 0xc8},
438+ {0x9e73, 0x32},
439+ {0x9e75, 0x04},
440+ {0x9e94, 0x0f},
441+ {0x9e95, 0x0f},
442+ {0x9e96, 0x0f},
443+ {0x9e97, 0x00},
444+ {0x9e98, 0x00},
445+ {0x9e99, 0x00},
446+ {0x9ea0, 0x0f},
447+ {0x9ea1, 0x0f},
448+ {0x9ea2, 0x0f},
449+ {0x9ea3, 0x00},
450+ {0x9ea4, 0x00},
451+ {0x9ea5, 0x00},
452+ {0x9ea6, 0x3f},
453+ {0x9ea7, 0x3f},
454+ {0x9ea8, 0x3f},
455+ {0x9ea9, 0x00},
456+ {0x9eaa, 0x00},
457+ {0x9eab, 0x00},
458+ {0x9eac, 0x09},
459+ {0x9ead, 0x09},
460+ {0x9eae, 0x09},
461+ {0x9ec9, 0x0a},
462+ {0x9ecb, 0x0a},
463+ {0x9ecd, 0x0a},
464+ {0x9f17, 0x35},
465+ {0x9f1d, 0x31},
466+ {0x9f29, 0x50},
467+ {0x9f3b, 0x2f},
468+ {0x9f41, 0x6b},
469+ {0x9f47, 0x42},
470+ {0x9f4d, 0x5a},
471+ {0x9f6b, 0x00},
472+ {0x9f71, 0xc8},
473+ {0x9f73, 0x32},
474+ {0x9f75, 0x04},
475+ {0x9f94, 0x0f},
476+ {0x9f95, 0x0f},
477+ {0x9f96, 0x0f},
478+ {0x9f97, 0x00},
479+ {0x9f98, 0x00},
480+ {0x9f99, 0x00},
481+ {0x9f9a, 0x2f},
482+ {0x9f9b, 0x2f},
483+ {0x9f9c, 0x2f},
484+ {0x9f9d, 0x00},
485+ {0x9f9e, 0x00},
486+ {0x9f9f, 0x00},
487+ {0x9fa0, 0x0f},
488+ {0x9fa1, 0x0f},
489+ {0x9fa2, 0x0f},
490+ {0x9fa3, 0x00},
491+ {0x9fa4, 0x00},
492+ {0x9fa5, 0x00},
493+ {0x9fa6, 0x1e},
494+ {0x9fa7, 0x1e},
495+ {0x9fa8, 0x1e},
496+ {0x9fa9, 0x00},
497+ {0x9faa, 0x00},
498+ {0x9fab, 0x00},
499+ {0x9fac, 0x09},
500+ {0x9fad, 0x09},
501+ {0x9fae, 0x09},
502+ {0x9fc9, 0x0a},
503+ {0x9fcb, 0x0a},
504+ {0x9fcd, 0x0a},
505+ {0xa14b, 0xff},
506+ {0xa151, 0x0c},
507+ {0xa153, 0x50},
508+ {0xa155, 0x02},
509+ {0xa157, 0x00},
510+ {0xa1ad, 0xff},
511+ {0xa1b3, 0x0c},
512+ {0xa1b5, 0x50},
513+ {0xa1b9, 0x00},
514+ {0xa24b, 0xff},
515+ {0xa257, 0x00},
516+ {0xa2ad, 0xff},
517+ {0xa2b9, 0x00},
518+ {0xb21f, 0x04},
519+ {0xb35c, 0x00},
520+ {0xb35e, 0x08},
521+ {0x0112, 0x0c},
522+ {0x0113, 0x0c},
523+ {0x0114, 0x01},
524+ {0x0350, 0x00},
525+ {0xbcf1, 0x02},
526+ {0x3ff9, 0x01},
527+};
528+
529+/* 12 mpix 10fps */
530+static const struct imx477_reg mode_4056x3040_regs[] = {
531+ {0x0342, 0x5d},
532+ {0x0343, 0xc0},
533+ {0x0344, 0x00},
534+ {0x0345, 0x00},
535+ {0x0346, 0x00},
536+ {0x0347, 0x00},
537+ {0x0348, 0x0f},
538+ {0x0349, 0xd7},
539+ {0x034a, 0x0b},
540+ {0x034b, 0xdf},
541+ {0x00e3, 0x00},
542+ {0x00e4, 0x00},
543+ {0x00fc, 0x0a},
544+ {0x00fd, 0x0a},
545+ {0x00fe, 0x0a},
546+ {0x00ff, 0x0a},
547+ {0x0220, 0x00},
548+ {0x0221, 0x11},
549+ {0x0381, 0x01},
550+ {0x0383, 0x01},
551+ {0x0385, 0x01},
552+ {0x0387, 0x01},
553+ {0x0900, 0x00},
554+ {0x0901, 0x11},
555+ {0x0902, 0x02},
556+ {0x3140, 0x02},
557+ {0x3c00, 0x00},
558+ {0x3c01, 0x03},
559+ {0x3c02, 0xa2},
560+ {0x3f0d, 0x01},
561+ {0x5748, 0x07},
562+ {0x5749, 0xff},
563+ {0x574a, 0x00},
564+ {0x574b, 0x00},
565+ {0x7b75, 0x0a},
566+ {0x7b76, 0x0c},
567+ {0x7b77, 0x07},
568+ {0x7b78, 0x06},
569+ {0x7b79, 0x3c},
570+ {0x7b53, 0x01},
571+ {0x9369, 0x5a},
572+ {0x936b, 0x55},
573+ {0x936d, 0x28},
574+ {0x9304, 0x00},
575+ {0x9305, 0x00},
576+ {0x9e9a, 0x2f},
577+ {0x9e9b, 0x2f},
578+ {0x9e9c, 0x2f},
579+ {0x9e9d, 0x00},
580+ {0x9e9e, 0x00},
581+ {0x9e9f, 0x00},
582+ {0xa2a9, 0x60},
583+ {0xa2b7, 0x00},
584+ {0x0401, 0x00},
585+ {0x0404, 0x00},
586+ {0x0405, 0x10},
587+ {0x0408, 0x00},
588+ {0x0409, 0x00},
589+ {0x040a, 0x00},
590+ {0x040b, 0x00},
591+ {0x040c, 0x0f},
592+ {0x040d, 0xd8},
593+ {0x040e, 0x0b},
594+ {0x040f, 0xe0},
595+ {0x034c, 0x0f},
596+ {0x034d, 0xd8},
597+ {0x034e, 0x0b},
598+ {0x034f, 0xe0},
599+ {0x0301, 0x05},
600+ {0x0303, 0x02},
601+ {0x0305, 0x04},
602+ {0x0306, 0x01},
603+ {0x0307, 0x5e},
604+ {0x0309, 0x0c},
605+ {0x030b, 0x02},
606+ {0x030d, 0x02},
607+ {0x030e, 0x00},
608+ {0x030f, 0x96},
609+ {0x0310, 0x01},
610+ {0x0820, 0x07},
611+ {0x0821, 0x08},
612+ {0x0822, 0x00},
613+ {0x0823, 0x00},
614+ {0x080a, 0x00},
615+ {0x080b, 0x7f},
616+ {0x080c, 0x00},
617+ {0x080d, 0x4f},
618+ {0x080e, 0x00},
619+ {0x080f, 0x77},
620+ {0x0810, 0x00},
621+ {0x0811, 0x5f},
622+ {0x0812, 0x00},
623+ {0x0813, 0x57},
624+ {0x0814, 0x00},
625+ {0x0815, 0x4f},
626+ {0x0816, 0x01},
627+ {0x0817, 0x27},
628+ {0x0818, 0x00},
629+ {0x0819, 0x3f},
630+ {0xe04c, 0x00},
631+ {0xe04d, 0x7f},
632+ {0xe04e, 0x00},
633+ {0xe04f, 0x1f},
634+ {0x3e20, 0x01},
635+ {0x3e37, 0x00},
636+ {0x3f50, 0x00},
637+ {0x3f56, 0x02},
638+ {0x3f57, 0xae},
639+};
640+
641+/* 2x2 binned. 40fps */
642+static const struct imx477_reg mode_2028x1520_regs[] = {
643+ {0x0342, 0x31},
644+ {0x0343, 0xc4},
645+ {0x0344, 0x00},
646+ {0x0345, 0x00},
647+ {0x0346, 0x00},
648+ {0x0347, 0x00},
649+ {0x0348, 0x0f},
650+ {0x0349, 0xd7},
651+ {0x034a, 0x0b},
652+ {0x034b, 0xdf},
653+ {0x0220, 0x00},
654+ {0x0221, 0x11},
655+ {0x0381, 0x01},
656+ {0x0383, 0x01},
657+ {0x0385, 0x01},
658+ {0x0387, 0x01},
659+ {0x0900, 0x01},
660+ {0x0901, 0x12},
661+ {0x0902, 0x02},
662+ {0x3140, 0x02},
663+ {0x3c00, 0x00},
664+ {0x3c01, 0x03},
665+ {0x3c02, 0xa2},
666+ {0x3f0d, 0x01},
667+ {0x5748, 0x07},
668+ {0x5749, 0xff},
669+ {0x574a, 0x00},
670+ {0x574b, 0x00},
671+ {0x7b53, 0x01},
672+ {0x9369, 0x73},
673+ {0x936b, 0x64},
674+ {0x936d, 0x5f},
675+ {0x9304, 0x00},
676+ {0x9305, 0x00},
677+ {0x9e9a, 0x2f},
678+ {0x9e9b, 0x2f},
679+ {0x9e9c, 0x2f},
680+ {0x9e9d, 0x00},
681+ {0x9e9e, 0x00},
682+ {0x9e9f, 0x00},
683+ {0xa2a9, 0x60},
684+ {0xa2b7, 0x00},
685+ {0x0401, 0x01},
686+ {0x0404, 0x00},
687+ {0x0405, 0x20},
688+ {0x0408, 0x00},
689+ {0x0409, 0x00},
690+ {0x040a, 0x00},
691+ {0x040b, 0x00},
692+ {0x040c, 0x0f},
693+ {0x040d, 0xd8},
694+ {0x040e, 0x0b},
695+ {0x040f, 0xe0},
696+ {0x034c, 0x07},
697+ {0x034d, 0xec},
698+ {0x034e, 0x05},
699+ {0x034f, 0xf0},
700+ {0x0301, 0x05},
701+ {0x0303, 0x02},
702+ {0x0305, 0x04},
703+ {0x0306, 0x01},
704+ {0x0307, 0x5e},
705+ {0x0309, 0x0c},
706+ {0x030b, 0x02},
707+ {0x030d, 0x02},
708+ {0x030e, 0x00},
709+ {0x030f, 0x96},
710+ {0x0310, 0x01},
711+ {0x0820, 0x07},
712+ {0x0821, 0x08},
713+ {0x0822, 0x00},
714+ {0x0823, 0x00},
715+ {0x080a, 0x00},
716+ {0x080b, 0x7f},
717+ {0x080c, 0x00},
718+ {0x080d, 0x4f},
719+ {0x080e, 0x00},
720+ {0x080f, 0x77},
721+ {0x0810, 0x00},
722+ {0x0811, 0x5f},
723+ {0x0812, 0x00},
724+ {0x0813, 0x57},
725+ {0x0814, 0x00},
726+ {0x0815, 0x4f},
727+ {0x0816, 0x01},
728+ {0x0817, 0x27},
729+ {0x0818, 0x00},
730+ {0x0819, 0x3f},
731+ {0xe04c, 0x00},
732+ {0xe04d, 0x7f},
733+ {0xe04e, 0x00},
734+ {0xe04f, 0x1f},
735+ {0x3e20, 0x01},
736+ {0x3e37, 0x00},
737+ {0x3f50, 0x00},
738+ {0x3f56, 0x01},
739+ {0x3f57, 0x6c},
740+};
741+
742+/* 1080p cropped mode */
743+static const struct imx477_reg mode_2028x1080_regs[] = {
744+ {0x0342, 0x31},
745+ {0x0343, 0xc4},
746+ {0x0344, 0x00},
747+ {0x0345, 0x00},
748+ {0x0346, 0x01},
749+ {0x0347, 0xb8},
750+ {0x0348, 0x0f},
751+ {0x0349, 0xd7},
752+ {0x034a, 0x0a},
753+ {0x034b, 0x27},
754+ {0x0220, 0x00},
755+ {0x0221, 0x11},
756+ {0x0381, 0x01},
757+ {0x0383, 0x01},
758+ {0x0385, 0x01},
759+ {0x0387, 0x01},
760+ {0x0900, 0x01},
761+ {0x0901, 0x12},
762+ {0x0902, 0x02},
763+ {0x3140, 0x02},
764+ {0x3c00, 0x00},
765+ {0x3c01, 0x03},
766+ {0x3c02, 0xa2},
767+ {0x3f0d, 0x01},
768+ {0x5748, 0x07},
769+ {0x5749, 0xff},
770+ {0x574a, 0x00},
771+ {0x574b, 0x00},
772+ {0x7b53, 0x01},
773+ {0x9369, 0x73},
774+ {0x936b, 0x64},
775+ {0x936d, 0x5f},
776+ {0x9304, 0x00},
777+ {0x9305, 0x00},
778+ {0x9e9a, 0x2f},
779+ {0x9e9b, 0x2f},
780+ {0x9e9c, 0x2f},
781+ {0x9e9d, 0x00},
782+ {0x9e9e, 0x00},
783+ {0x9e9f, 0x00},
784+ {0xa2a9, 0x60},
785+ {0xa2b7, 0x00},
786+ {0x0401, 0x01},
787+ {0x0404, 0x00},
788+ {0x0405, 0x20},
789+ {0x0408, 0x00},
790+ {0x0409, 0x00},
791+ {0x040a, 0x00},
792+ {0x040b, 0x00},
793+ {0x040c, 0x0f},
794+ {0x040d, 0xd8},
795+ {0x040e, 0x04},
796+ {0x040f, 0x38},
797+ {0x034c, 0x07},
798+ {0x034d, 0xec},
799+ {0x034e, 0x04},
800+ {0x034f, 0x38},
801+ {0x0301, 0x05},
802+ {0x0303, 0x02},
803+ {0x0305, 0x04},
804+ {0x0306, 0x01},
805+ {0x0307, 0x5e},
806+ {0x0309, 0x0c},
807+ {0x030b, 0x02},
808+ {0x030d, 0x02},
809+ {0x030e, 0x00},
810+ {0x030f, 0x96},
811+ {0x0310, 0x01},
812+ {0x0820, 0x07},
813+ {0x0821, 0x08},
814+ {0x0822, 0x00},
815+ {0x0823, 0x00},
816+ {0x080a, 0x00},
817+ {0x080b, 0x7f},
818+ {0x080c, 0x00},
819+ {0x080d, 0x4f},
820+ {0x080e, 0x00},
821+ {0x080f, 0x77},
822+ {0x0810, 0x00},
823+ {0x0811, 0x5f},
824+ {0x0812, 0x00},
825+ {0x0813, 0x57},
826+ {0x0814, 0x00},
827+ {0x0815, 0x4f},
828+ {0x0816, 0x01},
829+ {0x0817, 0x27},
830+ {0x0818, 0x00},
831+ {0x0819, 0x3f},
832+ {0xe04c, 0x00},
833+ {0xe04d, 0x7f},
834+ {0xe04e, 0x00},
835+ {0xe04f, 0x1f},
836+ {0x3e20, 0x01},
837+ {0x3e37, 0x00},
838+ {0x3f50, 0x00},
839+ {0x3f56, 0x01},
840+ {0x3f57, 0x6c},
841+};
842+
843+/* 4x4 binned. 120fps */
844+static const struct imx477_reg mode_1012x760_regs[] = {
845+ {0x420b, 0x01},
846+ {0x990c, 0x00},
847+ {0x990d, 0x08},
848+ {0x9956, 0x8c},
849+ {0x9957, 0x64},
850+ {0x9958, 0x50},
851+ {0x9a48, 0x06},
852+ {0x9a49, 0x06},
853+ {0x9a4a, 0x06},
854+ {0x9a4b, 0x06},
855+ {0x9a4c, 0x06},
856+ {0x9a4d, 0x06},
857+ {0x0112, 0x0a},
858+ {0x0113, 0x0a},
859+ {0x0114, 0x01},
860+ {0x0342, 0x14},
861+ {0x0343, 0x60},
862+ {0x0344, 0x00},
863+ {0x0345, 0x00},
864+ {0x0346, 0x00},
865+ {0x0347, 0x00},
866+ {0x0348, 0x0f},
867+ {0x0349, 0xd3},
868+ {0x034a, 0x0b},
869+ {0x034b, 0xdf},
870+ {0x00e3, 0x00},
871+ {0x00e4, 0x00},
872+ {0x00fc, 0x0a},
873+ {0x00fd, 0x0a},
874+ {0x00fe, 0x0a},
875+ {0x00ff, 0x0a},
876+ {0x0220, 0x00},
877+ {0x0221, 0x11},
878+ {0x0381, 0x01},
879+ {0x0383, 0x01},
880+ {0x0385, 0x01},
881+ {0x0387, 0x03},
882+ {0x0900, 0x01},
883+ {0x0901, 0x22},
884+ {0x0902, 0x02},
885+ {0x3140, 0x02},
886+ {0x3c00, 0x00},
887+ {0x3c01, 0x01},
888+ {0x3c02, 0x9c},
889+ {0x3f0d, 0x00},
890+ {0x5748, 0x00},
891+ {0x5749, 0x00},
892+ {0x574a, 0x00},
893+ {0x574b, 0xa4},
894+ {0x7b75, 0x0e},
895+ {0x7b76, 0x09},
896+ {0x7b77, 0x08},
897+ {0x7b78, 0x06},
898+ {0x7b79, 0x34},
899+ {0x7b53, 0x00},
900+ {0x9369, 0x73},
901+ {0x936b, 0x64},
902+ {0x936d, 0x5f},
903+ {0x9304, 0x03},
904+ {0x9305, 0x80},
905+ {0x9e9a, 0x3f},
906+ {0x9e9b, 0x3f},
907+ {0x9e9c, 0x3f},
908+ {0x9e9d, 0x27},
909+ {0x9e9e, 0x27},
910+ {0x9e9f, 0x27},
911+ {0xa2a9, 0x27},
912+ {0xa2b7, 0x03},
913+ {0x0401, 0x01},
914+ {0x0404, 0x00},
915+ {0x0405, 0x20},
916+ {0x0408, 0x00},
917+ {0x0409, 0x00},
918+ {0x040a, 0x00},
919+ {0x040b, 0x00},
920+ {0x040c, 0x07},
921+ {0x040d, 0xea},
922+ {0x040e, 0x02},
923+ {0x040f, 0xf8},
924+ {0x034c, 0x03},
925+ {0x034d, 0xf4},
926+ {0x034e, 0x02},
927+ {0x034f, 0xf8},
928+ {0x0301, 0x05},
929+ {0x0303, 0x02},
930+ {0x0305, 0x02},
931+ {0x0306, 0x00},
932+ {0x0307, 0xaf},
933+ {0x0309, 0x0a},
934+ {0x030b, 0x02},
935+ {0x030d, 0x02},
936+ {0x030e, 0x00},
937+ {0x030f, 0x96},
938+ {0x0310, 0x01},
939+ {0x0820, 0x07},
940+ {0x0821, 0x08},
941+ {0x0822, 0x00},
942+ {0x0823, 0x00},
943+ {0x080a, 0x00},
944+ {0x080b, 0x6f},
945+ {0x080c, 0x00},
946+ {0x080d, 0x3f},
947+ {0x080e, 0x00},
948+ {0x080f, 0xff},
949+ {0x0810, 0x00},
950+ {0x0811, 0x4f},
951+ {0x0812, 0x00},
952+ {0x0813, 0x47},
953+ {0x0814, 0x00},
954+ {0x0815, 0x37},
955+ {0x0816, 0x00},
956+ {0x0817, 0xe7},
957+ {0x0818, 0x00},
958+ {0x0819, 0x2f},
959+ {0xe04c, 0x00},
960+ {0xe04d, 0x5f},
961+ {0xe04e, 0x00},
962+ {0xe04f, 0x1f},
963+ {0x3e20, 0x01},
964+ {0x3e37, 0x00},
965+ {0x3f50, 0x00},
966+ {0x3f56, 0x00},
967+ {0x3f57, 0x96},
968+};
969+
970+/* Mode configs */
971+static const struct imx477_mode supported_modes_12bit[] = {
972+ {
973+ /* 12MPix 10fps mode */
974+ .width = 4056,
975+ .height = 3040,
976+ .line_length_pix = 0x5dc0,
977+ .crop = {
978+ .left = 0,
979+ .top = 0,
980+ .width = 4056,
981+ .height = 3040,
982+ },
983+ .timeperframe_min = {
984+ .numerator = 100,
985+ .denominator = 1000
986+ },
987+ .timeperframe_default = {
988+ .numerator = 100,
989+ .denominator = 1000
990+ },
991+ .reg_list = {
992+ .num_of_regs = ARRAY_SIZE(mode_4056x3040_regs),
993+ .regs = mode_4056x3040_regs,
994+ },
995+ },
996+ {
997+ /* 2x2 binned 40fps mode */
998+ .width = 2028,
999+ .height = 1520,
1000+ .line_length_pix = 0x31c4,
1001+ .crop = {
1002+ .left = 0,
1003+ .top = 0,
1004+ .width = 4056,
1005+ .height = 3040,
1006+ },
1007+ .timeperframe_min = {
1008+ .numerator = 100,
1009+ .denominator = 4000
1010+ },
1011+ .timeperframe_default = {
1012+ .numerator = 100,
1013+ .denominator = 3000
1014+ },
1015+ .reg_list = {
1016+ .num_of_regs = ARRAY_SIZE(mode_2028x1520_regs),
1017+ .regs = mode_2028x1520_regs,
1018+ },
1019+ },
1020+ {
1021+ /* 1080p 50fps cropped mode */
1022+ .width = 2028,
1023+ .height = 1080,
1024+ .line_length_pix = 0x31c4,
1025+ .crop = {
1026+ .left = 0,
1027+ .top = 440,
1028+ .width = 4056,
1029+ .height = 2600,
1030+ },
1031+ .timeperframe_min = {
1032+ .numerator = 100,
1033+ .denominator = 5000
1034+ },
1035+ .timeperframe_default = {
1036+ .numerator = 100,
1037+ .denominator = 3000
1038+ },
1039+ .reg_list = {
1040+ .num_of_regs = ARRAY_SIZE(mode_2028x1080_regs),
1041+ .regs = mode_2028x1080_regs,
1042+ },
1043+ }
1044+};
1045+
1046+static const struct imx477_mode supported_modes_10bit[] = {
1047+ {
1048+ /* 720P 120fps. 4x4 binned */
1049+ .width = 1012,
1050+ .height = 760,
1051+ .line_length_pix = 0x1460,
1052+ .crop = {
1053+ /*
1054+ * FIXME: the analog crop rectangle is actually
1055+ * programmed with a horizontal displacement of 0
1056+ * pixels, not 4. It gets shrunk after going through
1057+ * the scaler. Move this information to the compose
1058+ * rectangle once the driver is expanded to represent
1059+ * its processing blocks with multiple subdevs.
1060+ */
1061+ .left = 4,
1062+ .top = 0,
1063+ .width = 4052,
1064+ .height = 3040,
1065+ },
1066+ .timeperframe_min = {
1067+ .numerator = 100,
1068+ .denominator = 12000
1069+ },
1070+ .timeperframe_default = {
1071+ .numerator = 100,
1072+ .denominator = 60000
1073+ },
1074+ .reg_list = {
1075+ .num_of_regs = ARRAY_SIZE(mode_1012x760_regs),
1076+ .regs = mode_1012x760_regs,
1077+ }
1078+ }
1079+};
1080+
1081+/*
1082+ * The supported formats.
1083+ * This table MUST contain 4 entries per format, to cover the various flip
1084+ * combinations in the order
1085+ * - no flip
1086+ * - h flip
1087+ * - v flip
1088+ * - h&v flips
1089+ */
1090+static const u32 codes[] = {
1091+ /* 12-bit modes. */
1092+ MEDIA_BUS_FMT_SRGGB12_1X12,
1093+ MEDIA_BUS_FMT_SGRBG12_1X12,
1094+ MEDIA_BUS_FMT_SGBRG12_1X12,
1095+ MEDIA_BUS_FMT_SBGGR12_1X12,
1096+ /* 10-bit modes. */
1097+ MEDIA_BUS_FMT_SRGGB10_1X10,
1098+ MEDIA_BUS_FMT_SGRBG10_1X10,
1099+ MEDIA_BUS_FMT_SGBRG10_1X10,
1100+ MEDIA_BUS_FMT_SBGGR10_1X10,
1101+};
1102+
1103+static const char * const imx477_test_pattern_menu[] = {
1104+ "Disabled",
1105+ "Color Bars",
1106+ "Solid Color",
1107+ "Grey Color Bars",
1108+ "PN9"
1109+};
1110+
1111+static const int imx477_test_pattern_val[] = {
1112+ IMX477_TEST_PATTERN_DISABLE,
1113+ IMX477_TEST_PATTERN_COLOR_BARS,
1114+ IMX477_TEST_PATTERN_SOLID_COLOR,
1115+ IMX477_TEST_PATTERN_GREY_COLOR,
1116+ IMX477_TEST_PATTERN_PN9,
1117+};
1118+
1119+/* regulator supplies */
1120+static const char * const imx477_supply_name[] = {
1121+ /* Supplies can be enabled in any order */
1122+ "VANA", /* Analog (2.8V) supply */
1123+ "VDIG", /* Digital Core (1.05V) supply */
1124+ "VDDL", /* IF (1.8V) supply */
1125+};
1126+
1127+#define IMX477_NUM_SUPPLIES ARRAY_SIZE(imx477_supply_name)
1128+
1129+/*
1130+ * Initialisation delay between XCLR low->high and the moment when the sensor
1131+ * can start capture (i.e. can leave software standby), given by T7 in the
1132+ * datasheet is 8ms. This does include I2C setup time as well.
1133+ *
1134+ * Note, that delay between XCLR low->high and reading the CCI ID register (T6
1135+ * in the datasheet) is much smaller - 600us.
1136+ */
1137+#define IMX477_XCLR_MIN_DELAY_US 8000
1138+#define IMX477_XCLR_DELAY_RANGE_US 1000
1139+
1140+struct imx477 {
1141+ struct v4l2_subdev sd;
1142+ struct media_pad pad[NUM_PADS];
1143+
1144+ struct v4l2_mbus_framefmt fmt;
1145+
1146+ struct clk *xclk;
1147+ u32 xclk_freq;
1148+
1149+ struct gpio_desc *reset_gpio;
1150+ struct regulator_bulk_data supplies[IMX477_NUM_SUPPLIES];
1151+
1152+ struct v4l2_ctrl_handler ctrl_handler;
1153+ /* V4L2 Controls */
1154+ struct v4l2_ctrl *pixel_rate;
1155+ struct v4l2_ctrl *exposure;
1156+ struct v4l2_ctrl *vflip;
1157+ struct v4l2_ctrl *hflip;
1158+ struct v4l2_ctrl *vblank;
1159+ struct v4l2_ctrl *hblank;
1160+
1161+ /* Current mode */
1162+ const struct imx477_mode *mode;
1163+
1164+ /*
1165+ * Mutex for serialized access:
1166+ * Protect sensor module set pad format and start/stop streaming safely.
1167+ */
1168+ struct mutex mutex;
1169+
1170+ /* Streaming on/off */
1171+ bool streaming;
1172+
1173+ /* Rewrite common registers on stream on? */
1174+ bool common_regs_written;
1175+};
1176+
1177+static inline struct imx477 *to_imx477(struct v4l2_subdev *_sd)
1178+{
1179+ return container_of(_sd, struct imx477, sd);
1180+}
1181+
1182+static inline void get_mode_table(unsigned int code,
1183+ const struct imx477_mode **mode_list,
1184+ unsigned int *num_modes)
1185+{
1186+ switch (code) {
1187+ /* 12-bit */
1188+ case MEDIA_BUS_FMT_SRGGB12_1X12:
1189+ case MEDIA_BUS_FMT_SGRBG12_1X12:
1190+ case MEDIA_BUS_FMT_SGBRG12_1X12:
1191+ case MEDIA_BUS_FMT_SBGGR12_1X12:
1192+ *mode_list = supported_modes_12bit;
1193+ *num_modes = ARRAY_SIZE(supported_modes_12bit);
1194+ break;
1195+ /* 10-bit */
1196+ case MEDIA_BUS_FMT_SRGGB10_1X10:
1197+ case MEDIA_BUS_FMT_SGRBG10_1X10:
1198+ case MEDIA_BUS_FMT_SGBRG10_1X10:
1199+ case MEDIA_BUS_FMT_SBGGR10_1X10:
1200+ *mode_list = supported_modes_10bit;
1201+ *num_modes = ARRAY_SIZE(supported_modes_10bit);
1202+ break;
1203+ default:
1204+ *mode_list = NULL;
1205+ *num_modes = 0;
1206+ }
1207+}
1208+
1209+/* Read registers up to 2 at a time */
1210+static int imx477_read_reg(struct imx477 *imx477, u16 reg, u32 len, u32 *val)
1211+{
1212+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1213+ struct i2c_msg msgs[2];
1214+ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
1215+ u8 data_buf[4] = { 0, };
1216+ int ret;
1217+
1218+ if (len > 4)
1219+ return -EINVAL;
1220+
1221+ /* Write register address */
1222+ msgs[0].addr = client->addr;
1223+ msgs[0].flags = 0;
1224+ msgs[0].len = ARRAY_SIZE(addr_buf);
1225+ msgs[0].buf = addr_buf;
1226+
1227+ /* Read data from register */
1228+ msgs[1].addr = client->addr;
1229+ msgs[1].flags = I2C_M_RD;
1230+ msgs[1].len = len;
1231+ msgs[1].buf = &data_buf[4 - len];
1232+
1233+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1234+ if (ret != ARRAY_SIZE(msgs))
1235+ return -EIO;
1236+
1237+ *val = get_unaligned_be32(data_buf);
1238+
1239+ return 0;
1240+}
1241+
1242+/* Write registers up to 2 at a time */
1243+static int imx477_write_reg(struct imx477 *imx477, u16 reg, u32 len, u32 val)
1244+{
1245+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1246+ u8 buf[6];
1247+
1248+ if (len > 4)
1249+ return -EINVAL;
1250+
1251+ put_unaligned_be16(reg, buf);
1252+ put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1253+ if (i2c_master_send(client, buf, len + 2) != len + 2)
1254+ return -EIO;
1255+
1256+ return 0;
1257+}
1258+
1259+/* Write a list of registers */
1260+static int imx477_write_regs(struct imx477 *imx477,
1261+ const struct imx477_reg *regs, u32 len)
1262+{
1263+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1264+ unsigned int i;
1265+ int ret;
1266+
1267+ for (i = 0; i < len; i++) {
1268+ ret = imx477_write_reg(imx477, regs[i].address, 1, regs[i].val);
1269+ if (ret) {
1270+ dev_err_ratelimited(&client->dev,
1271+ "Failed to write reg 0x%4.4x. error = %d\n",
1272+ regs[i].address, ret);
1273+
1274+ return ret;
1275+ }
1276+ }
1277+
1278+ return 0;
1279+}
1280+
1281+/* Get bayer order based on flip setting. */
1282+static u32 imx477_get_format_code(struct imx477 *imx477, u32 code)
1283+{
1284+ unsigned int i;
1285+
1286+ lockdep_assert_held(&imx477->mutex);
1287+
1288+ for (i = 0; i < ARRAY_SIZE(codes); i++)
1289+ if (codes[i] == code)
1290+ break;
1291+
1292+ if (i >= ARRAY_SIZE(codes))
1293+ i = 0;
1294+
1295+ i = (i & ~3) | (imx477->vflip->val ? 2 : 0) |
1296+ (imx477->hflip->val ? 1 : 0);
1297+
1298+ return codes[i];
1299+}
1300+
1301+static void imx477_set_default_format(struct imx477 *imx477)
1302+{
1303+ struct v4l2_mbus_framefmt *fmt = &imx477->fmt;
1304+
1305+ /* Set default mode to max resolution */
1306+ imx477->mode = &supported_modes_12bit[0];
1307+
1308+ fmt->code = MEDIA_BUS_FMT_SRGGB12_1X12;
1309+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
1310+ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
1311+ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
1312+ fmt->colorspace,
1313+ fmt->ycbcr_enc);
1314+ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
1315+ fmt->width = imx477->mode->width;
1316+ fmt->height = imx477->mode->height;
1317+ fmt->field = V4L2_FIELD_NONE;
1318+}
1319+
1320+static int imx477_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1321+{
1322+ struct imx477 *imx477 = to_imx477(sd);
1323+ struct v4l2_mbus_framefmt *try_fmt_img =
1324+ v4l2_subdev_get_try_format(sd, fh->pad, IMAGE_PAD);
1325+ struct v4l2_mbus_framefmt *try_fmt_meta =
1326+ v4l2_subdev_get_try_format(sd, fh->pad, METADATA_PAD);
1327+ struct v4l2_rect *try_crop;
1328+
1329+ mutex_lock(&imx477->mutex);
1330+
1331+ /* Initialize try_fmt for the image pad */
1332+ try_fmt_img->width = supported_modes_12bit[0].width;
1333+ try_fmt_img->height = supported_modes_12bit[0].height;
1334+ try_fmt_img->code = imx477_get_format_code(imx477,
1335+ MEDIA_BUS_FMT_SRGGB12_1X12);
1336+ try_fmt_img->field = V4L2_FIELD_NONE;
1337+
1338+ /* Initialize try_fmt for the embedded metadata pad */
1339+ try_fmt_meta->width = IMX477_EMBEDDED_LINE_WIDTH;
1340+ try_fmt_meta->height = IMX477_NUM_EMBEDDED_LINES;
1341+ try_fmt_meta->code = MEDIA_BUS_FMT_SENSOR_DATA;
1342+ try_fmt_meta->field = V4L2_FIELD_NONE;
1343+
1344+ /* Initialize try_crop */
1345+ try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, IMAGE_PAD);
1346+ try_crop->left = IMX477_PIXEL_ARRAY_LEFT;
1347+ try_crop->top = IMX477_PIXEL_ARRAY_TOP;
1348+ try_crop->width = IMX477_PIXEL_ARRAY_WIDTH;
1349+ try_crop->height = IMX477_PIXEL_ARRAY_HEIGHT;
1350+
1351+ mutex_unlock(&imx477->mutex);
1352+
1353+ return 0;
1354+}
1355+
1356+static int imx477_set_ctrl(struct v4l2_ctrl *ctrl)
1357+{
1358+ struct imx477 *imx477 =
1359+ container_of(ctrl->handler, struct imx477, ctrl_handler);
1360+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1361+ int ret = 0;
1362+
1363+ if (ctrl->id == V4L2_CID_VBLANK) {
1364+ int exposure_max, exposure_def;
1365+
1366+ /* Update max exposure while meeting expected vblanking */
1367+ exposure_max = imx477->mode->height + ctrl->val -
1368+ IMX477_EXPOSURE_OFFSET;
1369+ exposure_def = min(exposure_max, imx477->exposure->val);
1370+ __v4l2_ctrl_modify_range(imx477->exposure,
1371+ imx477->exposure->minimum,
1372+ exposure_max, imx477->exposure->step,
1373+ exposure_def);
1374+ }
1375+
1376+ /*
1377+ * Applying V4L2 control value only happens
1378+ * when power is up for streaming
1379+ */
1380+ if (pm_runtime_get_if_in_use(&client->dev) == 0)
1381+ return 0;
1382+
1383+ switch (ctrl->id) {
1384+ case V4L2_CID_ANALOGUE_GAIN:
1385+ ret = imx477_write_reg(imx477, IMX477_REG_ANALOG_GAIN,
1386+ IMX477_REG_VALUE_16BIT, ctrl->val);
1387+ break;
1388+ case V4L2_CID_EXPOSURE:
1389+ ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE,
1390+ IMX477_REG_VALUE_16BIT, ctrl->val);
1391+ break;
1392+ case V4L2_CID_DIGITAL_GAIN:
1393+ ret = imx477_write_reg(imx477, IMX477_REG_DIGITAL_GAIN,
1394+ IMX477_REG_VALUE_16BIT, ctrl->val);
1395+ break;
1396+ case V4L2_CID_TEST_PATTERN:
1397+ ret = imx477_write_reg(imx477, IMX477_REG_TEST_PATTERN,
1398+ IMX477_REG_VALUE_16BIT,
1399+ imx477_test_pattern_val[ctrl->val]);
1400+ break;
1401+ case V4L2_CID_TEST_PATTERN_RED:
1402+ ret = imx477_write_reg(imx477, IMX477_REG_TEST_PATTERN_R,
1403+ IMX477_REG_VALUE_16BIT, ctrl->val);
1404+ break;
1405+ case V4L2_CID_TEST_PATTERN_GREENR:
1406+ ret = imx477_write_reg(imx477, IMX477_REG_TEST_PATTERN_GR,
1407+ IMX477_REG_VALUE_16BIT, ctrl->val);
1408+ break;
1409+ case V4L2_CID_TEST_PATTERN_BLUE:
1410+ ret = imx477_write_reg(imx477, IMX477_REG_TEST_PATTERN_B,
1411+ IMX477_REG_VALUE_16BIT, ctrl->val);
1412+ break;
1413+ case V4L2_CID_TEST_PATTERN_GREENB:
1414+ ret = imx477_write_reg(imx477, IMX477_REG_TEST_PATTERN_GB,
1415+ IMX477_REG_VALUE_16BIT, ctrl->val);
1416+ break;
1417+ case V4L2_CID_HFLIP:
1418+ case V4L2_CID_VFLIP:
1419+ ret = imx477_write_reg(imx477, IMX477_REG_ORIENTATION, 1,
1420+ imx477->hflip->val |
1421+ imx477->vflip->val << 1);
1422+ break;
1423+ case V4L2_CID_VBLANK:
1424+ ret = imx477_write_reg(imx477, IMX477_REG_FRAME_LENGTH,
1425+ IMX477_REG_VALUE_16BIT,
1426+ imx477->mode->height + ctrl->val);
1427+ break;
1428+ default:
1429+ dev_info(&client->dev,
1430+ "ctrl(id:0x%x,val:0x%x) is not handled\n",
1431+ ctrl->id, ctrl->val);
1432+ ret = -EINVAL;
1433+ break;
1434+ }
1435+
1436+ pm_runtime_put(&client->dev);
1437+
1438+ return ret;
1439+}
1440+
1441+static const struct v4l2_ctrl_ops imx477_ctrl_ops = {
1442+ .s_ctrl = imx477_set_ctrl,
1443+};
1444+
1445+static int imx477_enum_mbus_code(struct v4l2_subdev *sd,
1446+ struct v4l2_subdev_pad_config *cfg,
1447+ struct v4l2_subdev_mbus_code_enum *code)
1448+{
1449+ struct imx477 *imx477 = to_imx477(sd);
1450+
1451+ if (code->pad >= NUM_PADS)
1452+ return -EINVAL;
1453+
1454+ if (code->pad == IMAGE_PAD) {
1455+ if (code->index >= (ARRAY_SIZE(codes) / 4))
1456+ return -EINVAL;
1457+
1458+ code->code = imx477_get_format_code(imx477,
1459+ codes[code->index * 4]);
1460+ } else {
1461+ if (code->index > 0)
1462+ return -EINVAL;
1463+
1464+ code->code = MEDIA_BUS_FMT_SENSOR_DATA;
1465+ }
1466+
1467+ return 0;
1468+}
1469+
1470+static int imx477_enum_frame_size(struct v4l2_subdev *sd,
1471+ struct v4l2_subdev_pad_config *cfg,
1472+ struct v4l2_subdev_frame_size_enum *fse)
1473+{
1474+ struct imx477 *imx477 = to_imx477(sd);
1475+
1476+ if (fse->pad >= NUM_PADS)
1477+ return -EINVAL;
1478+
1479+ if (fse->pad == IMAGE_PAD) {
1480+ const struct imx477_mode *mode_list;
1481+ unsigned int num_modes;
1482+
1483+ get_mode_table(fse->code, &mode_list, &num_modes);
1484+
1485+ if (fse->index >= num_modes)
1486+ return -EINVAL;
1487+
1488+ if (fse->code != imx477_get_format_code(imx477, fse->code))
1489+ return -EINVAL;
1490+
1491+ fse->min_width = mode_list[fse->index].width;
1492+ fse->max_width = fse->min_width;
1493+ fse->min_height = mode_list[fse->index].height;
1494+ fse->max_height = fse->min_height;
1495+ } else {
1496+ if (fse->code != MEDIA_BUS_FMT_SENSOR_DATA || fse->index > 0)
1497+ return -EINVAL;
1498+
1499+ fse->min_width = IMX477_EMBEDDED_LINE_WIDTH;
1500+ fse->max_width = fse->min_width;
1501+ fse->min_height = IMX477_NUM_EMBEDDED_LINES;
1502+ fse->max_height = fse->min_height;
1503+ }
1504+
1505+ return 0;
1506+}
1507+
1508+static void imx477_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
1509+{
1510+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
1511+ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
1512+ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
1513+ fmt->colorspace,
1514+ fmt->ycbcr_enc);
1515+ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
1516+}
1517+
1518+static void imx477_update_image_pad_format(struct imx477 *imx477,
1519+ const struct imx477_mode *mode,
1520+ struct v4l2_subdev_format *fmt)
1521+{
1522+ fmt->format.width = mode->width;
1523+ fmt->format.height = mode->height;
1524+ fmt->format.field = V4L2_FIELD_NONE;
1525+ imx477_reset_colorspace(&fmt->format);
1526+}
1527+
1528+static void imx477_update_metadata_pad_format(struct v4l2_subdev_format *fmt)
1529+{
1530+ fmt->format.width = IMX477_EMBEDDED_LINE_WIDTH;
1531+ fmt->format.height = IMX477_NUM_EMBEDDED_LINES;
1532+ fmt->format.code = MEDIA_BUS_FMT_SENSOR_DATA;
1533+ fmt->format.field = V4L2_FIELD_NONE;
1534+}
1535+
1536+static int imx477_get_pad_format(struct v4l2_subdev *sd,
1537+ struct v4l2_subdev_pad_config *cfg,
1538+ struct v4l2_subdev_format *fmt)
1539+{
1540+ struct imx477 *imx477 = to_imx477(sd);
1541+
1542+ if (fmt->pad >= NUM_PADS)
1543+ return -EINVAL;
1544+
1545+ mutex_lock(&imx477->mutex);
1546+
1547+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1548+ struct v4l2_mbus_framefmt *try_fmt =
1549+ v4l2_subdev_get_try_format(&imx477->sd, cfg, fmt->pad);
1550+ /* update the code which could change due to vflip or hflip: */
1551+ try_fmt->code = fmt->pad == IMAGE_PAD ?
1552+ imx477_get_format_code(imx477, try_fmt->code) :
1553+ MEDIA_BUS_FMT_SENSOR_DATA;
1554+ fmt->format = *try_fmt;
1555+ } else {
1556+ if (fmt->pad == IMAGE_PAD) {
1557+ imx477_update_image_pad_format(imx477, imx477->mode,
1558+ fmt);
1559+ fmt->format.code =
1560+ imx477_get_format_code(imx477, imx477->fmt.code);
1561+ } else {
1562+ imx477_update_metadata_pad_format(fmt);
1563+ }
1564+ }
1565+
1566+ mutex_unlock(&imx477->mutex);
1567+ return 0;
1568+}
1569+
1570+static
1571+unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
1572+ const struct v4l2_fract *timeperframe)
1573+{
1574+ u64 frame_length;
1575+
1576+ frame_length = (u64)timeperframe->numerator * IMX477_PIXEL_RATE;
1577+ do_div(frame_length,
1578+ (u64)timeperframe->denominator * mode->line_length_pix);
1579+
1580+ if (WARN_ON(frame_length > IMX477_FRAME_LENGTH_MAX))
1581+ frame_length = IMX477_FRAME_LENGTH_MAX;
1582+
1583+ return max_t(unsigned int, frame_length, mode->height);
1584+}
1585+
1586+static void imx477_set_framing_limits(struct imx477 *imx477)
1587+{
1588+ const struct imx477_mode *mode = imx477->mode;
1589+ unsigned int frm_length_min, frm_length_default;
1590+ unsigned int exposure_max, exposure_def, hblank;
1591+
1592+ frm_length_min = imx477_get_frame_length(mode, &mode->timeperframe_min);
1593+ frm_length_default =
1594+ imx477_get_frame_length(mode, &mode->timeperframe_default);
1595+
1596+ /* Update limits and set FPS to default */
1597+ __v4l2_ctrl_modify_range(imx477->vblank, frm_length_min - mode->height,
1598+ IMX477_FRAME_LENGTH_MAX - mode->height,
1599+ 1, frm_length_default - mode->height);
1600+ __v4l2_ctrl_s_ctrl(imx477->vblank, frm_length_default - mode->height);
1601+
1602+ /* Update max exposure while meeting expected vblanking */
1603+ exposure_max = IMX477_FRAME_LENGTH_MAX - IMX477_EXPOSURE_OFFSET;
1604+ exposure_def = frm_length_default - mode->height -
1605+ IMX477_EXPOSURE_OFFSET;
1606+ __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum,
1607+ exposure_max, imx477->exposure->step,
1608+ exposure_def);
1609+ /*
1610+ * Currently PPL is fixed to the mode specified value, so hblank
1611+ * depends on mode->width only, and is not changeable in any
1612+ * way other than changing the mode.
1613+ */
1614+ hblank = mode->line_length_pix - mode->width;
1615+ __v4l2_ctrl_modify_range(imx477->hblank, hblank, hblank, 1, hblank);
1616+}
1617+
1618+static int imx477_set_pad_format(struct v4l2_subdev *sd,
1619+ struct v4l2_subdev_pad_config *cfg,
1620+ struct v4l2_subdev_format *fmt)
1621+{
1622+ struct v4l2_mbus_framefmt *framefmt;
1623+ const struct imx477_mode *mode;
1624+ struct imx477 *imx477 = to_imx477(sd);
1625+
1626+ if (fmt->pad >= NUM_PADS)
1627+ return -EINVAL;
1628+
1629+ mutex_lock(&imx477->mutex);
1630+
1631+ if (fmt->pad == IMAGE_PAD) {
1632+ const struct imx477_mode *mode_list;
1633+ unsigned int num_modes;
1634+
1635+ /* Bayer order varies with flips */
1636+ fmt->format.code = imx477_get_format_code(imx477,
1637+ fmt->format.code);
1638+
1639+ get_mode_table(fmt->format.code, &mode_list, &num_modes);
1640+
1641+ mode = v4l2_find_nearest_size(mode_list,
1642+ num_modes,
1643+ width, height,
1644+ fmt->format.width,
1645+ fmt->format.height);
1646+ imx477_update_image_pad_format(imx477, mode, fmt);
1647+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1648+ framefmt = v4l2_subdev_get_try_format(sd, cfg,
1649+ fmt->pad);
1650+ *framefmt = fmt->format;
1651+ } else {
1652+ imx477->mode = mode;
1653+ imx477_set_framing_limits(imx477);
1654+ }
1655+ } else {
1656+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1657+ framefmt = v4l2_subdev_get_try_format(sd, cfg,
1658+ fmt->pad);
1659+ *framefmt = fmt->format;
1660+ } else {
1661+ /* Only one embedded data mode is supported */
1662+ imx477_update_metadata_pad_format(fmt);
1663+ }
1664+ }
1665+
1666+ mutex_unlock(&imx477->mutex);
1667+
1668+ return 0;
1669+}
1670+
1671+static const struct v4l2_rect *
1672+__imx477_get_pad_crop(struct imx477 *imx477, struct v4l2_subdev_pad_config *cfg,
1673+ unsigned int pad, enum v4l2_subdev_format_whence which)
1674+{
1675+ switch (which) {
1676+ case V4L2_SUBDEV_FORMAT_TRY:
1677+ return v4l2_subdev_get_try_crop(&imx477->sd, cfg, pad);
1678+ case V4L2_SUBDEV_FORMAT_ACTIVE:
1679+ return &imx477->mode->crop;
1680+ }
1681+
1682+ return NULL;
1683+}
1684+
1685+static int imx477_get_selection(struct v4l2_subdev *sd,
1686+ struct v4l2_subdev_pad_config *cfg,
1687+ struct v4l2_subdev_selection *sel)
1688+{
1689+ switch (sel->target) {
1690+ case V4L2_SEL_TGT_CROP: {
1691+ struct imx477 *imx477 = to_imx477(sd);
1692+
1693+ mutex_lock(&imx477->mutex);
1694+ sel->r = *__imx477_get_pad_crop(imx477, cfg, sel->pad,
1695+ sel->which);
1696+ mutex_unlock(&imx477->mutex);
1697+
1698+ return 0;
1699+ }
1700+
1701+ case V4L2_SEL_TGT_NATIVE_SIZE:
1702+ sel->r.left = 0;
1703+ sel->r.top = 0;
1704+ sel->r.width = IMX477_NATIVE_WIDTH;
1705+ sel->r.height = IMX477_NATIVE_HEIGHT;
1706+
1707+ return 0;
1708+
1709+ case V4L2_SEL_TGT_CROP_DEFAULT:
1710+ sel->r.left = IMX477_PIXEL_ARRAY_LEFT;
1711+ sel->r.top = IMX477_PIXEL_ARRAY_TOP;
1712+ sel->r.width = IMX477_PIXEL_ARRAY_WIDTH;
1713+ sel->r.height = IMX477_PIXEL_ARRAY_HEIGHT;
1714+
1715+ return 0;
1716+ }
1717+
1718+ return -EINVAL;
1719+}
1720+
1721+/* Start streaming */
1722+static int imx477_start_streaming(struct imx477 *imx477)
1723+{
1724+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1725+ const struct imx477_reg_list *reg_list;
1726+ int ret;
1727+
1728+ if (!imx477->common_regs_written) {
1729+ ret = imx477_write_regs(imx477, mode_common_regs,
1730+ ARRAY_SIZE(mode_common_regs));
1731+ if (ret) {
1732+ dev_err(&client->dev, "%s failed to set common settings\n",
1733+ __func__);
1734+ return ret;
1735+ }
1736+ imx477->common_regs_written = true;
1737+ }
1738+
1739+ /* Apply default values of current mode */
1740+ reg_list = &imx477->mode->reg_list;
1741+ ret = imx477_write_regs(imx477, reg_list->regs, reg_list->num_of_regs);
1742+ if (ret) {
1743+ dev_err(&client->dev, "%s failed to set mode\n", __func__);
1744+ return ret;
1745+ }
1746+
1747+ /* Apply customized values from user */
1748+ ret = __v4l2_ctrl_handler_setup(imx477->sd.ctrl_handler);
1749+ if (ret)
1750+ return ret;
1751+
1752+ /* set stream on register */
1753+ return imx477_write_reg(imx477, IMX477_REG_MODE_SELECT,
1754+ IMX477_REG_VALUE_08BIT, IMX477_MODE_STREAMING);
1755+}
1756+
1757+/* Stop streaming */
1758+static void imx477_stop_streaming(struct imx477 *imx477)
1759+{
1760+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1761+ int ret;
1762+
1763+ /* set stream off register */
1764+ ret = imx477_write_reg(imx477, IMX477_REG_MODE_SELECT,
1765+ IMX477_REG_VALUE_08BIT, IMX477_MODE_STANDBY);
1766+ if (ret)
1767+ dev_err(&client->dev, "%s failed to set stream\n", __func__);
1768+}
1769+
1770+static int imx477_set_stream(struct v4l2_subdev *sd, int enable)
1771+{
1772+ struct imx477 *imx477 = to_imx477(sd);
1773+ struct i2c_client *client = v4l2_get_subdevdata(sd);
1774+ int ret = 0;
1775+
1776+ mutex_lock(&imx477->mutex);
1777+ if (imx477->streaming == enable) {
1778+ mutex_unlock(&imx477->mutex);
1779+ return 0;
1780+ }
1781+
1782+ if (enable) {
1783+ ret = pm_runtime_get_sync(&client->dev);
1784+ if (ret < 0) {
1785+ pm_runtime_put_noidle(&client->dev);
1786+ goto err_unlock;
1787+ }
1788+
1789+ /*
1790+ * Apply default & customized values
1791+ * and then start streaming.
1792+ */
1793+ ret = imx477_start_streaming(imx477);
1794+ if (ret)
1795+ goto err_rpm_put;
1796+ } else {
1797+ imx477_stop_streaming(imx477);
1798+ pm_runtime_put(&client->dev);
1799+ }
1800+
1801+ imx477->streaming = enable;
1802+
1803+ /* vflip and hflip cannot change during streaming */
1804+ __v4l2_ctrl_grab(imx477->vflip, enable);
1805+ __v4l2_ctrl_grab(imx477->hflip, enable);
1806+
1807+ mutex_unlock(&imx477->mutex);
1808+
1809+ return ret;
1810+
1811+err_rpm_put:
1812+ pm_runtime_put(&client->dev);
1813+err_unlock:
1814+ mutex_unlock(&imx477->mutex);
1815+
1816+ return ret;
1817+}
1818+
1819+/* Power/clock management functions */
1820+static int imx477_power_on(struct device *dev)
1821+{
1822+ struct i2c_client *client = to_i2c_client(dev);
1823+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1824+ struct imx477 *imx477 = to_imx477(sd);
1825+ int ret;
1826+
1827+ ret = regulator_bulk_enable(IMX477_NUM_SUPPLIES,
1828+ imx477->supplies);
1829+ if (ret) {
1830+ dev_err(&client->dev, "%s: failed to enable regulators\n",
1831+ __func__);
1832+ return ret;
1833+ }
1834+
1835+ ret = clk_prepare_enable(imx477->xclk);
1836+ if (ret) {
1837+ dev_err(&client->dev, "%s: failed to enable clock\n",
1838+ __func__);
1839+ goto reg_off;
1840+ }
1841+
1842+ gpiod_set_value_cansleep(imx477->reset_gpio, 1);
1843+ usleep_range(IMX477_XCLR_MIN_DELAY_US,
1844+ IMX477_XCLR_MIN_DELAY_US + IMX477_XCLR_DELAY_RANGE_US);
1845+
1846+ return 0;
1847+
1848+reg_off:
1849+ regulator_bulk_disable(IMX477_NUM_SUPPLIES, imx477->supplies);
1850+ return ret;
1851+}
1852+
1853+static int imx477_power_off(struct device *dev)
1854+{
1855+ struct i2c_client *client = to_i2c_client(dev);
1856+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1857+ struct imx477 *imx477 = to_imx477(sd);
1858+
1859+ gpiod_set_value_cansleep(imx477->reset_gpio, 0);
1860+ regulator_bulk_disable(IMX477_NUM_SUPPLIES, imx477->supplies);
1861+ clk_disable_unprepare(imx477->xclk);
1862+
1863+ /* Force reprogramming of the common registers when powered up again. */
1864+ imx477->common_regs_written = false;
1865+
1866+ return 0;
1867+}
1868+
1869+static int __maybe_unused imx477_suspend(struct device *dev)
1870+{
1871+ struct i2c_client *client = to_i2c_client(dev);
1872+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1873+ struct imx477 *imx477 = to_imx477(sd);
1874+
1875+ if (imx477->streaming)
1876+ imx477_stop_streaming(imx477);
1877+
1878+ return 0;
1879+}
1880+
1881+static int __maybe_unused imx477_resume(struct device *dev)
1882+{
1883+ struct i2c_client *client = to_i2c_client(dev);
1884+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1885+ struct imx477 *imx477 = to_imx477(sd);
1886+ int ret;
1887+
1888+ if (imx477->streaming) {
1889+ ret = imx477_start_streaming(imx477);
1890+ if (ret)
1891+ goto error;
1892+ }
1893+
1894+ return 0;
1895+
1896+error:
1897+ imx477_stop_streaming(imx477);
1898+ imx477->streaming = 0;
1899+ return ret;
1900+}
1901+
1902+static int imx477_get_regulators(struct imx477 *imx477)
1903+{
1904+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1905+ unsigned int i;
1906+
1907+ for (i = 0; i < IMX477_NUM_SUPPLIES; i++)
1908+ imx477->supplies[i].supply = imx477_supply_name[i];
1909+
1910+ return devm_regulator_bulk_get(&client->dev,
1911+ IMX477_NUM_SUPPLIES,
1912+ imx477->supplies);
1913+}
1914+
1915+/* Verify chip ID */
1916+static int imx477_identify_module(struct imx477 *imx477)
1917+{
1918+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1919+ int ret;
1920+ u32 val;
1921+
1922+ ret = imx477_read_reg(imx477, IMX477_REG_CHIP_ID,
1923+ IMX477_REG_VALUE_16BIT, &val);
1924+ if (ret) {
1925+ dev_err(&client->dev, "failed to read chip id %x, with error %d\n",
1926+ IMX477_CHIP_ID, ret);
1927+ return ret;
1928+ }
1929+
1930+ if (val != IMX477_CHIP_ID) {
1931+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1932+ IMX477_CHIP_ID, val);
1933+ ret = -EINVAL;
1934+ }
1935+
1936+ return 0;
1937+}
1938+
1939+static const struct v4l2_subdev_core_ops imx477_core_ops = {
1940+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1941+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1942+};
1943+
1944+static const struct v4l2_subdev_video_ops imx477_video_ops = {
1945+ .s_stream = imx477_set_stream,
1946+};
1947+
1948+static const struct v4l2_subdev_pad_ops imx477_pad_ops = {
1949+ .enum_mbus_code = imx477_enum_mbus_code,
1950+ .get_fmt = imx477_get_pad_format,
1951+ .set_fmt = imx477_set_pad_format,
1952+ .get_selection = imx477_get_selection,
1953+ .enum_frame_size = imx477_enum_frame_size,
1954+};
1955+
1956+static const struct v4l2_subdev_ops imx477_subdev_ops = {
1957+ .core = &imx477_core_ops,
1958+ .video = &imx477_video_ops,
1959+ .pad = &imx477_pad_ops,
1960+};
1961+
1962+static const struct v4l2_subdev_internal_ops imx477_internal_ops = {
1963+ .open = imx477_open,
1964+};
1965+
1966+/* Initialize control handlers */
1967+static int imx477_init_controls(struct imx477 *imx477)
1968+{
1969+ struct v4l2_ctrl_handler *ctrl_hdlr;
1970+ struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd);
1971+ unsigned int i;
1972+ int ret;
1973+
1974+ ctrl_hdlr = &imx477->ctrl_handler;
1975+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 14);
1976+ if (ret)
1977+ return ret;
1978+
1979+ mutex_init(&imx477->mutex);
1980+ ctrl_hdlr->lock = &imx477->mutex;
1981+
1982+ /* By default, PIXEL_RATE is read only */
1983+ imx477->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
1984+ V4L2_CID_PIXEL_RATE,
1985+ IMX477_PIXEL_RATE,
1986+ IMX477_PIXEL_RATE, 1,
1987+ IMX477_PIXEL_RATE);
1988+
1989+ /*
1990+ * Create the controls here, but mode specific limits are setup
1991+ * in the imx477_set_framing_limits() call below.
1992+ */
1993+ imx477->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
1994+ V4L2_CID_VBLANK, 0, 0xffff, 1, 0);
1995+ imx477->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
1996+ V4L2_CID_HBLANK, 0, 0xffff, 1, 0);
1997+
1998+ /* HBLANK is read-only for now, but does change with mode. */
1999+ if (imx477->hblank)
2000+ imx477->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2001+
2002+ imx477->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
2003+ V4L2_CID_EXPOSURE,
2004+ IMX477_EXPOSURE_MIN,
2005+ IMX477_EXPOSURE_MAX,
2006+ IMX477_EXPOSURE_STEP,
2007+ IMX477_EXPOSURE_DEFAULT);
2008+
2009+ v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
2010+ IMX477_ANA_GAIN_MIN, IMX477_ANA_GAIN_MAX,
2011+ IMX477_ANA_GAIN_STEP, IMX477_ANA_GAIN_DEFAULT);
2012+
2013+ v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
2014+ IMX477_DGTL_GAIN_MIN, IMX477_DGTL_GAIN_MAX,
2015+ IMX477_DGTL_GAIN_STEP, IMX477_DGTL_GAIN_DEFAULT);
2016+
2017+ imx477->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
2018+ V4L2_CID_HFLIP, 0, 1, 1, 0);
2019+ if (imx477->hflip)
2020+ imx477->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
2021+
2022+ imx477->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
2023+ V4L2_CID_VFLIP, 0, 1, 1, 0);
2024+ if (imx477->vflip)
2025+ imx477->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
2026+
2027+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx477_ctrl_ops,
2028+ V4L2_CID_TEST_PATTERN,
2029+ ARRAY_SIZE(imx477_test_pattern_menu) - 1,
2030+ 0, 0, imx477_test_pattern_menu);
2031+ for (i = 0; i < 4; i++) {
2032+ /*
2033+ * The assumption is that
2034+ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
2035+ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
2036+ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
2037+ */
2038+ v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops,
2039+ V4L2_CID_TEST_PATTERN_RED + i,
2040+ IMX477_TEST_PATTERN_COLOUR_MIN,
2041+ IMX477_TEST_PATTERN_COLOUR_MAX,
2042+ IMX477_TEST_PATTERN_COLOUR_STEP,
2043+ IMX477_TEST_PATTERN_COLOUR_MAX);
2044+ /* The "Solid color" pattern is white by default */
2045+ }
2046+
2047+ if (ctrl_hdlr->error) {
2048+ ret = ctrl_hdlr->error;
2049+ dev_err(&client->dev, "%s control init failed (%d)\n",
2050+ __func__, ret);
2051+ goto error;
2052+ }
2053+
2054+ imx477->sd.ctrl_handler = ctrl_hdlr;
2055+
2056+ /* Setup exposure and frame/line length limits. */
2057+ imx477_set_framing_limits(imx477);
2058+
2059+ return 0;
2060+
2061+error:
2062+ v4l2_ctrl_handler_free(ctrl_hdlr);
2063+ mutex_destroy(&imx477->mutex);
2064+
2065+ return ret;
2066+}
2067+
2068+static void imx477_free_controls(struct imx477 *imx477)
2069+{
2070+ v4l2_ctrl_handler_free(imx477->sd.ctrl_handler);
2071+ mutex_destroy(&imx477->mutex);
2072+}
2073+
2074+static int imx477_check_hwcfg(struct device *dev)
2075+{
2076+ struct fwnode_handle *endpoint;
2077+ struct v4l2_fwnode_endpoint ep_cfg = {
2078+ .bus_type = V4L2_MBUS_CSI2_DPHY
2079+ };
2080+ int ret = -EINVAL;
2081+
2082+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
2083+ if (!endpoint) {
2084+ dev_err(dev, "endpoint node not found\n");
2085+ return -EINVAL;
2086+ }
2087+
2088+ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
2089+ dev_err(dev, "could not parse endpoint\n");
2090+ goto error_out;
2091+ }
2092+
2093+ /* Check the number of MIPI CSI2 data lanes */
2094+ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
2095+ dev_err(dev, "only 2 data lanes are currently supported\n");
2096+ goto error_out;
2097+ }
2098+
2099+ /* Check the link frequency set in device tree */
2100+ if (!ep_cfg.nr_of_link_frequencies) {
2101+ dev_err(dev, "link-frequency property not found in DT\n");
2102+ goto error_out;
2103+ }
2104+
2105+ if (ep_cfg.nr_of_link_frequencies != 1 ||
2106+ ep_cfg.link_frequencies[0] != IMX477_DEFAULT_LINK_FREQ) {
2107+ dev_err(dev, "Link frequency not supported: %lld\n",
2108+ ep_cfg.link_frequencies[0]);
2109+ goto error_out;
2110+ }
2111+
2112+ ret = 0;
2113+
2114+error_out:
2115+ v4l2_fwnode_endpoint_free(&ep_cfg);
2116+ fwnode_handle_put(endpoint);
2117+
2118+ return ret;
2119+}
2120+
2121+static int imx477_probe(struct i2c_client *client)
2122+{
2123+ struct device *dev = &client->dev;
2124+ struct imx477 *imx477;
2125+ int ret;
2126+
2127+ imx477 = devm_kzalloc(&client->dev, sizeof(*imx477), GFP_KERNEL);
2128+ if (!imx477)
2129+ return -ENOMEM;
2130+
2131+ v4l2_i2c_subdev_init(&imx477->sd, client, &imx477_subdev_ops);
2132+
2133+ /* Check the hardware configuration in device tree */
2134+ if (imx477_check_hwcfg(dev))
2135+ return -EINVAL;
2136+
2137+ /* Get system clock (xclk) */
2138+ imx477->xclk = devm_clk_get(dev, NULL);
2139+ if (IS_ERR(imx477->xclk)) {
2140+ dev_err(dev, "failed to get xclk\n");
2141+ return PTR_ERR(imx477->xclk);
2142+ }
2143+
2144+ imx477->xclk_freq = clk_get_rate(imx477->xclk);
2145+ if (imx477->xclk_freq != IMX477_XCLK_FREQ) {
2146+ dev_err(dev, "xclk frequency not supported: %d Hz\n",
2147+ imx477->xclk_freq);
2148+ return -EINVAL;
2149+ }
2150+
2151+ ret = imx477_get_regulators(imx477);
2152+ if (ret) {
2153+ dev_err(dev, "failed to get regulators\n");
2154+ return ret;
2155+ }
2156+
2157+ /* Request optional enable pin */
2158+ imx477->reset_gpio = devm_gpiod_get_optional(dev, "reset",
2159+ GPIOD_OUT_HIGH);
2160+
2161+ /*
2162+ * The sensor must be powered for imx477_identify_module()
2163+ * to be able to read the CHIP_ID register
2164+ */
2165+ ret = imx477_power_on(dev);
2166+ if (ret)
2167+ return ret;
2168+
2169+ ret = imx477_identify_module(imx477);
2170+ if (ret)
2171+ goto error_power_off;
2172+
2173+ /* Initialize default format */
2174+ imx477_set_default_format(imx477);
2175+
2176+ /* Enable runtime PM and turn off the device */
2177+ pm_runtime_set_active(dev);
2178+ pm_runtime_enable(dev);
2179+ pm_runtime_idle(dev);
2180+
2181+ /* This needs the pm runtime to be registered. */
2182+ ret = imx477_init_controls(imx477);
2183+ if (ret)
2184+ goto error_power_off;
2185+
2186+ /* Initialize subdev */
2187+ imx477->sd.internal_ops = &imx477_internal_ops;
2188+ imx477->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
2189+ V4L2_SUBDEV_FL_HAS_EVENTS;
2190+ imx477->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
2191+
2192+ /* Initialize source pads */
2193+ imx477->pad[IMAGE_PAD].flags = MEDIA_PAD_FL_SOURCE;
2194+ imx477->pad[METADATA_PAD].flags = MEDIA_PAD_FL_SOURCE;
2195+
2196+ ret = media_entity_pads_init(&imx477->sd.entity, NUM_PADS, imx477->pad);
2197+ if (ret) {
2198+ dev_err(dev, "failed to init entity pads: %d\n", ret);
2199+ goto error_handler_free;
2200+ }
2201+
2202+ ret = v4l2_async_register_subdev_sensor_common(&imx477->sd);
2203+ if (ret < 0) {
2204+ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
2205+ goto error_media_entity;
2206+ }
2207+
2208+ return 0;
2209+
2210+error_media_entity:
2211+ media_entity_cleanup(&imx477->sd.entity);
2212+
2213+error_handler_free:
2214+ imx477_free_controls(imx477);
2215+
2216+error_power_off:
2217+ pm_runtime_disable(&client->dev);
2218+ pm_runtime_set_suspended(&client->dev);
2219+ imx477_power_off(&client->dev);
2220+
2221+ return ret;
2222+}
2223+
2224+static int imx477_remove(struct i2c_client *client)
2225+{
2226+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
2227+ struct imx477 *imx477 = to_imx477(sd);
2228+
2229+ v4l2_async_unregister_subdev(sd);
2230+ media_entity_cleanup(&sd->entity);
2231+ imx477_free_controls(imx477);
2232+
2233+ pm_runtime_disable(&client->dev);
2234+ if (!pm_runtime_status_suspended(&client->dev))
2235+ imx477_power_off(&client->dev);
2236+ pm_runtime_set_suspended(&client->dev);
2237+
2238+ return 0;
2239+}
2240+
2241+static const struct of_device_id imx477_dt_ids[] = {
2242+ { .compatible = "sony,imx477" },
2243+ { /* sentinel */ }
2244+};
2245+MODULE_DEVICE_TABLE(of, imx477_dt_ids);
2246+
2247+static const struct dev_pm_ops imx477_pm_ops = {
2248+ SET_SYSTEM_SLEEP_PM_OPS(imx477_suspend, imx477_resume)
2249+ SET_RUNTIME_PM_OPS(imx477_power_off, imx477_power_on, NULL)
2250+};
2251+
2252+static struct i2c_driver imx477_i2c_driver = {
2253+ .driver = {
2254+ .name = "imx477",
2255+ .of_match_table = imx477_dt_ids,
2256+ .pm = &imx477_pm_ops,
2257+ },
2258+ .probe_new = imx477_probe,
2259+ .remove = imx477_remove,
2260+};
2261+
2262+module_i2c_driver(imx477_i2c_driver);
2263+
2264+MODULE_AUTHOR("Naushir Patuck <naush@raspberrypi.com>");
2265+MODULE_DESCRIPTION("Sony IMX477 sensor driver");
2266+MODULE_LICENSE("GPL v2");