xref: /linux/drivers/media/i2c/vd55g1.c (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for VD55G1 global shutter sensor family driver
4  *
5  * Copyright (C) 2025 STMicroelectronics SA
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/delay.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/i2c.h>
12 #include <linux/iopoll.h>
13 #include <linux/module.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/property.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/unaligned.h>
19 #include <linux/units.h>
20 
21 #include <media/mipi-csi2.h>
22 #include <media/v4l2-async.h>
23 #include <media/v4l2-cci.h>
24 #include <media/v4l2-ctrls.h>
25 #include <media/v4l2-device.h>
26 #include <media/v4l2-event.h>
27 #include <media/v4l2-fwnode.h>
28 #include <media/v4l2-subdev.h>
29 
30 /* Register Map */
31 #define VD55G1_REG_MODEL_ID				CCI_REG32_LE(0x0000)
32 #define VD55G1_MODEL_ID_VD55G1				0x53354731 /* Mono */
33 #define VD55G1_MODEL_ID_VD65G4				0x53354733 /* RGB */
34 #define VD55G1_REG_REVISION				CCI_REG16_LE(0x0004)
35 #define VD55G1_REVISION_CCB				0x2020
36 #define VD55G1_REVISION_BAYER				0x3030
37 #define VD55G1_REG_FWPATCH_REVISION			CCI_REG16_LE(0x0012)
38 #define VD55G1_REG_FWPATCH_START_ADDR			CCI_REG8(0x2000)
39 #define VD55G1_REG_SYSTEM_FSM				CCI_REG8(0x001c)
40 #define VD55G1_SYSTEM_FSM_READY_TO_BOOT			0x01
41 #define VD55G1_SYSTEM_FSM_SW_STBY			0x02
42 #define VD55G1_SYSTEM_FSM_STREAMING			0x03
43 #define VD55G1_REG_BOOT					CCI_REG8(0x0200)
44 #define VD55G1_BOOT_BOOT				1
45 #define VD55G1_BOOT_PATCH_AND_BOOT			2
46 #define VD55G1_REG_STBY					CCI_REG8(0x0201)
47 #define VD55G1_STBY_START_STREAM			1
48 #define VD55G1_REG_STREAMING				CCI_REG8(0x0202)
49 #define VD55G1_STREAMING_STOP_STREAM			1
50 #define VD55G1_REG_EXT_CLOCK				CCI_REG32_LE(0x0220)
51 #define VD55G1_REG_LINE_LENGTH				CCI_REG16_LE(0x0300)
52 #define VD55G1_REG_ORIENTATION				CCI_REG8(0x0302)
53 #define VD55G1_REG_FORMAT_CTRL				CCI_REG8(0x030a)
54 #define VD55G1_REG_OIF_CTRL				CCI_REG16_LE(0x030c)
55 #define VD55G1_REG_ISL_ENABLE				CCI_REG16_LE(0x326)
56 #define VD55G1_REG_OIF_IMG_CTRL				CCI_REG8(0x030f)
57 #define VD55G1_REG_MIPI_DATA_RATE			CCI_REG32_LE(0x0224)
58 #define VD55G1_REG_PATGEN_CTRL				CCI_REG16_LE(0x0304)
59 #define VD55G1_PATGEN_TYPE_SHIFT			4
60 #define VD55G1_PATGEN_ENABLE				BIT(0)
61 #define VD55G1_REG_MANUAL_ANALOG_GAIN			CCI_REG8(0x0501)
62 #define VD55G1_REG_MANUAL_COARSE_EXPOSURE		CCI_REG16_LE(0x0502)
63 #define VD55G1_REG_MANUAL_DIGITAL_GAIN			CCI_REG16_LE(0x0504)
64 #define VD55G1_REG_APPLIED_COARSE_EXPOSURE		CCI_REG16_LE(0x00e8)
65 #define VD55G1_REG_APPLIED_ANALOG_GAIN			CCI_REG16_LE(0x00ea)
66 #define VD55G1_REG_APPLIED_DIGITAL_GAIN			CCI_REG16_LE(0x00ec)
67 #define VD55G1_REG_AE_FORCE_COLDSTART			CCI_REG8(0x0308)
68 #define VD55G1_REG_AE_COLDSTART_EXP_TIME		CCI_REG32_LE(0x0374)
69 #define VD55G1_REG_READOUT_CTRL				CCI_REG8(0x052e)
70 #define VD55G1_READOUT_CTRL_BIN_MODE_NORMAL		0
71 #define VD55G1_READOUT_CTRL_BIN_MODE_DIGITAL_X2		1
72 #define VD55G1_REG_DUSTER_CTRL				CCI_REG8(0x03ae)
73 #define VD55G1_DUSTER_ENABLE				BIT(0)
74 #define VD55G1_DUSTER_DISABLE				0
75 #define VD55G1_DUSTER_DYN_ENABLE			BIT(1)
76 #define VD55G1_DUSTER_RING_ENABLE			BIT(4)
77 #define VD55G1_REG_AE_TARGET_PERCENTAGE			CCI_REG8(0x0486)
78 #define VD55G1_REG_NEXT_CTX				CCI_REG16_LE(0x03e4)
79 #define VD55G1_REG_EXPOSURE_USE_CASES			CCI_REG8(0x0312)
80 #define VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT		BIT(2)
81 #define VD55G1_REG_EXPOSURE_MAX_COARSE			CCI_REG16_LE(0x0372)
82 #define VD55G1_EXPOSURE_MAX_COARSE_DEF			0x7fff
83 #define VD55G1_EXPOSURE_MAX_COARSE_SUB			446
84 #define VD55G1_REG_CTX_REPEAT_COUNT_CTX0		CCI_REG16_LE(0x03dc)
85 #define VD55G1_REG_CTX_REPEAT_COUNT_CTX1		CCI_REG16_LE(0x03de)
86 
87 #define VD55G1_REG_EXP_MODE(ctx) \
88 	CCI_REG8(0x0500 + VD55G1_CTX_OFFSET * (ctx))
89 #define VD55G1_REG_FRAME_LENGTH(ctx) \
90 	CCI_REG32_LE(0x050c + VD55G1_CTX_OFFSET * (ctx))
91 #define VD55G1_REG_X_START(ctx) \
92 	CCI_REG16_LE(0x0514 + VD55G1_CTX_OFFSET * (ctx))
93 #define VD55G1_REG_X_WIDTH(ctx) \
94 	CCI_REG16_LE(0x0516 + VD55G1_CTX_OFFSET * (ctx))
95 #define VD55G1_REG_Y_START(ctx) \
96 	CCI_REG16_LE(0x0510 + VD55G1_CTX_OFFSET * (ctx))
97 #define VD55G1_REG_Y_HEIGHT(ctx) \
98 	CCI_REG16_LE(0x0512 + VD55G1_CTX_OFFSET * (ctx))
99 #define VD55G1_REG_GPIO_0_CTRL(ctx) \
100 	CCI_REG8(0x051d + VD55G1_CTX_OFFSET * (ctx))
101 #define VD55G1_GPIO_MODE_FSYNC_OUT			0x00
102 #define VD55G1_GPIO_MODE_IN				0x01
103 #define VD55G1_GPIO_MODE_STROBE				0x02
104 #define VD55G1_REG_VT_MODE(ctx) \
105 	CCI_REG8(0x0536 + VD55G1_CTX_OFFSET * (ctx))
106 #define VD55G1_VT_MODE_NORMAL				0
107 #define VD55G1_VT_MODE_SUBTRACTION			1
108 #define VD55G1_REG_MASK_FRAME_CTRL(ctx) \
109 	CCI_REG8(0x0537 + VD55G1_CTX_OFFSET * (ctx))
110 #define VD55G1_MASK_FRAME_CTRL_OUTPUT			0
111 #define VD55G1_MASK_FRAME_CTRL_MASK			1
112 #define VD55G1_REG_EXPOSURE_INSTANCE(ctx) \
113 	CCI_REG32_LE(0x52D + VD55G1_CTX_OFFSET * (ctx))
114 
115 #define VD55G1_WIDTH					804
116 #define VD55G1_HEIGHT					704
117 #define VD55G1_MODE_DEF					0
118 #define VD55G1_NB_GPIOS					4
119 #define VD55G1_MBUS_CODE_DEF				0
120 #define VD55G1_DGAIN_DEF				256
121 #define VD55G1_AGAIN_DEF				19
122 #define VD55G1_EXPO_MAX_TERM				64
123 #define VD55G1_EXPO_DEF					500
124 #define VD55G1_LINE_LENGTH_MIN				1128
125 #define VD55G1_LINE_LENGTH_SUB_MIN			1344
126 #define VD55G1_VBLANK_MIN				86
127 #define VD55G1_VBLANK_MAX				0xffff
128 #define VD55G1_FRAME_LENGTH_DEF				1860 /* 60 fps */
129 #define VD55G1_MIPI_MARGIN				900
130 #define VD55G1_CTX_OFFSET				0x50
131 #define VD55G1_FWPATCH_REVISION_MAJOR			2
132 #define VD55G1_FWPATCH_REVISION_MINOR			9
133 #define VD55G1_XCLK_FREQ_MIN				(6 * HZ_PER_MHZ)
134 #define VD55G1_XCLK_FREQ_MAX				(27 * HZ_PER_MHZ)
135 #define VD55G1_MIPI_RATE_MIN				(250 * MEGA)
136 #define VD55G1_MIPI_RATE_MAX				(1200 * MEGA)
137 
138 #define VD55G1_MODEL_ID_NAME(id) \
139 	((id) == VD55G1_MODEL_ID_VD55G1 ? "vd55g1" : "vd65g4")
140 
141 static const u8 vd55g1_patch_array[] = {
142 	0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00,
143 	0xf0, 0x01, 0x42, 0x00, 0xe6, 0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
144 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 	0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0xfa, 0x68, 0x40, 0x00, 0xe8,
150 	0x09, 0xbe, 0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0x1c, 0x00, 0xc0, 0xe2,
151 	0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa, 0x6b, 0x80, 0x98, 0x7f,
152 	0xfc, 0xef, 0x11, 0xc1, 0x0f, 0x82, 0x69, 0xbe, 0x0f, 0xac, 0x58, 0x40,
153 	0x00, 0xe8, 0x0c, 0x0c, 0x00, 0xf2, 0x93, 0xdd, 0x1c, 0x00, 0x40, 0xe3,
154 	0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x84, 0xfa, 0x46, 0x0e, 0xe8, 0xe0,
155 	0x08, 0xde, 0x4a, 0x40, 0x84, 0xe0, 0xa5, 0x86, 0xa8, 0x7d, 0xfc, 0xef,
156 	0x6b, 0x80, 0x01, 0xbf, 0x28, 0x77, 0x0c, 0xef, 0x0b, 0x0e, 0x21, 0x78,
157 	0x06, 0xc0, 0x0b, 0xa5, 0xb5, 0x84, 0x06, 0x42, 0x98, 0xe1, 0x01, 0x81,
158 	0x01, 0x42, 0x38, 0xe0, 0x0c, 0xc4, 0x0e, 0x84, 0x46, 0x02, 0x84, 0xe0,
159 	0x0c, 0x84, 0x11, 0x81, 0x21, 0x81, 0x31, 0x81, 0x41, 0x81, 0x51, 0x81,
160 	0xc1, 0x81, 0x05, 0x83, 0x0c, 0x0c, 0x84, 0xf2, 0x93, 0xdd, 0x06, 0x40,
161 	0x98, 0xe1, 0xc8, 0x80, 0x58, 0x82, 0x48, 0xc0, 0x38, 0xc2, 0x29, 0x00,
162 	0x10, 0xe0, 0x19, 0x00, 0x14, 0xe0, 0x09, 0x00, 0x38, 0xe0, 0x5f, 0xb8,
163 	0x5f, 0xa8, 0x5f, 0xa6, 0x5f, 0xa4, 0x5f, 0xa2, 0x5f, 0xa0, 0x56, 0x41,
164 	0x98, 0xe1, 0x18, 0x82, 0x28, 0x80, 0x38, 0xc0, 0x5f, 0xa2, 0x19, 0x00,
165 	0x20, 0xf8, 0x5f, 0xa4, 0x28, 0xc2, 0x5f, 0xa6, 0x39, 0x00, 0x10, 0xe0,
166 	0x5f, 0xa2, 0x19, 0x00, 0x14, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x18, 0xe0,
167 	0x5f, 0xa6, 0x39, 0x00, 0x40, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x44, 0xe0,
168 	0x5f, 0xa4, 0x29, 0x00, 0x1c, 0xe0, 0x5f, 0xa6, 0x39, 0x00, 0x38, 0xe0,
169 	0x5f, 0xa2, 0x19, 0x00, 0x20, 0xe0, 0x5f, 0xa4, 0x29, 0x00, 0x24, 0xe0,
170 	0x5f, 0xa6, 0x39, 0x00, 0x28, 0xe0, 0x5f, 0xa2, 0x19, 0x00, 0x2c, 0xe0,
171 	0x5f, 0xa4, 0x29, 0x00, 0x30, 0xe0, 0x5f, 0xa6, 0x09, 0x00, 0x34, 0xe0,
172 	0x5f, 0xa2, 0x5f, 0xa4, 0x5f, 0xa0, 0x4a, 0x0a, 0xfc, 0xfb, 0xe5, 0x82,
173 	0x08, 0xde, 0x4a, 0x40, 0x88, 0xe0, 0xf6, 0x40, 0x00, 0xe0, 0x01, 0x4e,
174 	0x99, 0x78, 0x0a, 0xc0, 0x85, 0x80, 0x98, 0x40, 0x00, 0xe8, 0x35, 0x81,
175 	0xa8, 0x40, 0x00, 0xe8, 0x0b, 0x8c, 0x0c, 0x0c, 0x84, 0xf2, 0xd5, 0xed,
176 	0x83, 0xc1, 0x13, 0xc5, 0x93, 0xdd, 0xc3, 0xc1, 0x83, 0xc1, 0x13, 0xc3,
177 	0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0xc6, 0x0f, 0x94, 0xe0,
178 	0x19, 0x0e, 0xc9, 0x65, 0x01, 0xc0, 0x28, 0xde, 0x0a, 0x42, 0x80, 0xe0,
179 	0x24, 0x02, 0x00, 0xfc, 0x16, 0xde, 0xa5, 0x8a, 0x19, 0x00, 0xb8, 0xe0,
180 	0x10, 0x02, 0x0c, 0xec, 0x1d, 0xe6, 0x14, 0x02, 0x88, 0x80, 0x4e, 0x04,
181 	0x01, 0x00, 0x10, 0x80, 0x25, 0x02, 0x08, 0x9c, 0x86, 0x02, 0x00, 0x80,
182 	0x08, 0x44, 0x00, 0x98, 0x55, 0x81, 0x11, 0x85, 0x45, 0x81, 0x11, 0x89,
183 	0x25, 0x81, 0x11, 0x83, 0x2b, 0x00, 0x24, 0xe0, 0x64, 0xc2, 0x0b, 0x84,
184 	0x08, 0x51, 0x00, 0xef, 0x2b, 0x80, 0x01, 0x83, 0x1b, 0x8c, 0x38, 0x7d,
185 	0x5c, 0xef, 0x18, 0xde, 0x0b, 0xa1, 0x25, 0x82, 0x0b, 0x0e, 0x88, 0xf9,
186 	0x0a, 0x00, 0x00, 0xe8, 0x10, 0x42, 0x04, 0x9c, 0x11, 0x4e, 0x0c, 0x80,
187 	0x10, 0x40, 0x04, 0xf0, 0x4e, 0x05, 0x01, 0x60, 0x10, 0xc0, 0x06, 0x88,
188 	0x10, 0x40, 0xf8, 0xf3, 0x06, 0xde, 0x4c, 0x0c, 0x04, 0xf2, 0x93, 0xdd,
189 	0x0c, 0x04, 0x1c, 0xfe, 0xf6, 0x0f, 0x94, 0xe0, 0x38, 0x9c, 0x46, 0x51,
190 	0xfc, 0xe0, 0x46, 0x49, 0x38, 0xe2, 0x30, 0x46, 0xf8, 0xf3, 0x36, 0x9c,
191 	0xc6, 0x46, 0x0c, 0xe1, 0x34, 0x8c, 0x94, 0xa0, 0x4e, 0xa0, 0x39, 0x06,
192 	0x80, 0xe0, 0x4a, 0x46, 0x94, 0xe0, 0x05, 0x8c, 0x6a, 0x40, 0x80, 0xe0,
193 	0x2c, 0x0c, 0x00, 0xe2, 0x0b, 0x8c, 0xb8, 0x7c, 0x5c, 0xef, 0x0b, 0x8c,
194 	0x9e, 0xa0, 0xf8, 0x40, 0x60, 0xef, 0x0b, 0xa1, 0x5a, 0x40, 0x80, 0xe0,
195 	0x65, 0x88, 0x28, 0x02, 0x01, 0x40, 0x00, 0x80, 0x2a, 0x42, 0x9c, 0xe1,
196 	0x28, 0x49, 0x60, 0xef, 0x96, 0x4d, 0x9c, 0xe1, 0x01, 0x81, 0x06, 0x98,
197 	0xd5, 0x81, 0x09, 0x0e, 0xa1, 0x64, 0x01, 0xc0, 0x4a, 0x40, 0x88, 0xe0,
198 	0x85, 0x80, 0xb8, 0x77, 0xfc, 0xef, 0x35, 0x81, 0xc8, 0x77, 0xfc, 0xef,
199 	0x08, 0x98, 0x4a, 0x00, 0xfc, 0xfb, 0x55, 0xfc, 0xe8, 0x4a, 0x60, 0xef,
200 	0x1a, 0x44, 0x9c, 0xe1, 0x35, 0x81, 0x1a, 0x4e, 0x9c, 0xe9, 0x1c, 0x00,
201 	0x00, 0xe2, 0x0c, 0x0c, 0x1c, 0xf6, 0x93, 0xdd, 0x0d, 0xc3, 0x1a, 0x41,
202 	0x08, 0xe4, 0x0a, 0x40, 0x84, 0xe1, 0x0c, 0x00, 0x00, 0xe2, 0x93, 0xdd,
203 	0x4c, 0x04, 0x1c, 0xfa, 0x86, 0x52, 0xec, 0xe1, 0x08, 0xa6, 0x65, 0x12,
204 	0x24, 0xf8, 0x0e, 0x02, 0x99, 0x7a, 0x00, 0xc0, 0x00, 0x40, 0xa0, 0xf3,
205 	0x06, 0xa6, 0x0b, 0x8c, 0x08, 0x49, 0x00, 0xef, 0x85, 0x12, 0x28, 0xf8,
206 	0x02, 0x02, 0xfc, 0xed, 0xf6, 0x47, 0xfd, 0x6f, 0xe0, 0xff, 0x04, 0xe2,
207 	0x14, 0x04, 0xc0, 0xe0, 0x0f, 0x86, 0x2f, 0xa0, 0x0b, 0x8c, 0x2e, 0xe2,
208 	0x08, 0x48, 0x00, 0xef, 0x86, 0x02, 0x84, 0xfe, 0x0e, 0x05, 0x09, 0x7d,
209 	0x00, 0xc0, 0x05, 0x52, 0x08, 0xf8, 0x18, 0x7d, 0xfc, 0xef, 0x4a, 0x40,
210 	0x80, 0xe0, 0x09, 0x12, 0x04, 0xc0, 0x65, 0x12, 0x20, 0xf8, 0x00, 0x40,
211 	0x40, 0xdc, 0x01, 0x52, 0x04, 0xc0, 0x0e, 0x00, 0x41, 0x78, 0xf5, 0xc5,
212 	0x6d, 0xc0, 0xb5, 0x82, 0x05, 0x10, 0x10, 0xe0, 0x11, 0xf1, 0x0f, 0x82,
213 	0x05, 0x50, 0x10, 0xe0, 0x05, 0x10, 0x10, 0xe0, 0xfe, 0x02, 0xf0, 0xff,
214 	0x0f, 0x82, 0x85, 0x83, 0x15, 0x10, 0x10, 0xe0, 0x16, 0x00, 0x91, 0x6e,
215 	0x69, 0xcd, 0x21, 0xf1, 0x6d, 0xc1, 0x01, 0x83, 0x2f, 0x82, 0x26, 0x00,
216 	0x00, 0x80, 0x2f, 0xa0, 0x25, 0x50, 0x10, 0xe0, 0x05, 0x10, 0x10, 0xe0,
217 	0x11, 0xa1, 0xfe, 0x04, 0xf0, 0xff, 0x06, 0x42, 0x00, 0x80, 0x0f, 0x84,
218 	0x0f, 0xa2, 0x05, 0x50, 0x10, 0xe0, 0x16, 0x00, 0x91, 0x6e, 0x69, 0xcd,
219 	0x6d, 0xc1, 0x71, 0x8d, 0x16, 0x00, 0x79, 0x61, 0x2d, 0xcb, 0x86, 0x0e,
220 	0x00, 0x80, 0x6d, 0xc1, 0x56, 0x0e, 0x00, 0xc0, 0x0b, 0x8c, 0x1b, 0x8e,
221 	0x71, 0x52, 0x0c, 0xf8, 0x08, 0x43, 0x00, 0xef, 0x05, 0x52, 0x14, 0xf8,
222 	0x15, 0x10, 0x28, 0xe0, 0x70, 0x04, 0x04, 0xec, 0x31, 0xe1, 0x29, 0x9e,
223 	0x1f, 0x86, 0x1f, 0xa4, 0x15, 0x50, 0x28, 0xe0, 0x86, 0x42, 0x3c, 0xe0,
224 	0x0e, 0x04, 0x9d, 0x64, 0x9b, 0xc2, 0x05, 0x52, 0x1c, 0xf8, 0x78, 0xa6,
225 	0x48, 0x77, 0xfc, 0xef, 0x4a, 0x40, 0x80, 0xe0, 0x70, 0x4e, 0x10, 0xdc,
226 	0x1e, 0x00, 0x81, 0x70, 0xeb, 0xcb, 0x70, 0x4e, 0xec, 0x93, 0x6d, 0xc1,
227 	0x11, 0x85, 0x36, 0x02, 0x00, 0x80, 0x76, 0xa6, 0x11, 0x52, 0x10, 0xf8,
228 	0x05, 0x10, 0x40, 0xe0, 0xfe, 0x47, 0x0c, 0xff, 0x14, 0x04, 0xa0, 0xe0,
229 	0x0f, 0x86, 0x0f, 0xa4, 0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x28, 0xe0,
230 	0xfe, 0x47, 0xfd, 0x7f, 0xe3, 0xff, 0x14, 0x04, 0xd0, 0xe0, 0x0f, 0x86,
231 	0x2f, 0xa0, 0x20, 0x00, 0x01, 0x6c, 0x00, 0xd0, 0x05, 0x50, 0x28, 0xe0,
232 	0x0b, 0x8c, 0xf8, 0x7e, 0xfc, 0xee, 0x0e, 0x03, 0x59, 0x78, 0xf5, 0xc5,
233 	0x0d, 0xc2, 0x05, 0x52, 0x0c, 0xf8, 0x08, 0xa6, 0x46, 0x42, 0xb4, 0xe0,
234 	0x18, 0x84, 0x00, 0x40, 0xf4, 0x93, 0x00, 0x40, 0x08, 0xdc, 0x1b, 0xa1,
235 	0x06, 0xa6, 0x05, 0x10, 0x40, 0x80, 0x04, 0x00, 0x50, 0x9c, 0x65, 0x8a,
236 	0x05, 0x10, 0x44, 0xe0, 0xf6, 0x43, 0xfd, 0x6f, 0x00, 0xf8, 0x0f, 0x82,
237 	0x06, 0x02, 0x01, 0x60, 0x1e, 0xc0, 0x0f, 0xa2, 0x05, 0x50, 0x44, 0xe0,
238 	0x05, 0x10, 0x44, 0xe0, 0x0e, 0x02, 0x00, 0xf8, 0x0f, 0x82, 0x09, 0xf6,
239 	0x05, 0x50, 0x44, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04, 0x00, 0x54, 0xfc,
240 	0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04, 0x00, 0xcc, 0xfc,
241 	0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04, 0x00, 0x4c, 0xfc,
242 	0x05, 0x50, 0x40, 0xe0, 0x05, 0x10, 0x40, 0xe0, 0x04, 0x00, 0xd0, 0xfc,
243 	0x05, 0x50, 0x40, 0xe0, 0x4c, 0x0c, 0x1c, 0xf2, 0x93, 0xdd, 0xc3, 0xc1,
244 	0xc6, 0x40, 0xfc, 0xe0, 0x04, 0x80, 0xc6, 0x44, 0x0c, 0xe1, 0x15, 0x04,
245 	0x0c, 0xf8, 0x0a, 0x80, 0x06, 0x07, 0x04, 0xe0, 0x03, 0x42, 0x48, 0xe1,
246 	0x46, 0x02, 0x40, 0xe2, 0x08, 0xc6, 0x44, 0x88, 0x06, 0x46, 0x0e, 0xe0,
247 	0x86, 0x01, 0x84, 0xe0, 0x33, 0x80, 0x39, 0x06, 0xd8, 0xef, 0x0a, 0x46,
248 	0x80, 0xe0, 0x31, 0xbf, 0x06, 0x06, 0x00, 0xc0, 0x31, 0x48, 0x60, 0xe0,
249 	0x34, 0x88, 0x49, 0x06, 0x40, 0xe1, 0x40, 0x48, 0x7c, 0xf3, 0x41, 0x46,
250 	0x40, 0xe1, 0x24, 0x8a, 0x39, 0x04, 0x10, 0xe0, 0x39, 0xc2, 0x31, 0x44,
251 	0x10, 0xe0, 0x14, 0xc4, 0x1b, 0xa5, 0x11, 0x83, 0x11, 0x40, 0x25, 0x6a,
252 	0x01, 0xc0, 0x08, 0x5c, 0x00, 0xda, 0x15, 0x00, 0xcc, 0xe0, 0x25, 0x00,
253 	0xf8, 0xe0, 0x1b, 0x85, 0x08, 0x5c, 0x00, 0x9a, 0x4e, 0x03, 0x01, 0x60,
254 	0x10, 0xc0, 0x29, 0x00, 0x1c, 0xe4, 0x18, 0x84, 0x20, 0x44, 0xf8, 0xf3,
255 	0x2f, 0xa2, 0x21, 0x40, 0x1c, 0xe4, 0x93, 0xdd, 0x0c, 0x00, 0x80, 0xfa,
256 	0x15, 0x00, 0x3c, 0xe0, 0x21, 0x81, 0x31, 0x85, 0x21, 0x42, 0x60, 0xe0,
257 	0x15, 0x00, 0x44, 0xe0, 0x31, 0x42, 0x40, 0xe1, 0x15, 0x00, 0x34, 0xe0,
258 	0x21, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0xd6, 0x04, 0x10, 0xe0,
259 	0x23, 0x42, 0x30, 0xe0, 0x15, 0x00, 0x34, 0xe0, 0x86, 0x44, 0x04, 0xe0,
260 	0x23, 0x42, 0x38, 0xe0, 0x05, 0x00, 0x30, 0xe0, 0xc6, 0x02, 0x08, 0xe0,
261 	0x13, 0x40, 0x10, 0xe3, 0xe8, 0x56, 0x40, 0xef, 0x06, 0x40, 0x0c, 0xe1,
262 	0x04, 0x80, 0x06, 0x02, 0x94, 0xe0, 0x2b, 0x02, 0xc4, 0xea, 0x3b, 0x00,
263 	0x78, 0xe2, 0x20, 0x44, 0xfd, 0x73, 0x07, 0xc0, 0x30, 0x46, 0x01, 0x70,
264 	0xf8, 0xc0, 0x3f, 0xa4, 0x33, 0x40, 0x78, 0xe2, 0x0a, 0x84, 0x0c, 0x08,
265 	0x80, 0xf2, 0xf8, 0x3b, 0x3c, 0xff, 0xc3, 0xc1, 0x06, 0x40, 0x0c, 0xe1,
266 	0x04, 0x80, 0x1b, 0x00, 0x40, 0xe4, 0x19, 0xc2, 0x13, 0x40, 0x40, 0xe4,
267 	0x1b, 0x00, 0x40, 0xe4, 0x19, 0xc4, 0x13, 0x40, 0x40, 0xe4, 0x93, 0xdd,
268 	0xc6, 0x43, 0xec, 0xe0, 0x46, 0x41, 0xfc, 0xe0, 0x24, 0x84, 0x04, 0x80,
269 	0x31, 0x81, 0x4a, 0x44, 0x80, 0xe0, 0x86, 0x44, 0x0c, 0xe1, 0x09, 0x00,
270 	0x6c, 0xe0, 0xc4, 0x8a, 0x8e, 0x47, 0xfc, 0x9f, 0x01, 0x42, 0x51, 0x78,
271 	0x0c, 0xc0, 0x31, 0x58, 0x90, 0xe0, 0x34, 0x8a, 0x41, 0xbf, 0x06, 0x08,
272 	0x00, 0xc0, 0x41, 0x46, 0xa0, 0xe0, 0x34, 0x8a, 0x51, 0x81, 0xf6, 0x0b,
273 	0x00, 0xc0, 0x51, 0x46, 0xd0, 0xe0, 0x34, 0x8a, 0x01, 0xbf, 0x51, 0x46,
274 	0xe0, 0xe0, 0x44, 0x84, 0x0a, 0x48, 0x84, 0xe0, 0x75, 0x86, 0x54, 0xca,
275 	0x49, 0x88, 0x44, 0x06, 0x88, 0xe1, 0x36, 0x94, 0x4a, 0x46, 0x80, 0xe0,
276 	0x34, 0xca, 0x47, 0xc6, 0x11, 0x8d, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88,
277 	0x76, 0x02, 0x00, 0xc0, 0x06, 0x00, 0x00, 0xc0, 0x16, 0x8c, 0x14, 0x88,
278 	0x01, 0x42, 0xc0, 0xe1, 0x01, 0x42, 0xe0, 0xe1, 0x01, 0x42, 0xf0, 0xe1,
279 	0x93, 0xdd, 0x34, 0xca, 0x41, 0x85, 0x46, 0x8c, 0x34, 0xca, 0x06, 0x48,
280 	0x00, 0xe0, 0x41, 0x46, 0xd0, 0xe0, 0x34, 0x88, 0x41, 0x83, 0x46, 0x8c,
281 	0x34, 0x88, 0x01, 0x46, 0xc0, 0xe1, 0x01, 0x46, 0xe0, 0xe1, 0x01, 0x46,
282 	0xf0, 0xe1, 0x09, 0x02, 0x20, 0xe0, 0x14, 0xca, 0x03, 0x42, 0x58, 0xe0,
283 	0x93, 0xdd, 0xc3, 0xc1, 0x4c, 0x04, 0x04, 0xfa, 0x46, 0x4e, 0x08, 0xe1,
284 	0x06, 0x4c, 0x0c, 0xe1, 0x0a, 0x9e, 0x14, 0x98, 0x05, 0x42, 0x44, 0xe0,
285 	0x10, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0x78, 0x41, 0x00, 0xe8, 0x08, 0x9c,
286 	0x0b, 0xa1, 0x04, 0x98, 0x06, 0x02, 0x10, 0x80, 0x13, 0x40, 0xf8, 0x86,
287 	0x65, 0x82, 0x00, 0x00, 0xe1, 0x65, 0x03, 0xc0, 0xa8, 0x40, 0x00, 0xe8,
288 	0x14, 0x98, 0x04, 0x00, 0xa0, 0xfc, 0x03, 0x42, 0x00, 0xe7, 0x4c, 0x0c,
289 	0x04, 0xf2, 0x93, 0xdd, 0x0a, 0x80, 0x93, 0xdd, 0x0c, 0x04, 0x00, 0xfa,
290 	0x06, 0x02, 0xec, 0xe1, 0x64, 0x84, 0x15, 0x0c, 0x2c, 0xe0, 0x14, 0x02,
291 	0xa0, 0xfc, 0x15, 0x4c, 0x2c, 0xe0, 0xd8, 0x40, 0x00, 0xe8, 0x14, 0xd8,
292 	0x09, 0x82, 0x14, 0x02, 0x00, 0xfc, 0x1f, 0xa0, 0x1e, 0xd8, 0x01, 0x85,
293 	0x0c, 0x0c, 0x00, 0xf2, 0xe8, 0x32, 0x2c, 0xff, 0x93, 0xdd, 0xc3, 0xc1,
294 	0x0c, 0x04, 0x00, 0xfa, 0x6b, 0x80, 0xf6, 0x01, 0x94, 0xe0, 0x08, 0x80,
295 	0x4a, 0x40, 0x80, 0xe0, 0x45, 0x86, 0x06, 0x40, 0x0c, 0xe1, 0x04, 0x80,
296 	0xc6, 0x02, 0x40, 0xe2, 0x09, 0x00, 0xd0, 0xe0, 0x14, 0x84, 0x1b, 0xa5,
297 	0x15, 0x84, 0x07, 0xc5, 0x09, 0x82, 0x18, 0x41, 0x00, 0xe8, 0x46, 0x43,
298 	0xfc, 0xe0, 0x14, 0x84, 0x19, 0x02, 0xd8, 0xe0, 0x19, 0x82, 0x0b, 0x83,
299 	0x16, 0x00, 0x00, 0xc0, 0x01, 0x4c, 0x00, 0xc0, 0x0c, 0x0c, 0x00, 0xf2,
300 	0x93, 0xdd, 0xc3, 0xc1, 0x4a, 0x00, 0x00, 0xe0, 0x0c, 0x00, 0x00, 0xe2,
301 	0x93, 0xdd, 0xc3, 0xc1, 0x46, 0x40, 0x84, 0xe0, 0x11, 0xaf, 0x13, 0x40,
302 	0x6c, 0xec, 0x11, 0xb3, 0x13, 0x40, 0x70, 0xec, 0xc6, 0x43, 0xf0, 0xe0,
303 	0x13, 0x40, 0xdc, 0xec, 0xc6, 0x02, 0x24, 0xe0, 0x1c, 0x80, 0x93, 0xdd,
304 	0x4c, 0x00, 0x00, 0xfa, 0xc8, 0x60, 0x7c, 0xef, 0xe8, 0x61, 0x7c, 0xef,
305 	0x28, 0x7e, 0x80, 0xef, 0xc6, 0x40, 0x98, 0xe1, 0x11, 0x83, 0x16, 0x80,
306 	0x46, 0x01, 0x10, 0xe1, 0x11, 0x81, 0x16, 0x80, 0x4c, 0x08, 0x00, 0xf2,
307 	0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x0c, 0xfa, 0x6b, 0x80, 0x04, 0x98,
308 	0x7b, 0x82, 0x56, 0x42, 0xb4, 0xe0, 0x88, 0x84, 0x05, 0x00, 0x10, 0xe0,
309 	0x09, 0x86, 0x0b, 0xa5, 0x46, 0x02, 0x00, 0x80, 0x06, 0x05, 0x00, 0x80,
310 	0x25, 0x82, 0x0b, 0xa3, 0xa5, 0x80, 0x0b, 0xa1, 0x06, 0x00, 0xf4, 0xef,
311 	0xd5, 0x84, 0x11, 0x85, 0x21, 0x91, 0x0b, 0x8e, 0x88, 0x74, 0x10, 0xef,
312 	0x0b, 0xa1, 0xf5, 0x82, 0x0a, 0x9e, 0x1a, 0x9c, 0x24, 0x98, 0x07, 0xe0,
313 	0x0f, 0xa2, 0x0e, 0xca, 0x0a, 0xde, 0x1a, 0xdc, 0x24, 0x98, 0x03, 0xb0,
314 	0x07, 0xe0, 0x0f, 0xa2, 0x0e, 0xc8, 0x01, 0x81, 0x0c, 0x0c, 0x0c, 0xf2,
315 	0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x7c, 0xfa, 0x46, 0x42, 0x9c, 0xe0,
316 	0x0b, 0x02, 0x04, 0xe3, 0xf0, 0x1e, 0x30, 0xec, 0x0b, 0xa3, 0x35, 0x96,
317 	0x8e, 0x01, 0x01, 0x60, 0x10, 0xc0, 0x0e, 0xfc, 0xc6, 0x05, 0xd0, 0xe1,
318 	0x0b, 0x82, 0x31, 0x81, 0x10, 0x16, 0x00, 0xe5, 0x20, 0x10, 0x20, 0xe7,
319 	0x0e, 0xbe, 0xb5, 0x85, 0x94, 0xfc, 0xa4, 0xbe, 0x82, 0x4c, 0x9c, 0xf0,
320 	0x05, 0x0c, 0x40, 0xe0, 0x11, 0x89, 0x93, 0x8e, 0xa3, 0x8e, 0x58, 0x44,
321 	0x00, 0xe8, 0x15, 0x0c, 0xc0, 0xf8, 0x04, 0x0c, 0x80, 0xfb, 0x0c, 0xed,
322 	0x0b, 0x82, 0x1b, 0x8c, 0x48, 0x44, 0x00, 0xe8, 0x15, 0x10, 0x1c, 0xfc,
323 	0x0e, 0xa8, 0x0b, 0x82, 0x1b, 0x8c, 0xd8, 0x43, 0x00, 0xe8, 0x71, 0x88,
324 	0x0e, 0xa4, 0x0a, 0x0e, 0x40, 0xe0, 0x35, 0xf8, 0x04, 0xbe, 0x14, 0xbc,
325 	0x81, 0xa0, 0x03, 0x8e, 0x0e, 0xbe, 0x04, 0xfc, 0x11, 0x82, 0x3b, 0x82,
326 	0x03, 0x8e, 0x0e, 0xfc, 0x3b, 0xa9, 0x06, 0x0e, 0x00, 0xc0, 0x35, 0x5e,
327 	0x00, 0xc0, 0xd5, 0xfa, 0xc6, 0x01, 0xd0, 0xe1, 0x7b, 0x80, 0x04, 0x9e,
328 	0x11, 0x91, 0x98, 0x41, 0x00, 0xe8, 0x24, 0x9c, 0x46, 0x42, 0x9c, 0xe0,
329 	0x6b, 0x82, 0x03, 0x4c, 0xc4, 0xe0, 0x11, 0x91, 0x0b, 0x84, 0xf8, 0x40,
330 	0x00, 0xe8, 0x19, 0x0e, 0x20, 0xe5, 0x03, 0x4c, 0xc0, 0xe0, 0x0b, 0x82,
331 	0x08, 0x72, 0xfc, 0xef, 0x01, 0x4c, 0x24, 0xf9, 0xf1, 0x98, 0x0c, 0x0c,
332 	0x7c, 0xf2, 0x93, 0xdd, 0x4c, 0x00, 0x00, 0xfa, 0x48, 0x65, 0x2c, 0xef,
333 	0x4c, 0x08, 0x00, 0xf2, 0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x00, 0xfa,
334 	0x6b, 0x82, 0x78, 0x6e, 0xfc, 0xee, 0x46, 0x42, 0xec, 0xe0, 0x24, 0x84,
335 	0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x83, 0xf5, 0x82, 0x24, 0x02,
336 	0xa0, 0xe1, 0x14, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x85, 0x15, 0x82,
337 	0x27, 0xe1, 0x24, 0x02, 0x80, 0xfa, 0x1d, 0xcc, 0x11, 0x89, 0x86, 0x02,
338 	0x00, 0x80, 0x0c, 0x0c, 0x00, 0xf2, 0x18, 0x17, 0xfc, 0xfe, 0xc3, 0xc1,
339 	0x0c, 0x04, 0x00, 0xfa, 0x06, 0x41, 0x8c, 0xe0, 0x1b, 0x00, 0xec, 0xe4,
340 	0x1b, 0xa3, 0x75, 0x84, 0x11, 0x81, 0x8e, 0x05, 0x01, 0x60, 0x10, 0xc0,
341 	0x00, 0x06, 0xc0, 0xe5, 0x95, 0x81, 0x44, 0x88, 0x1d, 0xee, 0x75, 0x80,
342 	0x4e, 0xc1, 0x25, 0x81, 0x4e, 0xcd, 0x21, 0x88, 0x11, 0x82, 0x0a, 0x02,
343 	0x40, 0xe0, 0xd5, 0xfc, 0x56, 0x00, 0x00, 0xe1, 0x18, 0x80, 0x1b, 0xa1,
344 	0xc5, 0x84, 0x08, 0x82, 0x4a, 0x00, 0xfc, 0xfb, 0x45, 0x84, 0x86, 0x4d,
345 	0x84, 0xe1, 0x04, 0x98, 0x05, 0x00, 0x10, 0xe0, 0x4a, 0x40, 0x80, 0xe0,
346 	0x45, 0x82, 0x11, 0x81, 0x0b, 0x8c, 0x58, 0x76, 0x28, 0xef, 0x0b, 0x8c,
347 	0x0c, 0x0c, 0x00, 0xf2, 0x88, 0x35, 0x28, 0xff, 0x0c, 0x0c, 0x00, 0xf2,
348 	0x93, 0xdd, 0xc3, 0xc1, 0x46, 0x41, 0xfc, 0xe0, 0x04, 0x80, 0x09, 0x00,
349 	0x80, 0xe0, 0x09, 0x9e, 0x0b, 0xa3, 0x75, 0x82, 0x46, 0x41, 0x80, 0xe1,
350 	0x04, 0x80, 0xc6, 0x42, 0x8c, 0xe0, 0x04, 0xc2, 0x00, 0x40, 0x00, 0xf2,
351 	0x07, 0xcf, 0x06, 0x84, 0x06, 0x40, 0x84, 0xe0, 0x15, 0x00, 0x28, 0xe5,
352 	0x1c, 0xc2, 0x93, 0xdd, 0x0b, 0xa1, 0xc6, 0x00, 0xa0, 0xe1, 0x15, 0x00,
353 	0x04, 0xf8, 0x05, 0x84, 0x21, 0x8b, 0x2c, 0x84, 0x14, 0x80, 0x2c, 0x84,
354 	0x14, 0x82, 0x2c, 0x84, 0x15, 0x00, 0x10, 0xe0, 0x21, 0xa1, 0x21, 0x42,
355 	0x10, 0xe0, 0x05, 0x00, 0x14, 0xe0, 0x01, 0x88, 0x75, 0x83, 0x21, 0x85,
356 	0x2c, 0x84, 0x14, 0x80, 0x06, 0x46, 0x00, 0xe0, 0x2c, 0x84, 0x14, 0x82,
357 	0x2c, 0x84, 0x14, 0xc0, 0x21, 0xa1, 0x21, 0x42, 0x20, 0xe0, 0x14, 0xc2,
358 	0x31, 0x42, 0x20, 0xe0, 0x15, 0x00, 0x10, 0xe0, 0x21, 0x42, 0x20, 0xe0,
359 	0x05, 0x00, 0x14, 0xe0, 0x01, 0x90, 0x06, 0x42, 0x00, 0xe0, 0x16, 0x80,
360 	0x93, 0xdd, 0xc3, 0xc1, 0x0c, 0x04, 0x7c, 0xfa, 0x4a, 0x40, 0x80, 0xe0,
361 	0xf0, 0x1e, 0x30, 0xec, 0xe5, 0x82, 0xa6, 0x40, 0x00, 0xe1, 0x1a, 0x80,
362 	0x2a, 0xc0, 0x3a, 0xc2, 0x13, 0x40, 0x10, 0xe0, 0x1a, 0x82, 0x23, 0x40,
363 	0x18, 0xe0, 0x33, 0x40, 0x1c, 0xe0, 0x13, 0x40, 0x14, 0xe0, 0xf8, 0x61,
364 	0x68, 0xef, 0xc6, 0x13, 0x00, 0xe1, 0x15, 0x12, 0x28, 0xf8, 0x0b, 0x02,
365 	0x2c, 0xe0, 0x1b, 0x02, 0x24, 0xe0, 0x8a, 0x00, 0xa5, 0x64, 0x03, 0xc0,
366 	0x35, 0x82, 0x0a, 0x4e, 0x9c, 0xe1, 0x1a, 0x03, 0x11, 0x6f, 0x02, 0xc0,
367 	0xe8, 0x13, 0x01, 0x20, 0x00, 0xc0, 0x1f, 0xa0, 0x5a, 0x42, 0x80, 0xe0,
368 	0x0a, 0x4e, 0x9c, 0xe1, 0x68, 0x13, 0x00, 0xa0, 0x09, 0x12, 0x78, 0xf8,
369 	0xa1, 0x81, 0xf0, 0x02, 0x10, 0xe4, 0x07, 0xc4, 0x0c, 0xfc, 0xf0, 0x00,
370 	0x20, 0xe4, 0xa6, 0x91, 0xa8, 0x53, 0x74, 0xef, 0x05, 0x12, 0x30, 0xf8,
371 	0x25, 0x12, 0x28, 0xf8, 0x61, 0x87, 0x09, 0x00, 0x48, 0xe0, 0x81, 0x85,
372 	0x09, 0x86, 0x0b, 0xa7, 0x26, 0x0c, 0x00, 0xc0, 0x0b, 0xa1, 0x0b, 0x04,
373 	0x28, 0xe0, 0x16, 0x0c, 0x00, 0x80, 0x03, 0x52, 0x04, 0xf8, 0x0b, 0x04,
374 	0x20, 0xe0, 0x0c, 0xa6, 0x1b, 0x04, 0x2c, 0xe0, 0x3b, 0x04, 0x28, 0xe0,
375 	0x4b, 0x04, 0x20, 0xe0, 0x13, 0x86, 0x3b, 0x04, 0x24, 0xe0, 0x10, 0x0a,
376 	0x04, 0xec, 0x1a, 0xfc, 0x33, 0x88, 0x30, 0x06, 0x04, 0xec, 0x12, 0x4e,
377 	0x94, 0xf0, 0x32, 0x48, 0x84, 0xf0, 0x4c, 0xe4, 0x7c, 0xa4, 0xcb, 0x04,
378 	0x28, 0xe0, 0x14, 0x08, 0x84, 0xe1, 0xcd, 0xc9, 0xc2, 0x58, 0x90, 0x91,
379 	0x42, 0x4e, 0x94, 0x90, 0xc3, 0x52, 0x04, 0x98, 0x73, 0x52, 0x00, 0x80,
380 	0x5b, 0x04, 0x20, 0xe0, 0x5d, 0xc9, 0x52, 0x40, 0x90, 0x91, 0x42, 0x48,
381 	0x8c, 0x90, 0x03, 0x52, 0x04, 0x80, 0x43, 0x52, 0x08, 0x80, 0x3b, 0x04,
382 	0x2c, 0xe0, 0x49, 0x04, 0xb8, 0xe0, 0x33, 0x52, 0x1c, 0xf8, 0x2b, 0x04,
383 	0x24, 0xe0, 0x4b, 0xab, 0x23, 0x52, 0x18, 0xf8, 0x65, 0x8a, 0x4b, 0xa9,
384 	0xe5, 0x90, 0x4b, 0xa7, 0x22, 0x44, 0x84, 0xd0, 0x32, 0x46, 0x84, 0xd0,
385 	0x33, 0x52, 0x1c, 0xd8, 0x23, 0x52, 0x18, 0xd8, 0x95, 0x96, 0x20, 0x44,
386 	0xf9, 0x73, 0xff, 0xc0, 0x27, 0xc3, 0x23, 0x82, 0x23, 0x52, 0x18, 0xf8,
387 	0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x58, 0x52,
388 	0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc3,
389 	0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02,
390 	0x80, 0xfb, 0x2b, 0x8c, 0x68, 0x51, 0x74, 0xef, 0xc5, 0x87, 0x20, 0x44,
391 	0xe1, 0x73, 0xff, 0xc0, 0x27, 0xc7, 0x23, 0x82, 0x23, 0x52, 0x18, 0xf8,
392 	0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x78, 0x57,
393 	0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc7,
394 	0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02,
395 	0x80, 0xfb, 0x2b, 0x8c, 0x88, 0x56, 0x74, 0xef, 0xe5, 0x83, 0x20, 0x44,
396 	0xf1, 0x73, 0xff, 0xc0, 0x27, 0xc5, 0x23, 0x82, 0x23, 0x52, 0x18, 0xf8,
397 	0x24, 0x02, 0x80, 0xfb, 0x04, 0x00, 0x80, 0xfb, 0x2b, 0x8c, 0x18, 0x52,
398 	0x74, 0xef, 0x1b, 0x12, 0x1c, 0xf8, 0x2a, 0xfc, 0x0c, 0xe4, 0x17, 0xc5,
399 	0x13, 0x84, 0x13, 0x52, 0x1c, 0xf8, 0x0b, 0x12, 0x04, 0xf8, 0x14, 0x02,
400 	0x80, 0xfb, 0x2b, 0x8c, 0x28, 0x51, 0x74, 0xef, 0x7b, 0x80, 0x7c, 0xa4,
401 	0x08, 0x91, 0xa3, 0x52, 0x1c, 0xe0, 0xa3, 0x52, 0x24, 0xe0, 0x0b, 0xa1,
402 	0x83, 0x52, 0x1c, 0x80, 0x83, 0x52, 0x24, 0x80, 0x89, 0x12, 0x78, 0xf8,
403 	0xf6, 0x57, 0xfc, 0xef, 0x6b, 0x12, 0x1c, 0xf8, 0xab, 0x12, 0x18, 0xf8,
404 	0xd6, 0x57, 0xfc, 0x8f, 0x8b, 0xa3, 0xa0, 0x40, 0x00, 0x9c, 0xa5, 0x86,
405 	0x64, 0x00, 0x80, 0xfb, 0x1b, 0x90, 0xf8, 0x7d, 0xf8, 0xee, 0x6b, 0x80,
406 	0xa4, 0x00, 0x80, 0xfb, 0x1b, 0x90, 0x98, 0x7d, 0xf8, 0xee, 0x15, 0x12,
407 	0x28, 0xf8, 0x19, 0x02, 0xb8, 0xe0, 0x1b, 0xad, 0x95, 0x82, 0x1a, 0xa6,
408 	0xa0, 0x44, 0xf9, 0x73, 0xff, 0xc0, 0x27, 0xc3, 0x13, 0x94, 0x10, 0x02,
409 	0x08, 0xec, 0x1c, 0xe4, 0x23, 0x52, 0x18, 0xf8, 0x1b, 0x12, 0x04, 0xf8,
410 	0x03, 0x96, 0x03, 0x52, 0x28, 0xe0, 0x1c, 0xe6, 0x0a, 0xa6, 0x1a, 0xe4,
411 	0x63, 0x96, 0x63, 0x52, 0x20, 0xe0, 0x73, 0x52, 0x10, 0xe0, 0x03, 0x52,
412 	0x14, 0xe0, 0x13, 0x52, 0x18, 0xe0, 0x98, 0x52, 0x74, 0xef, 0x09, 0x12,
413 	0x8c, 0xe0, 0x0b, 0xa1, 0x01, 0x81, 0x01, 0x52, 0x90, 0xe0, 0x65, 0x82,
414 	0x05, 0x12, 0x30, 0xf8, 0x09, 0x00, 0xa8, 0xe0, 0x0a, 0x00, 0x0c, 0xf8,
415 	0x16, 0x00, 0x00, 0xc0, 0x01, 0x52, 0x90, 0xc0, 0x46, 0x41, 0x84, 0xe0,
416 	0x0a, 0x80, 0x0a, 0x4e, 0x9c, 0xe9, 0x1a, 0x00, 0x08, 0xe0, 0x38, 0x01,
417 	0x01, 0x20, 0x00, 0xc0, 0x0b, 0x12, 0x1c, 0xe0, 0x1b, 0x12, 0x24, 0xe0,
418 	0x2b, 0x12, 0x28, 0xe0, 0x03, 0x52, 0x2c, 0xe0, 0x0b, 0x12, 0x20, 0xe0,
419 	0x13, 0x52, 0x34, 0xe0, 0x23, 0x52, 0x38, 0xe0, 0x03, 0x52, 0x30, 0xe0,
420 	0x0c, 0x00, 0x00, 0xe2, 0xf1, 0x98, 0x0c, 0x0c, 0x7c, 0xf2, 0x93, 0xdd,
421 	0x13, 0xa9, 0x00, 0x00, 0xa8, 0xc1, 0x40, 0x00, 0x68, 0x04, 0xa0, 0xe0,
422 	0x40, 0x6c, 0x40, 0x00, 0xe8, 0x34, 0xc8, 0xe0, 0xfc, 0x91, 0x40, 0x00,
423 	0x68, 0x1f, 0xb8, 0xe0, 0x30, 0x16, 0x41, 0x00, 0x28, 0x39, 0x74, 0xe0,
424 	0xb0, 0x7e, 0x40, 0x00, 0xe8, 0x38, 0xc0, 0xe0, 0x30, 0x04, 0x41, 0x00,
425 	0x48, 0x1b, 0x80, 0xe0, 0x30, 0x2e, 0x40, 0x00, 0x88, 0x0c, 0xec, 0xe0,
426 	0x10, 0x9f, 0x40, 0x00, 0x88, 0x08, 0xb4, 0xe0, 0x10, 0x01, 0x41, 0x00,
427 	0x68, 0x01, 0x84, 0xe0, 0x54, 0xd6, 0x40, 0x00, 0xc8, 0x1a, 0x98, 0xe0,
428 	0xd0, 0xc8, 0x40, 0x00, 0x68, 0x08, 0xa0, 0xe0, 0x80, 0xdb, 0x40, 0x00,
429 	0xe8, 0x35, 0x94, 0xe0, 0x74, 0xff, 0x40, 0x00, 0xa8, 0x11, 0x80, 0xe0,
430 	0xf8, 0x89, 0x40, 0x00, 0x88, 0x16, 0xbc, 0xe0, 0x00, 0x90, 0x40, 0x00,
431 	0x08, 0x35, 0xb8, 0xe0, 0x7c, 0x73, 0x40, 0x00, 0x88, 0x1b, 0xc8, 0xe0,
432 	0xf4, 0xff, 0x40, 0x00, 0x68, 0x39, 0x80, 0xe0, 0xa4, 0xa4, 0x40, 0x00,
433 	0xa8, 0x16, 0xb0, 0xe0, 0x50, 0xc9, 0x40, 0x00, 0x28, 0x3a, 0x98, 0xe0,
434 	0x00, 0xb9, 0x00, 0x00, 0xb6, 0x85, 0x00, 0x00,
435 };
436 
437 static const char * const vd55g1_tp_menu[] = {
438 	"Disabled",
439 	"Diagonal Grey Scale",
440 	"Pseudo-random Noise",
441 };
442 
443 static const s64 vd55g1_ev_bias_menu[] = {
444 	-3000, -2500, -2000, -1500, -1000, -500,
445 	    0,
446 	  500,  1000,  1500,  2000,  2500, 3000,
447 };
448 
449 static const char * const vd55g1_hdr_menu[] = {
450 	"No HDR",
451 	/*
452 	 * This mode acquires 2 frames on the sensor, the first one is ditched
453 	 * out and only used for auto exposure data, the second one is output to
454 	 * the host
455 	 */
456 	"Internal subtraction",
457 };
458 
459 static const char * const vd55g1_supply_name[] = {
460 	"vcore",
461 	"vddio",
462 	"vana",
463 };
464 
465 enum vd55g1_hdr_mode {
466 	VD55G1_NO_HDR,
467 	VD55G1_HDR_SUB,
468 };
469 
470 struct vd55g1_mode {
471 	u32 width;
472 	u32 height;
473 };
474 
475 static const u32 vd55g1_mbus_formats_mono[] = {
476 	MEDIA_BUS_FMT_Y8_1X8,
477 	MEDIA_BUS_FMT_Y10_1X10,
478 };
479 
480 /* Format order is : no flip, hflip, vflip, both */
481 static const u32 vd55g1_mbus_formats_bayer[][4] = {
482 	{
483 		MEDIA_BUS_FMT_SRGGB8_1X8,
484 		MEDIA_BUS_FMT_SGRBG8_1X8,
485 		MEDIA_BUS_FMT_SGBRG8_1X8,
486 		MEDIA_BUS_FMT_SBGGR8_1X8,
487 	},
488 	{
489 		MEDIA_BUS_FMT_SRGGB10_1X10,
490 		MEDIA_BUS_FMT_SGRBG10_1X10,
491 		MEDIA_BUS_FMT_SGBRG10_1X10,
492 		MEDIA_BUS_FMT_SBGGR10_1X10,
493 	},
494 };
495 
496 static const struct vd55g1_mode vd55g1_supported_modes[] = {
497 	{
498 		.width = VD55G1_WIDTH,
499 		.height = VD55G1_HEIGHT,
500 	},
501 	{
502 		.width = 800,
503 		.height = VD55G1_HEIGHT,
504 	},
505 	{
506 		.width = 800,
507 		.height = 600,
508 	},
509 	{
510 		.width = 640,
511 		.height = 480,
512 	},
513 	{
514 		.width = 320,
515 		.height = 240,
516 	},
517 };
518 
519 enum vd55g1_expo_state {
520 	VD55G1_EXP_AUTO,
521 	VD55G1_EXP_FREEZE,
522 	VD55G1_EXP_MANUAL,
523 	VD55G1_EXP_SINGLE_STEP,
524 	VD55G1_EXP_BYPASS,
525 };
526 
527 struct vd55g1_vblank_limits {
528 	u16 min;
529 	u16 def;
530 	u16 max;
531 };
532 
533 struct vd55g1 {
534 	struct device *dev;
535 	unsigned int id;
536 	struct v4l2_subdev sd;
537 	struct media_pad pad;
538 	struct regulator_bulk_data supplies[ARRAY_SIZE(vd55g1_supply_name)];
539 	struct gpio_desc *reset_gpio;
540 	struct clk *xclk;
541 	struct regmap *regmap;
542 	u32 xclk_freq;
543 	u16 oif_ctrl;
544 	u8 gpios[VD55G1_NB_GPIOS];
545 	unsigned long ext_leds_mask;
546 	u32 mipi_rate;
547 	u32 pixel_clock;
548 	u64 link_freq;
549 	struct v4l2_ctrl_handler ctrl_handler;
550 	struct v4l2_ctrl *pixel_rate_ctrl;
551 	struct v4l2_ctrl *vblank_ctrl;
552 	struct v4l2_ctrl *hblank_ctrl;
553 	struct {
554 		struct v4l2_ctrl *hflip_ctrl;
555 		struct v4l2_ctrl *vflip_ctrl;
556 	};
557 	struct v4l2_ctrl *patgen_ctrl;
558 	struct {
559 		struct v4l2_ctrl *ae_ctrl;
560 		struct v4l2_ctrl *expo_ctrl;
561 		struct v4l2_ctrl *again_ctrl;
562 		struct v4l2_ctrl *dgain_ctrl;
563 	};
564 	struct v4l2_ctrl *ae_lock_ctrl;
565 	struct v4l2_ctrl *ae_bias_ctrl;
566 	struct v4l2_ctrl *led_ctrl;
567 	struct v4l2_ctrl *hdr_ctrl;
568 };
569 
570 static inline struct vd55g1 *to_vd55g1(struct v4l2_subdev *sd)
571 {
572 	return container_of_const(sd, struct vd55g1, sd);
573 }
574 
575 static inline struct vd55g1 *ctrl_to_vd55g1(struct v4l2_ctrl *ctrl)
576 {
577 	struct v4l2_subdev *sd = &container_of_const(ctrl->handler,
578 						     struct vd55g1,
579 						     ctrl_handler)->sd;
580 
581 	return to_vd55g1(sd);
582 }
583 
584 static unsigned int vd55g1_get_fmt_bpp(u32 code)
585 {
586 	switch (code) {
587 	case MEDIA_BUS_FMT_Y8_1X8:
588 	case MEDIA_BUS_FMT_SRGGB8_1X8:
589 	case MEDIA_BUS_FMT_SGRBG8_1X8:
590 	case MEDIA_BUS_FMT_SGBRG8_1X8:
591 	case MEDIA_BUS_FMT_SBGGR8_1X8:
592 	default:
593 		return 8;
594 
595 	case MEDIA_BUS_FMT_Y10_1X10:
596 	case MEDIA_BUS_FMT_SRGGB10_1X10:
597 	case MEDIA_BUS_FMT_SGRBG10_1X10:
598 	case MEDIA_BUS_FMT_SGBRG10_1X10:
599 	case MEDIA_BUS_FMT_SBGGR10_1X10:
600 		return 10;
601 	}
602 }
603 
604 static unsigned int vd55g1_get_fmt_data_type(u32 code)
605 {
606 	switch (code) {
607 	case MEDIA_BUS_FMT_Y8_1X8:
608 	case MEDIA_BUS_FMT_SRGGB8_1X8:
609 	case MEDIA_BUS_FMT_SGRBG8_1X8:
610 	case MEDIA_BUS_FMT_SGBRG8_1X8:
611 	case MEDIA_BUS_FMT_SBGGR8_1X8:
612 	default:
613 		return MIPI_CSI2_DT_RAW8;
614 
615 	case MEDIA_BUS_FMT_Y10_1X10:
616 	case MEDIA_BUS_FMT_SRGGB10_1X10:
617 	case MEDIA_BUS_FMT_SGRBG10_1X10:
618 	case MEDIA_BUS_FMT_SGBRG10_1X10:
619 	case MEDIA_BUS_FMT_SBGGR10_1X10:
620 		return MIPI_CSI2_DT_RAW10;
621 	}
622 }
623 
624 static u32 vd55g1_get_fmt_code(struct vd55g1 *sensor, u32 code)
625 {
626 	unsigned int i, j;
627 
628 	if (sensor->id == VD55G1_MODEL_ID_VD55G1)
629 		return code;
630 
631 	for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_formats_bayer); i++) {
632 		for (j = 0; j < ARRAY_SIZE(vd55g1_mbus_formats_bayer[i]); j++) {
633 			if (vd55g1_mbus_formats_bayer[i][j] == code)
634 				goto adapt_bayer_pattern;
635 		}
636 	}
637 	dev_warn(sensor->dev, "Unsupported mbus format\n");
638 
639 	return code;
640 
641 adapt_bayer_pattern:
642 	j = 0;
643 	/* In first init_state() call, controls might not be initialized yet */
644 	if (sensor->hflip_ctrl && sensor->vflip_ctrl) {
645 		j = (sensor->hflip_ctrl->val ? 1 : 0) +
646 			(sensor->vflip_ctrl->val ? 2 : 0);
647 	}
648 
649 	return vd55g1_mbus_formats_bayer[i][j];
650 }
651 
652 static s32 vd55g1_get_pixel_rate(struct vd55g1 *sensor,
653 				 struct v4l2_mbus_framefmt *format)
654 {
655 	return sensor->mipi_rate / vd55g1_get_fmt_bpp(format->code);
656 }
657 
658 static unsigned int vd55g1_get_hblank_min(struct vd55g1 *sensor,
659 					  struct v4l2_mbus_framefmt *format,
660 					  struct v4l2_rect *crop)
661 {
662 	u32 mipi_req_line_time;
663 	u32 mipi_req_line_length;
664 	u32 min_line_length;
665 
666 	/* MIPI required time */
667 	mipi_req_line_time = (crop->width *
668 			      vd55g1_get_fmt_bpp(format->code) +
669 			      VD55G1_MIPI_MARGIN) /
670 			      (sensor->mipi_rate / MEGA);
671 	mipi_req_line_length = mipi_req_line_time * sensor->pixel_clock /
672 			       HZ_PER_MHZ;
673 
674 	/* Absolute time required for ADCs to convert pixels */
675 	min_line_length = VD55G1_LINE_LENGTH_MIN;
676 	if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB)
677 		min_line_length = VD55G1_LINE_LENGTH_SUB_MIN;
678 
679 	/* Respect both constraint */
680 	min_line_length = max(min_line_length, mipi_req_line_length);
681 
682 	return min_line_length - crop->width;
683 }
684 
685 static void vd55g1_get_vblank_limits(struct vd55g1 *sensor,
686 				     struct v4l2_rect *crop,
687 				     struct vd55g1_vblank_limits *limits)
688 {
689 	limits->min = VD55G1_VBLANK_MIN;
690 	limits->def = VD55G1_FRAME_LENGTH_DEF - crop->height;
691 	limits->max = VD55G1_VBLANK_MAX - crop->height;
692 }
693 
694 #define vd55g1_read(sensor, reg, val, err) \
695 	cci_read((sensor)->regmap, reg, val, err)
696 
697 #define vd55g1_write(sensor, reg, val, err) \
698 	cci_write((sensor)->regmap, reg, val, err)
699 
700 static int vd55g1_write_array(struct vd55g1 *sensor, u32 reg, unsigned int len,
701 			      const u8 *array, int *err)
702 {
703 	unsigned int chunk_sz = 1024;
704 	unsigned int sz;
705 	int ret = 0;
706 
707 	if (err && *err)
708 		return *err;
709 
710 	/*
711 	 * This loop isn't necessary but in certains conditions (platforms, cpu
712 	 * load, etc.) it has been observed that the bulk write could timeout.
713 	 */
714 	while (len) {
715 		sz = min(len, chunk_sz);
716 		ret = regmap_bulk_write(sensor->regmap, reg, array, sz);
717 		if (ret < 0)
718 			goto out;
719 		len -= sz;
720 		reg += sz;
721 		array += sz;
722 	}
723 
724 out:
725 	if (ret && err)
726 		*err = ret;
727 
728 	return ret;
729 }
730 
731 static int vd55g1_poll_reg(struct vd55g1 *sensor, u32 reg, u8 poll_val,
732 			   int *err)
733 {
734 	unsigned int val = 0;
735 	int ret;
736 
737 	if (err && *err)
738 		return *err;
739 
740 	ret = regmap_read_poll_timeout(sensor->regmap, CCI_REG_ADDR(reg), val,
741 				       (val == poll_val), 2000,
742 				       500 * USEC_PER_MSEC);
743 
744 	if (ret && err)
745 		*err = ret;
746 
747 	return ret;
748 }
749 
750 static int vd55g1_wait_state(struct vd55g1 *sensor, int state, int *err)
751 {
752 	return vd55g1_poll_reg(sensor, VD55G1_REG_SYSTEM_FSM, state, err);
753 }
754 
755 static int vd55g1_prepare_clock_tree(struct vd55g1 *sensor)
756 {
757 	u32 sys_clk, mipi_div, pixel_div;
758 
759 	if (sensor->xclk_freq < VD55G1_XCLK_FREQ_MIN ||
760 	    sensor->xclk_freq > VD55G1_XCLK_FREQ_MAX) {
761 		dev_err(sensor->dev,
762 			"Only %luMhz-%luMhz clock range supported. Provided %lu MHz\n",
763 			VD55G1_XCLK_FREQ_MIN / HZ_PER_MHZ,
764 			VD55G1_XCLK_FREQ_MAX / HZ_PER_MHZ,
765 			sensor->xclk_freq / HZ_PER_MHZ);
766 		return -EINVAL;
767 	}
768 
769 	/* MIPI bus is double data rate */
770 	sensor->mipi_rate = sensor->link_freq * 2;
771 
772 	if (sensor->mipi_rate < VD55G1_MIPI_RATE_MIN ||
773 	    sensor->mipi_rate > VD55G1_MIPI_RATE_MAX) {
774 		dev_err(sensor->dev,
775 			"Only %luMbps-%luMbps data rate range supported. Provided %lu Mbps\n",
776 			VD55G1_MIPI_RATE_MIN / MEGA,
777 			VD55G1_MIPI_RATE_MAX / MEGA,
778 			sensor->mipi_rate / MEGA);
779 		return -EINVAL;
780 	}
781 
782 	if (sensor->mipi_rate <= 300 * MEGA)
783 		mipi_div = 4;
784 	else if (sensor->mipi_rate <= 600 * MEGA)
785 		mipi_div = 2;
786 	else
787 		mipi_div = 1;
788 
789 	sys_clk = sensor->mipi_rate * mipi_div;
790 
791 	if (sys_clk <= 780 * HZ_PER_MHZ)
792 		pixel_div = 5;
793 	else if (sys_clk <= 900 * HZ_PER_MHZ)
794 		pixel_div = 6;
795 	else
796 		pixel_div = 8;
797 
798 	sensor->pixel_clock = sys_clk / pixel_div;
799 
800 	return 0;
801 }
802 
803 static int vd55g1_update_patgen(struct vd55g1 *sensor, u32 patgen_index)
804 {
805 	static const u8 index2val[] = {
806 		0x0, 0x22, 0x28
807 	};
808 	u32 pattern = index2val[patgen_index];
809 	u32 reg = pattern << VD55G1_PATGEN_TYPE_SHIFT;
810 	u8 duster = VD55G1_DUSTER_RING_ENABLE | VD55G1_DUSTER_DYN_ENABLE |
811 		    VD55G1_DUSTER_ENABLE;
812 	int ret = 0;
813 
814 	BUILD_BUG_ON(ARRAY_SIZE(index2val) != ARRAY_SIZE(vd55g1_tp_menu));
815 
816 	if (pattern != 0) {
817 		reg |= VD55G1_PATGEN_ENABLE;
818 		/* Take care of duster to not mess up the test pattern output */
819 		duster = VD55G1_DUSTER_DISABLE;
820 	}
821 
822 	vd55g1_write(sensor, VD55G1_REG_DUSTER_CTRL, duster, &ret);
823 	vd55g1_write(sensor, VD55G1_REG_PATGEN_CTRL, reg, &ret);
824 
825 	return ret;
826 }
827 
828 static int vd55g1_update_expo_cluster(struct vd55g1 *sensor, bool is_auto)
829 {
830 	enum vd55g1_expo_state expo_state = is_auto ? VD55G1_EXP_AUTO :
831 						      VD55G1_EXP_MANUAL;
832 	int ret = 0;
833 
834 	if (sensor->ae_ctrl->is_new)
835 		vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
836 
837 	if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB &&
838 	    sensor->hdr_ctrl->is_new) {
839 		vd55g1_write(sensor, VD55G1_REG_EXP_MODE(1), VD55G1_EXP_BYPASS,
840 			     &ret);
841 		if (ret)
842 			return ret;
843 	}
844 
845 	if (!is_auto && sensor->expo_ctrl->is_new)
846 		vd55g1_write(sensor, VD55G1_REG_MANUAL_COARSE_EXPOSURE,
847 			     sensor->expo_ctrl->val, &ret);
848 
849 	if (!is_auto && sensor->again_ctrl->is_new)
850 		vd55g1_write(sensor, VD55G1_REG_MANUAL_ANALOG_GAIN,
851 			     sensor->again_ctrl->val, &ret);
852 
853 	if (!is_auto && sensor->dgain_ctrl->is_new)
854 		vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN,
855 			     sensor->dgain_ctrl->val, &ret);
856 
857 	return ret;
858 }
859 
860 static int vd55g1_lock_exposure(struct vd55g1 *sensor, u32 lock_val)
861 {
862 	bool ae_lock = lock_val & V4L2_LOCK_EXPOSURE;
863 	enum vd55g1_expo_state expo_state = ae_lock ? VD55G1_EXP_FREEZE :
864 						      VD55G1_EXP_AUTO;
865 	int ret = 0;
866 
867 	if (sensor->ae_ctrl->val == V4L2_EXPOSURE_AUTO)
868 		vd55g1_write(sensor, VD55G1_REG_EXP_MODE(0), expo_state, &ret);
869 
870 	return ret;
871 }
872 
873 static int vd55g1_read_expo_cluster(struct vd55g1 *sensor)
874 {
875 	u64 exposure = 0;
876 	u64 again = 0;
877 	u64 dgain = 0;
878 	int ret = 0;
879 
880 	vd55g1_read(sensor, VD55G1_REG_APPLIED_COARSE_EXPOSURE, &exposure,
881 		    &ret);
882 	vd55g1_read(sensor, VD55G1_REG_APPLIED_ANALOG_GAIN, &again, &ret);
883 	vd55g1_read(sensor, VD55G1_REG_APPLIED_DIGITAL_GAIN, &dgain, &ret);
884 	if (ret)
885 		return ret;
886 
887 	sensor->expo_ctrl->cur.val = exposure;
888 	sensor->again_ctrl->cur.val = again;
889 	sensor->dgain_ctrl->cur.val = dgain;
890 
891 	return 0;
892 }
893 
894 static int vd55g1_update_frame_length(struct vd55g1 *sensor,
895 				      unsigned int frame_length)
896 {
897 	int ret = 0;
898 
899 	if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB)
900 		vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(1), frame_length,
901 			     &ret);
902 	vd55g1_write(sensor, VD55G1_REG_FRAME_LENGTH(0), frame_length, &ret);
903 
904 	return ret;
905 }
906 
907 static int vd55g1_update_exposure_target(struct vd55g1 *sensor, int index)
908 {
909 	/*
910 	 * Find auto exposure target with: default target exposure * 2^EV
911 	 * Defaut target exposure being 27 for the sensor.
912 	 */
913 	static const unsigned int index2exposure_target[] = {
914 		3, 5, 7, 10, 14, 19, 27, 38, 54, 76, 108, 153, 216,
915 	};
916 	int exposure_target = index2exposure_target[index];
917 
918 	return vd55g1_write(sensor, VD55G1_REG_AE_TARGET_PERCENTAGE,
919 			    exposure_target, NULL);
920 }
921 
922 static int vd55g1_apply_cold_start(struct vd55g1 *sensor,
923 				   struct v4l2_rect *crop)
924 {
925 	/*
926 	 * Cold start register is a single register expressed as exposure time
927 	 * in us. This differ from status registers being a combination of
928 	 * exposure, digital gain, and analog gain, requiring the following
929 	 * format conversion.
930 	 */
931 	unsigned int line_length = crop->width + sensor->hblank_ctrl->val;
932 	unsigned int line_time_us = DIV_ROUND_UP(line_length * MEGA,
933 						 sensor->pixel_clock);
934 	u8 d_gain = DIV_ROUND_CLOSEST(sensor->dgain_ctrl->val, 1 << 8);
935 	u8 a_gain = DIV_ROUND_CLOSEST(32, (32 - sensor->again_ctrl->val));
936 	unsigned int expo_us = sensor->expo_ctrl->val * d_gain * a_gain *
937 			       line_time_us;
938 	int ret = 0;
939 
940 	vd55g1_write(sensor, VD55G1_REG_AE_FORCE_COLDSTART, 1, &ret);
941 	vd55g1_write(sensor, VD55G1_REG_AE_COLDSTART_EXP_TIME, expo_us, &ret);
942 
943 	return ret;
944 }
945 
946 static void vd55g1_update_pad_fmt(struct vd55g1 *sensor,
947 				  const struct vd55g1_mode *mode, u32 code,
948 				  struct v4l2_mbus_framefmt *fmt)
949 {
950 	fmt->code = vd55g1_get_fmt_code(sensor, code);
951 	fmt->width = mode->width;
952 	fmt->height = mode->height;
953 	fmt->colorspace = V4L2_COLORSPACE_RAW;
954 	fmt->field = V4L2_FIELD_NONE;
955 	fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
956 	fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
957 	fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
958 }
959 
960 static int vd55g1_update_hdr_mode(struct vd55g1 *sensor)
961 {
962 	int ret = 0;
963 
964 	switch (sensor->hdr_ctrl->val) {
965 	case VD55G1_NO_HDR:
966 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
967 			     VD55G1_EXPOSURE_MAX_COARSE_DEF, &ret);
968 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES, 0, &ret);
969 		vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0, &ret);
970 
971 		vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 0, &ret);
972 
973 		vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
974 			     VD55G1_VT_MODE_NORMAL, &ret);
975 		vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
976 			     VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
977 		break;
978 	case VD55G1_HDR_SUB:
979 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_MAX_COARSE,
980 			     VD55G1_EXPOSURE_MAX_COARSE_SUB, &ret);
981 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_USE_CASES,
982 			     VD55G1_EXPOSURE_USE_CASES_MULTI_CONTEXT, &ret);
983 		vd55g1_write(sensor, VD55G1_REG_NEXT_CTX, 0x0001, &ret);
984 
985 		vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX0, 1, &ret);
986 		vd55g1_write(sensor, VD55G1_REG_CTX_REPEAT_COUNT_CTX1, 1, &ret);
987 
988 		vd55g1_write(sensor, VD55G1_REG_VT_MODE(0),
989 			     VD55G1_VT_MODE_NORMAL, &ret);
990 		vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(0),
991 			     VD55G1_MASK_FRAME_CTRL_MASK, &ret);
992 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(0), 0, &ret);
993 		vd55g1_write(sensor, VD55G1_REG_VT_MODE(1),
994 			     VD55G1_VT_MODE_SUBTRACTION, &ret);
995 		vd55g1_write(sensor, VD55G1_REG_MASK_FRAME_CTRL(1),
996 			     VD55G1_MASK_FRAME_CTRL_OUTPUT, &ret);
997 		vd55g1_write(sensor, VD55G1_REG_EXPOSURE_INSTANCE(1), 1, &ret);
998 		break;
999 	default:
1000 		ret = -EINVAL;
1001 	}
1002 
1003 	return ret;
1004 }
1005 
1006 static int vd55g1_set_framefmt(struct vd55g1 *sensor,
1007 			       struct v4l2_mbus_framefmt *format,
1008 			       struct v4l2_rect *crop)
1009 {
1010 	u8 binning;
1011 	int ret = 0;
1012 
1013 	vd55g1_write(sensor, VD55G1_REG_FORMAT_CTRL,
1014 		     vd55g1_get_fmt_bpp(format->code), &ret);
1015 	vd55g1_write(sensor, VD55G1_REG_OIF_IMG_CTRL,
1016 		     vd55g1_get_fmt_data_type(format->code), &ret);
1017 
1018 	switch (crop->width / format->width) {
1019 	case 1:
1020 	default:
1021 		binning = VD55G1_READOUT_CTRL_BIN_MODE_NORMAL;
1022 		break;
1023 	case 2:
1024 		binning = VD55G1_READOUT_CTRL_BIN_MODE_DIGITAL_X2;
1025 		break;
1026 	}
1027 	vd55g1_write(sensor, VD55G1_REG_READOUT_CTRL, binning, &ret);
1028 
1029 	vd55g1_write(sensor, VD55G1_REG_X_START(0), crop->left, &ret);
1030 	vd55g1_write(sensor, VD55G1_REG_X_WIDTH(0), crop->width, &ret);
1031 	vd55g1_write(sensor, VD55G1_REG_Y_START(0), crop->top, &ret);
1032 	vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(0), crop->height, &ret);
1033 
1034 	vd55g1_write(sensor, VD55G1_REG_X_START(1), crop->left, &ret);
1035 	vd55g1_write(sensor, VD55G1_REG_X_WIDTH(1), crop->width, &ret);
1036 	vd55g1_write(sensor, VD55G1_REG_Y_START(1), crop->top, &ret);
1037 	vd55g1_write(sensor, VD55G1_REG_Y_HEIGHT(1), crop->height, &ret);
1038 
1039 	return ret;
1040 }
1041 
1042 static int vd55g1_update_gpios(struct vd55g1 *sensor, unsigned long gpio_mask)
1043 {
1044 	unsigned long io;
1045 	u8 gpio_val;
1046 	int ret = 0;
1047 
1048 	for_each_set_bit(io, &gpio_mask, VD55G1_NB_GPIOS) {
1049 		gpio_val = sensor->gpios[io];
1050 
1051 		if (gpio_val == VD55G1_GPIO_MODE_STROBE &&
1052 		    sensor->led_ctrl->val == V4L2_FLASH_LED_MODE_NONE) {
1053 			gpio_val = VD55G1_GPIO_MODE_IN;
1054 			if (sensor->hdr_ctrl->val == VD55G1_HDR_SUB) {
1055 				/* Make its context 1 counterpart strobe too */
1056 				vd55g1_write(sensor,
1057 					     VD55G1_REG_GPIO_0_CTRL(1) + io,
1058 					     gpio_val, &ret);
1059 			}
1060 		}
1061 
1062 		ret = vd55g1_write(sensor, VD55G1_REG_GPIO_0_CTRL(0) + io,
1063 				   gpio_val, &ret);
1064 	}
1065 
1066 	return ret;
1067 }
1068 
1069 static int vd55g1_ro_ctrls_setup(struct vd55g1 *sensor, struct v4l2_rect *crop)
1070 {
1071 	return vd55g1_write(sensor, VD55G1_REG_LINE_LENGTH,
1072 			    crop->width + sensor->hblank_ctrl->val, NULL);
1073 }
1074 
1075 static void vd55g1_grab_ctrls(struct vd55g1 *sensor, bool enable)
1076 {
1077 	/* These settings cannot change during stream */
1078 	v4l2_ctrl_grab(sensor->hflip_ctrl, enable);
1079 	v4l2_ctrl_grab(sensor->vflip_ctrl, enable);
1080 	v4l2_ctrl_grab(sensor->patgen_ctrl, enable);
1081 	v4l2_ctrl_grab(sensor->hdr_ctrl, enable);
1082 }
1083 
1084 static int vd55g1_enable_streams(struct v4l2_subdev *sd,
1085 				 struct v4l2_subdev_state *state, u32 pad,
1086 				 u64 streams_mask)
1087 {
1088 	struct vd55g1 *sensor = to_vd55g1(sd);
1089 	struct v4l2_rect *crop =
1090 		v4l2_subdev_state_get_crop(state, 0);
1091 	struct v4l2_mbus_framefmt *format =
1092 		v4l2_subdev_state_get_format(state, 0);
1093 	int ret;
1094 
1095 	ret = pm_runtime_resume_and_get(sensor->dev);
1096 	if (ret < 0)
1097 		return ret;
1098 
1099 	/* Configure output */
1100 	vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,
1101 		     sensor->mipi_rate, &ret);
1102 	vd55g1_write(sensor, VD55G1_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
1103 	vd55g1_write(sensor, VD55G1_REG_ISL_ENABLE, 0, &ret);
1104 	if (ret)
1105 		goto err_rpm_put;
1106 
1107 	ret = vd55g1_set_framefmt(sensor, format, crop);
1108 	if (ret)
1109 		goto err_rpm_put;
1110 
1111 	/* Setup default GPIO values; could be overridden by V4L2 ctrl setup */
1112 	ret = vd55g1_update_gpios(sensor, GENMASK(VD55G1_NB_GPIOS - 1, 0));
1113 	if (ret)
1114 		goto err_rpm_put;
1115 
1116 	ret = vd55g1_apply_cold_start(sensor, crop);
1117 	if (ret)
1118 		goto err_rpm_put;
1119 
1120 	/* Apply settings from V4L2 ctrls */
1121 	ret = __v4l2_ctrl_handler_setup(&sensor->ctrl_handler);
1122 	if (ret)
1123 		goto err_rpm_put;
1124 
1125 	/* Also apply settings from read-only V4L2 ctrls */
1126 	ret = vd55g1_ro_ctrls_setup(sensor, crop);
1127 	if (ret)
1128 		goto err_rpm_put;
1129 
1130 	/* Start streaming */
1131 	vd55g1_write(sensor, VD55G1_REG_STBY, VD55G1_STBY_START_STREAM, &ret);
1132 	vd55g1_poll_reg(sensor, VD55G1_REG_STBY, 0, &ret);
1133 	vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_STREAMING, &ret);
1134 	if (ret)
1135 		goto err_rpm_put;
1136 
1137 	vd55g1_grab_ctrls(sensor, true);
1138 
1139 	return 0;
1140 
1141 err_rpm_put:
1142 	pm_runtime_put(sensor->dev);
1143 	return -EINVAL;
1144 }
1145 
1146 static int vd55g1_disable_streams(struct v4l2_subdev *sd,
1147 				  struct v4l2_subdev_state *state, u32 pad,
1148 				  u64 streams_mask)
1149 {
1150 	struct vd55g1 *sensor = to_vd55g1(sd);
1151 	int ret = 0;
1152 
1153 	/* Retrieve Expo cluster to enable coldstart of AE */
1154 	ret = vd55g1_read_expo_cluster(sensor);
1155 
1156 	vd55g1_write(sensor, VD55G1_REG_STREAMING, VD55G1_STREAMING_STOP_STREAM,
1157 		     &ret);
1158 	vd55g1_poll_reg(sensor, VD55G1_REG_STREAMING, 0, &ret);
1159 	vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, &ret);
1160 
1161 	if (ret)
1162 		dev_warn(sensor->dev, "Can't disable stream\n");
1163 
1164 	vd55g1_grab_ctrls(sensor, false);
1165 
1166 	pm_runtime_put_autosuspend(sensor->dev);
1167 
1168 	return ret;
1169 }
1170 
1171 static int vd55g1_patch(struct vd55g1 *sensor)
1172 {
1173 	u64 patch;
1174 	int ret = 0;
1175 
1176 	/* vd55g1 needs a patch while vd65g4 does not */
1177 	if (sensor->id == VD55G1_MODEL_ID_VD55G1) {
1178 		vd55g1_write_array(sensor, VD55G1_REG_FWPATCH_START_ADDR,
1179 				   sizeof(vd55g1_patch_array),
1180 				   vd55g1_patch_array, &ret);
1181 		vd55g1_write(sensor, VD55G1_REG_BOOT,
1182 			     VD55G1_BOOT_PATCH_AND_BOOT, &ret);
1183 		vd55g1_poll_reg(sensor, VD55G1_REG_BOOT, 0, &ret);
1184 		if (ret) {
1185 			dev_err(sensor->dev, "Failed to apply patch\n");
1186 			return ret;
1187 		}
1188 
1189 		vd55g1_read(sensor, VD55G1_REG_FWPATCH_REVISION, &patch, &ret);
1190 		if (patch != (VD55G1_FWPATCH_REVISION_MAJOR << 8) +
1191 		    VD55G1_FWPATCH_REVISION_MINOR) {
1192 			dev_err(sensor->dev, "Bad patch version expected %d.%d got %d.%d\n",
1193 				VD55G1_FWPATCH_REVISION_MAJOR,
1194 				VD55G1_FWPATCH_REVISION_MINOR,
1195 				(u8)(patch >> 8), (u8)(patch & 0xff));
1196 			return -ENODEV;
1197 		}
1198 		dev_dbg(sensor->dev, "patch %d.%d applied\n",
1199 			(u8)(patch >> 8), (u8)(patch & 0xff));
1200 
1201 	} else {
1202 		vd55g1_write(sensor, VD55G1_REG_BOOT, VD55G1_BOOT_BOOT, &ret);
1203 		vd55g1_poll_reg(sensor, VD55G1_REG_BOOT, 0, &ret);
1204 		if (ret) {
1205 			dev_err(sensor->dev, "Failed to boot\n");
1206 			return ret;
1207 		}
1208 	}
1209 
1210 	ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_SW_STBY, NULL);
1211 	if (ret) {
1212 		dev_err(sensor->dev, "Sensor waiting after boot failed\n");
1213 		return ret;
1214 	}
1215 
1216 	return 0;
1217 }
1218 
1219 static int vd55g1_get_selection(struct v4l2_subdev *sd,
1220 				struct v4l2_subdev_state *sd_state,
1221 				struct v4l2_subdev_selection *sel)
1222 {
1223 	const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(sd_state, 0);
1224 
1225 	switch (sel->target) {
1226 	case V4L2_SEL_TGT_CROP:
1227 		sel->r = *crop;
1228 		return 0;
1229 	case V4L2_SEL_TGT_NATIVE_SIZE:
1230 	case V4L2_SEL_TGT_CROP_DEFAULT:
1231 	case V4L2_SEL_TGT_CROP_BOUNDS:
1232 		sel->r.top = 0;
1233 		sel->r.left = 0;
1234 		sel->r.width = VD55G1_WIDTH;
1235 		sel->r.height = VD55G1_HEIGHT;
1236 		return 0;
1237 	}
1238 
1239 	return -EINVAL;
1240 }
1241 
1242 static int vd55g1_enum_mbus_code(struct v4l2_subdev *sd,
1243 				 struct v4l2_subdev_state *sd_state,
1244 				 struct v4l2_subdev_mbus_code_enum *code)
1245 {
1246 	struct vd55g1 *sensor = to_vd55g1(sd);
1247 	u32 base_code;
1248 
1249 	if (sensor->id == VD55G1_MODEL_ID_VD55G1) {
1250 		if (code->index >= ARRAY_SIZE(vd55g1_mbus_formats_mono))
1251 			return -EINVAL;
1252 		base_code = vd55g1_mbus_formats_mono[code->index];
1253 	} else {
1254 		if (code->index >= ARRAY_SIZE(vd55g1_mbus_formats_bayer))
1255 			return -EINVAL;
1256 		base_code = vd55g1_mbus_formats_bayer[code->index][0];
1257 	}
1258 	code->code = vd55g1_get_fmt_code(sensor, base_code);
1259 
1260 	return 0;
1261 }
1262 
1263 static int vd55g1_new_format_change_controls(struct vd55g1 *sensor,
1264 					     struct v4l2_mbus_framefmt *format,
1265 					     struct v4l2_rect *crop)
1266 {
1267 	struct vd55g1_vblank_limits vblank;
1268 	unsigned int hblank;
1269 	unsigned int frame_length = 0;
1270 	unsigned int expo_max;
1271 	int ret;
1272 
1273 	/* Reset vblank and frame length to default */
1274 	vd55g1_get_vblank_limits(sensor, crop, &vblank);
1275 	ret = __v4l2_ctrl_modify_range(sensor->vblank_ctrl, vblank.min,
1276 				       vblank.max, 1, vblank.def);
1277 	if (ret)
1278 		return ret;
1279 
1280 	/* Max exposure changes with vblank */
1281 	frame_length = crop->height + sensor->vblank_ctrl->val;
1282 	expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1283 	ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max, 1,
1284 				       VD55G1_EXPO_DEF);
1285 	if (ret)
1286 		return ret;
1287 
1288 	/* Update pixel rate to reflect new bpp */
1289 	ret = __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl,
1290 				       vd55g1_get_pixel_rate(sensor, format));
1291 	if (ret)
1292 		return ret;
1293 
1294 	/* Update hblank according to new width */
1295 	hblank = vd55g1_get_hblank_min(sensor, format, crop);
1296 	ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl, hblank, hblank, 1,
1297 				       hblank);
1298 
1299 	return ret;
1300 }
1301 
1302 static int vd55g1_set_pad_fmt(struct v4l2_subdev *sd,
1303 			      struct v4l2_subdev_state *sd_state,
1304 			      struct v4l2_subdev_format *sd_fmt)
1305 {
1306 	struct vd55g1 *sensor = to_vd55g1(sd);
1307 	const struct vd55g1_mode *new_mode;
1308 	struct v4l2_mbus_framefmt *format;
1309 	struct v4l2_rect pad_crop;
1310 	unsigned int binning;
1311 
1312 	new_mode = v4l2_find_nearest_size(vd55g1_supported_modes,
1313 					  ARRAY_SIZE(vd55g1_supported_modes),
1314 					  width, height, sd_fmt->format.width,
1315 					  sd_fmt->format.height);
1316 
1317 	vd55g1_update_pad_fmt(sensor, new_mode, sd_fmt->format.code,
1318 			      &sd_fmt->format);
1319 
1320 	/*
1321 	 * Use binning to maximize the crop rectangle size, and centre it in the
1322 	 * sensor.
1323 	 */
1324 	binning = min(VD55G1_WIDTH / sd_fmt->format.width,
1325 		      VD55G1_HEIGHT / sd_fmt->format.height);
1326 	binning = min(binning, 2U);
1327 	pad_crop.width = sd_fmt->format.width * binning;
1328 	pad_crop.height = sd_fmt->format.height * binning;
1329 	pad_crop.left = (VD55G1_WIDTH - pad_crop.width) / 2;
1330 	pad_crop.top = (VD55G1_HEIGHT - pad_crop.height) / 2;
1331 
1332 	format = v4l2_subdev_state_get_format(sd_state, sd_fmt->pad);
1333 
1334 	*format = sd_fmt->format;
1335 
1336 	*v4l2_subdev_state_get_crop(sd_state, sd_fmt->pad) = pad_crop;
1337 	if (sd_fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1338 		return vd55g1_new_format_change_controls(sensor,
1339 							 &sd_fmt->format,
1340 							 &pad_crop);
1341 
1342 	return 0;
1343 }
1344 
1345 static int vd55g1_init_state(struct v4l2_subdev *sd,
1346 			     struct v4l2_subdev_state *sd_state)
1347 {
1348 	struct vd55g1 *sensor = to_vd55g1(sd);
1349 	struct v4l2_subdev_format fmt = { 0 };
1350 	struct v4l2_subdev_route routes[] = {
1351 		{ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE }
1352 	};
1353 	struct v4l2_subdev_krouting routing = {
1354 	    .num_routes = ARRAY_SIZE(routes),
1355 	    .routes = routes,
1356 	};
1357 	int ret;
1358 
1359 	/* Needed by v4l2_subdev_s_stream_helper(), even with 1 stream only */
1360 	ret = v4l2_subdev_set_routing(sd, sd_state, &routing);
1361 	if (ret)
1362 		return ret;
1363 
1364 	vd55g1_update_pad_fmt(sensor, &vd55g1_supported_modes[VD55G1_MODE_DEF],
1365 			      vd55g1_get_fmt_code(sensor, VD55G1_MBUS_CODE_DEF),
1366 			      &fmt.format);
1367 
1368 	return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
1369 }
1370 
1371 static int vd55g1_enum_frame_size(struct v4l2_subdev *sd,
1372 				  struct v4l2_subdev_state *sd_state,
1373 				  struct v4l2_subdev_frame_size_enum *fse)
1374 {
1375 	struct vd55g1 *sensor = to_vd55g1(sd);
1376 	u32 code;
1377 
1378 	if (fse->index >= ARRAY_SIZE(vd55g1_supported_modes))
1379 		return -EINVAL;
1380 
1381 	code = vd55g1_get_fmt_code(sensor, fse->code);
1382 	if (fse->code != code)
1383 		return -EINVAL;
1384 
1385 	fse->min_width = vd55g1_supported_modes[fse->index].width;
1386 	fse->max_width = fse->min_width;
1387 	fse->min_height = vd55g1_supported_modes[fse->index].height;
1388 	fse->max_height = fse->min_height;
1389 
1390 	return 0;
1391 }
1392 
1393 static const struct v4l2_subdev_internal_ops vd55g1_internal_ops = {
1394 	.init_state = vd55g1_init_state,
1395 };
1396 
1397 static const struct v4l2_subdev_pad_ops vd55g1_pad_ops = {
1398 	.enum_mbus_code = vd55g1_enum_mbus_code,
1399 	.get_fmt = v4l2_subdev_get_fmt,
1400 	.set_fmt = vd55g1_set_pad_fmt,
1401 	.get_selection = vd55g1_get_selection,
1402 	.enum_frame_size = vd55g1_enum_frame_size,
1403 	.enable_streams = vd55g1_enable_streams,
1404 	.disable_streams = vd55g1_disable_streams,
1405 };
1406 
1407 static const struct v4l2_subdev_video_ops vd55g1_video_ops = {
1408 	.s_stream = v4l2_subdev_s_stream_helper,
1409 };
1410 
1411 static const struct v4l2_subdev_ops vd55g1_subdev_ops = {
1412 	.video = &vd55g1_video_ops,
1413 	.pad = &vd55g1_pad_ops,
1414 };
1415 
1416 static int vd55g1_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1417 {
1418 	struct vd55g1 *sensor = ctrl_to_vd55g1(ctrl);
1419 	int ret = 0;
1420 
1421 	/* Interact with HW only when it is powered ON */
1422 	if (!pm_runtime_get_if_in_use(sensor->dev))
1423 		return 0;
1424 
1425 	switch (ctrl->id) {
1426 	case V4L2_CID_EXPOSURE_AUTO:
1427 		ret = vd55g1_read_expo_cluster(sensor);
1428 		break;
1429 	default:
1430 		ret = -EINVAL;
1431 		break;
1432 	}
1433 
1434 	pm_runtime_put_autosuspend(sensor->dev);
1435 
1436 	return ret;
1437 }
1438 
1439 static int vd55g1_s_ctrl(struct v4l2_ctrl *ctrl)
1440 {
1441 	struct vd55g1 *sensor = ctrl_to_vd55g1(ctrl);
1442 	unsigned int frame_length = 0;
1443 	unsigned int expo_max;
1444 	struct v4l2_subdev_state *state =
1445 		v4l2_subdev_get_locked_active_state(&sensor->sd);
1446 	struct v4l2_rect *crop =
1447 		v4l2_subdev_state_get_crop(state, 0);
1448 	struct v4l2_mbus_framefmt *format =
1449 		v4l2_subdev_state_get_format(state, 0);
1450 	unsigned int hblank = vd55g1_get_hblank_min(sensor, format, crop);
1451 	bool is_auto = false;
1452 	int ret = 0;
1453 
1454 	if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
1455 		return 0;
1456 
1457 	/* Update controls state, range, etc. whatever the state of the HW */
1458 	switch (ctrl->id) {
1459 	case V4L2_CID_VBLANK:
1460 		frame_length = crop->height + ctrl->val;
1461 		expo_max = frame_length - VD55G1_EXPO_MAX_TERM;
1462 		ret = __v4l2_ctrl_modify_range(sensor->expo_ctrl, 0, expo_max,
1463 					       1, VD55G1_EXPO_DEF);
1464 		break;
1465 	case V4L2_CID_EXPOSURE_AUTO:
1466 		is_auto = (ctrl->val == V4L2_EXPOSURE_AUTO);
1467 		__v4l2_ctrl_grab(sensor->ae_lock_ctrl, !is_auto);
1468 		__v4l2_ctrl_grab(sensor->ae_bias_ctrl, !is_auto);
1469 		break;
1470 	case V4L2_CID_HDR_SENSOR_MODE:
1471 		/* Discriminate if the userspace changed the control value */
1472 		if (ctrl->val != ctrl->cur.val) {
1473 			/* Max horizontal blanking changes with hdr mode */
1474 			ret = __v4l2_ctrl_modify_range(sensor->hblank_ctrl,
1475 						       hblank, hblank, 1,
1476 						       hblank);
1477 		}
1478 		break;
1479 	default:
1480 		break;
1481 	}
1482 
1483 	/* Don't modify hardware if controls modification failed */
1484 	if (ret)
1485 		return ret;
1486 
1487 	/* Interact with HW only when it is powered ON */
1488 	if (!pm_runtime_get_if_in_use(sensor->dev))
1489 		return 0;
1490 
1491 	switch (ctrl->id) {
1492 	case V4L2_CID_HFLIP:
1493 		ret = vd55g1_write(sensor, VD55G1_REG_ORIENTATION,
1494 				   sensor->hflip_ctrl->val |
1495 					   (sensor->vflip_ctrl->val << 1),
1496 				   NULL);
1497 		break;
1498 	case V4L2_CID_TEST_PATTERN:
1499 		ret = vd55g1_update_patgen(sensor, ctrl->val);
1500 		break;
1501 	case V4L2_CID_EXPOSURE_AUTO:
1502 		ret = vd55g1_update_expo_cluster(sensor, is_auto);
1503 		break;
1504 	case V4L2_CID_3A_LOCK:
1505 		ret = vd55g1_lock_exposure(sensor, ctrl->val);
1506 		break;
1507 	case V4L2_CID_AUTO_EXPOSURE_BIAS:
1508 		/*
1509 		 * We use auto exposure target percentage register to control
1510 		 * exposure bias for more precision.
1511 		 */
1512 		ret = vd55g1_update_exposure_target(sensor, ctrl->val);
1513 		break;
1514 	case V4L2_CID_VBLANK:
1515 		ret = vd55g1_update_frame_length(sensor, frame_length);
1516 		break;
1517 	case V4L2_CID_FLASH_LED_MODE:
1518 		ret = vd55g1_update_gpios(sensor, sensor->ext_leds_mask);
1519 		break;
1520 	case V4L2_CID_HDR_SENSOR_MODE:
1521 		ret = vd55g1_update_hdr_mode(sensor);
1522 		break;
1523 	default:
1524 		ret = -EINVAL;
1525 		break;
1526 	}
1527 
1528 	pm_runtime_put_autosuspend(sensor->dev);
1529 
1530 	return ret;
1531 }
1532 
1533 static const struct v4l2_ctrl_ops vd55g1_ctrl_ops = {
1534 	.g_volatile_ctrl = vd55g1_g_volatile_ctrl,
1535 	.s_ctrl = vd55g1_s_ctrl,
1536 };
1537 
1538 static int vd55g1_init_ctrls(struct vd55g1 *sensor)
1539 {
1540 	const struct v4l2_ctrl_ops *ops = &vd55g1_ctrl_ops;
1541 	struct v4l2_ctrl_handler *hdl = &sensor->ctrl_handler;
1542 	struct v4l2_ctrl *ctrl;
1543 	struct v4l2_fwnode_device_properties fwnode_props;
1544 	struct vd55g1_vblank_limits vblank;
1545 	unsigned int hblank;
1546 	struct v4l2_subdev_state *state =
1547 		v4l2_subdev_lock_and_get_active_state(&sensor->sd);
1548 	struct v4l2_rect *crop =
1549 		v4l2_subdev_state_get_crop(state, 0);
1550 	struct v4l2_mbus_framefmt *format =
1551 		v4l2_subdev_state_get_format(state, 0);
1552 	s32 pixel_rate = vd55g1_get_pixel_rate(sensor, format);
1553 	int ret;
1554 
1555 	v4l2_ctrl_handler_init(hdl, 16);
1556 
1557 	/* Flip cluster */
1558 	sensor->hflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
1559 					       0, 1, 1, 0);
1560 	if (sensor->hflip_ctrl)
1561 		sensor->hflip_ctrl->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1562 	sensor->vflip_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
1563 					       0, 1, 1, 0);
1564 	if (sensor->vflip_ctrl)
1565 		sensor->vflip_ctrl->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1566 	v4l2_ctrl_cluster(2, &sensor->hflip_ctrl);
1567 
1568 	/* Exposition cluster */
1569 	sensor->ae_ctrl = v4l2_ctrl_new_std_menu(hdl, ops,
1570 						 V4L2_CID_EXPOSURE_AUTO, 1,
1571 						 ~0x3, V4L2_EXPOSURE_AUTO);
1572 	sensor->again_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
1573 					       0, 0x1c, 1, VD55G1_AGAIN_DEF);
1574 	sensor->dgain_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DIGITAL_GAIN,
1575 					       256, 0xffff, 1,
1576 					       VD55G1_DGAIN_DEF);
1577 	sensor->expo_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0,
1578 					      VD55G1_FRAME_LENGTH_DEF -
1579 					      VD55G1_EXPO_MAX_TERM,
1580 					      1, VD55G1_EXPO_DEF);
1581 	v4l2_ctrl_auto_cluster(4, &sensor->ae_ctrl, V4L2_EXPOSURE_MANUAL, true);
1582 
1583 	sensor->patgen_ctrl =
1584 		v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
1585 					     ARRAY_SIZE(vd55g1_tp_menu) - 1, 0,
1586 					     0, vd55g1_tp_menu);
1587 	ctrl = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
1588 				      0, 0, &sensor->link_freq);
1589 	if (ctrl)
1590 		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1591 	sensor->pixel_rate_ctrl = v4l2_ctrl_new_std(hdl, ops,
1592 						    V4L2_CID_PIXEL_RATE, 1,
1593 						    INT_MAX, 1,
1594 						    pixel_rate);
1595 	if (sensor->pixel_rate_ctrl)
1596 		sensor->pixel_rate_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1597 	sensor->ae_lock_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_3A_LOCK,
1598 						 0, 1, 0, 0);
1599 	sensor->ae_bias_ctrl =
1600 		v4l2_ctrl_new_int_menu(hdl, ops,
1601 				       V4L2_CID_AUTO_EXPOSURE_BIAS,
1602 				       ARRAY_SIZE(vd55g1_ev_bias_menu) - 1,
1603 				       ARRAY_SIZE(vd55g1_ev_bias_menu) / 2,
1604 				       vd55g1_ev_bias_menu);
1605 	sensor->hdr_ctrl =
1606 		v4l2_ctrl_new_std_menu_items(hdl, ops,
1607 					     V4L2_CID_HDR_SENSOR_MODE,
1608 					     ARRAY_SIZE(vd55g1_hdr_menu) - 1, 0,
1609 					     VD55G1_NO_HDR, vd55g1_hdr_menu);
1610 	hblank = vd55g1_get_hblank_min(sensor, format, crop);
1611 	sensor->hblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK,
1612 						hblank, hblank, 1, hblank);
1613 	if (sensor->hblank_ctrl)
1614 		sensor->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1615 	vd55g1_get_vblank_limits(sensor, crop, &vblank);
1616 	sensor->vblank_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK,
1617 						vblank.min, vblank.max,
1618 						1, vblank.def);
1619 
1620 	/* Additional controls based on device tree properties */
1621 	if (sensor->ext_leds_mask) {
1622 		sensor->led_ctrl =
1623 			v4l2_ctrl_new_std_menu(hdl, ops,
1624 					       V4L2_CID_FLASH_LED_MODE,
1625 					       V4L2_FLASH_LED_MODE_FLASH, 0,
1626 					       V4L2_FLASH_LED_MODE_NONE);
1627 	}
1628 
1629 	ret = v4l2_fwnode_device_parse(sensor->dev, &fwnode_props);
1630 	if (ret)
1631 		goto free_ctrls;
1632 
1633 	ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &fwnode_props);
1634 	if (ret)
1635 		goto free_ctrls;
1636 
1637 	sensor->sd.ctrl_handler = hdl;
1638 	goto unlock_state;
1639 
1640 free_ctrls:
1641 	v4l2_ctrl_handler_free(hdl);
1642 unlock_state:
1643 	v4l2_subdev_unlock_state(state);
1644 	return ret;
1645 }
1646 
1647 static int vd55g1_detect(struct vd55g1 *sensor)
1648 {
1649 	unsigned int dt_id = (uintptr_t)device_get_match_data(sensor->dev);
1650 	u64 rev, id;
1651 	int ret;
1652 
1653 	ret = vd55g1_read(sensor, VD55G1_REG_MODEL_ID, &id, NULL);
1654 	if (ret)
1655 		return ret;
1656 
1657 	if (id != VD55G1_MODEL_ID_VD55G1 && id != VD55G1_MODEL_ID_VD65G4) {
1658 		dev_warn(sensor->dev, "Unsupported sensor id 0x%x\n",
1659 			 (u32)id);
1660 		return -ENODEV;
1661 	}
1662 	if (id != dt_id) {
1663 		dev_err(sensor->dev, "Probed sensor %s and device tree definition (%s) mismatch",
1664 			VD55G1_MODEL_ID_NAME(id), VD55G1_MODEL_ID_NAME(dt_id));
1665 		return -ENODEV;
1666 	}
1667 	sensor->id = id;
1668 
1669 	ret = vd55g1_read(sensor, VD55G1_REG_REVISION, &rev, NULL);
1670 	if (ret)
1671 		return ret;
1672 
1673 	if ((id == VD55G1_MODEL_ID_VD55G1 && rev != VD55G1_REVISION_CCB) &&
1674 	    (id == VD55G1_MODEL_ID_VD65G4 && rev != VD55G1_REVISION_BAYER)) {
1675 		dev_err(sensor->dev, "Unsupported sensor revision 0x%x for sensor %s\n",
1676 			(u16)rev, VD55G1_MODEL_ID_NAME(id));
1677 		return -ENODEV;
1678 	}
1679 
1680 	return 0;
1681 }
1682 
1683 static int vd55g1_power_on(struct device *dev)
1684 {
1685 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
1686 	struct vd55g1 *sensor = to_vd55g1(sd);
1687 	int ret;
1688 
1689 	ret = regulator_bulk_enable(ARRAY_SIZE(vd55g1_supply_name),
1690 				    sensor->supplies);
1691 	if (ret) {
1692 		dev_err(dev, "Failed to enable regulators %d\n", ret);
1693 		return ret;
1694 	}
1695 
1696 	ret = clk_prepare_enable(sensor->xclk);
1697 	if (ret) {
1698 		dev_err(dev, "Failed to enable clock %d\n", ret);
1699 		goto disable_bulk;
1700 	}
1701 
1702 	gpiod_set_value_cansleep(sensor->reset_gpio, 0);
1703 	usleep_range(5000, 10000);
1704 	ret = vd55g1_wait_state(sensor, VD55G1_SYSTEM_FSM_READY_TO_BOOT, NULL);
1705 	if (ret) {
1706 		dev_err(dev, "Sensor reset failed %d\n", ret);
1707 		goto disable_clock;
1708 	}
1709 
1710 	ret = vd55g1_detect(sensor);
1711 	if (ret) {
1712 		dev_err(dev, "Sensor detect failed %d\n", ret);
1713 		goto disable_clock;
1714 	}
1715 
1716 	/* Setup clock now to advance through system FSM states */
1717 	vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1718 
1719 	ret = vd55g1_patch(sensor);
1720 	if (ret) {
1721 		dev_err(dev, "Sensor patch failed %d\n", ret);
1722 		goto disable_clock;
1723 	}
1724 
1725 	return 0;
1726 
1727 disable_clock:
1728 	gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1729 	clk_disable_unprepare(sensor->xclk);
1730 disable_bulk:
1731 	regulator_bulk_disable(ARRAY_SIZE(vd55g1_supply_name),
1732 			       sensor->supplies);
1733 
1734 	return ret;
1735 }
1736 
1737 static int vd55g1_power_off(struct device *dev)
1738 {
1739 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
1740 	struct vd55g1 *sensor = to_vd55g1(sd);
1741 
1742 	gpiod_set_value_cansleep(sensor->reset_gpio, 1);
1743 	clk_disable_unprepare(sensor->xclk);
1744 	regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies);
1745 
1746 	return 0;
1747 }
1748 
1749 static int vd55g1_check_csi_conf(struct vd55g1 *sensor,
1750 				 struct fwnode_handle *endpoint)
1751 {
1752 	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
1753 	u8 n_lanes;
1754 	int ret;
1755 
1756 	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
1757 	if (ret)
1758 		return -EINVAL;
1759 
1760 	/* Check lanes number */
1761 	n_lanes = ep.bus.mipi_csi2.num_data_lanes;
1762 	if (n_lanes != 1) {
1763 		dev_err(sensor->dev, "Sensor only supports 1 lane, found %d\n",
1764 			n_lanes);
1765 		ret = -EINVAL;
1766 		goto done;
1767 	}
1768 
1769 	/* Clock lane must be first */
1770 	if (ep.bus.mipi_csi2.clock_lane != 0) {
1771 		dev_err(sensor->dev, "Clock lane must be mapped to lane 0\n");
1772 		ret = -EINVAL;
1773 		goto done;
1774 	}
1775 
1776 	/* Handle polarities in sensor configuration */
1777 	sensor->oif_ctrl = (ep.bus.mipi_csi2.lane_polarities[0] << 3) |
1778 			   (ep.bus.mipi_csi2.lane_polarities[1] << 6);
1779 
1780 	/* Check the link frequency set in device tree */
1781 	if (!ep.nr_of_link_frequencies) {
1782 		dev_err(sensor->dev, "link-frequency property not found in DT\n");
1783 		ret = -EINVAL;
1784 		goto done;
1785 	}
1786 	if (ep.nr_of_link_frequencies != 1) {
1787 		dev_err(sensor->dev, "Multiple link frequencies not supported\n");
1788 		ret = -EINVAL;
1789 		goto done;
1790 	}
1791 	sensor->link_freq = ep.link_frequencies[0];
1792 
1793 done:
1794 	v4l2_fwnode_endpoint_free(&ep);
1795 
1796 	return ret;
1797 }
1798 
1799 static int vd55g1_parse_dt_gpios_array(struct vd55g1 *sensor,
1800 				       char *prop_name, u32 *array, int *nb)
1801 {
1802 	unsigned int i;
1803 	int ret;
1804 
1805 	*nb = device_property_count_u32(sensor->dev, prop_name);
1806 	if (*nb == -EINVAL) {
1807 		/* Property not found */
1808 		*nb = 0;
1809 		return 0;
1810 	}
1811 
1812 	ret = device_property_read_u32_array(sensor->dev,
1813 					     prop_name, array, *nb);
1814 	if (ret) {
1815 		dev_err(sensor->dev, "Failed to read %s prop\n", prop_name);
1816 		return ret;
1817 	}
1818 	for (i = 0; i < *nb;  i++) {
1819 		if (array[i] >= VD55G1_NB_GPIOS) {
1820 			dev_err(sensor->dev, "Invalid GPIO number %d\n",
1821 				array[i]);
1822 			return -EINVAL;
1823 		}
1824 	}
1825 
1826 	return 0;
1827 }
1828 
1829 static int vd55g1_parse_dt_gpios(struct vd55g1 *sensor)
1830 {
1831 	u32 led_gpios[VD55G1_NB_GPIOS];
1832 	int nb_gpios_leds;
1833 	unsigned int i;
1834 	int ret;
1835 
1836 	/* Initialize GPIOs to default */
1837 	for (i = 0; i < VD55G1_NB_GPIOS; i++)
1838 		sensor->gpios[i] = VD55G1_GPIO_MODE_IN;
1839 	sensor->ext_leds_mask = 0;
1840 
1841 	/* Take into account optional 'st,leds' output for GPIOs */
1842 	ret = vd55g1_parse_dt_gpios_array(sensor, "st,leds", led_gpios,
1843 					  &nb_gpios_leds);
1844 	if (ret)
1845 		return ret;
1846 
1847 	for (i = 0; i < nb_gpios_leds; i++) {
1848 		sensor->gpios[led_gpios[i]] = VD55G1_GPIO_MODE_STROBE;
1849 		set_bit(led_gpios[i], &sensor->ext_leds_mask);
1850 	}
1851 
1852 	return 0;
1853 }
1854 
1855 static int vd55g1_parse_dt(struct vd55g1 *sensor)
1856 {
1857 	struct fwnode_handle *endpoint;
1858 	int ret;
1859 
1860 	endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(sensor->dev),
1861 						   0, 0, 0);
1862 	if (!endpoint) {
1863 		dev_err(sensor->dev, "Endpoint node not found\n");
1864 		return -EINVAL;
1865 	}
1866 
1867 	ret = vd55g1_check_csi_conf(sensor, endpoint);
1868 	fwnode_handle_put(endpoint);
1869 	if (ret)
1870 		return ret;
1871 
1872 	return vd55g1_parse_dt_gpios(sensor);
1873 }
1874 
1875 static int vd55g1_subdev_init(struct vd55g1 *sensor)
1876 {
1877 	int ret;
1878 
1879 	/* Init sub device */
1880 	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1881 	sensor->sd.internal_ops = &vd55g1_internal_ops;
1882 
1883 	/* Init source pad */
1884 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
1885 	sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1886 	ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
1887 	if (ret) {
1888 		dev_err(sensor->dev, "Failed to init media entity: %d\n", ret);
1889 		return ret;
1890 	}
1891 
1892 	sensor->sd.state_lock = sensor->ctrl_handler.lock;
1893 	ret = v4l2_subdev_init_finalize(&sensor->sd);
1894 	if (ret) {
1895 		dev_err(sensor->dev, "Subdev init error: %d\n", ret);
1896 		goto err_ctrls;
1897 	}
1898 
1899 	/*
1900 	 * Initialize controls after v4l2_subdev_init_finalize() to make sure
1901 	 * active state is set
1902 	 */
1903 	ret = vd55g1_init_ctrls(sensor);
1904 	if (ret) {
1905 		dev_err(sensor->dev, "Controls initialization failed %d\n",
1906 			ret);
1907 		goto err_media;
1908 	}
1909 
1910 	return 0;
1911 
1912 err_ctrls:
1913 	v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1914 
1915 err_media:
1916 	media_entity_cleanup(&sensor->sd.entity);
1917 	return ret;
1918 }
1919 
1920 static void vd55g1_subdev_cleanup(struct vd55g1 *sensor)
1921 {
1922 	v4l2_async_unregister_subdev(&sensor->sd);
1923 	v4l2_subdev_cleanup(&sensor->sd);
1924 	media_entity_cleanup(&sensor->sd.entity);
1925 	v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
1926 }
1927 
1928 static int vd55g1_get_regulators(struct vd55g1 *sensor)
1929 {
1930 	unsigned int i;
1931 
1932 	for (i = 0; i < ARRAY_SIZE(vd55g1_supply_name); i++)
1933 		sensor->supplies[i].supply = vd55g1_supply_name[i];
1934 
1935 	return devm_regulator_bulk_get(sensor->dev,
1936 				       ARRAY_SIZE(vd55g1_supply_name),
1937 				       sensor->supplies);
1938 }
1939 
1940 static int vd55g1_probe(struct i2c_client *client)
1941 {
1942 	struct device *dev = &client->dev;
1943 	struct vd55g1 *sensor;
1944 	int ret;
1945 
1946 	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
1947 	if (!sensor)
1948 		return -ENOMEM;
1949 	sensor->dev = &client->dev;
1950 
1951 	v4l2_i2c_subdev_init(&sensor->sd, client, &vd55g1_subdev_ops);
1952 
1953 	ret = vd55g1_parse_dt(sensor);
1954 	if (ret)
1955 		return dev_err_probe(dev, ret, "Failed to parse Device Tree\n");
1956 
1957 	/* Get (and check) resources : power regs, ext clock, reset gpio */
1958 	ret = vd55g1_get_regulators(sensor);
1959 	if (ret)
1960 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
1961 
1962 	sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
1963 	if (IS_ERR(sensor->xclk))
1964 		return dev_err_probe(dev, PTR_ERR(sensor->xclk),
1965 				     "Failed to get xclk\n");
1966 
1967 	sensor->xclk_freq = clk_get_rate(sensor->xclk);
1968 	ret = vd55g1_prepare_clock_tree(sensor);
1969 	if (ret)
1970 		return ret;
1971 
1972 	sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1973 						     GPIOD_OUT_HIGH);
1974 	if (IS_ERR(sensor->reset_gpio))
1975 		return dev_err_probe(dev, PTR_ERR(sensor->reset_gpio),
1976 				     "Failed to get reset gpio\n");
1977 
1978 	sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
1979 	if (IS_ERR(sensor->regmap))
1980 		return dev_err_probe(dev, PTR_ERR(sensor->regmap),
1981 				     "Failed to init regmap\n");
1982 
1983 	/* Detect if sensor is present and if its revision is supported */
1984 	ret = vd55g1_power_on(dev);
1985 	if (ret)
1986 		return ret;
1987 
1988 	/* Enable pm_runtime and power off the sensor */
1989 	pm_runtime_set_active(dev);
1990 	pm_runtime_get_noresume(dev);
1991 	pm_runtime_enable(dev);
1992 	pm_runtime_set_autosuspend_delay(dev, 4000);
1993 	pm_runtime_use_autosuspend(dev);
1994 	pm_runtime_put_autosuspend(dev);
1995 
1996 	ret = vd55g1_subdev_init(sensor);
1997 	if (ret) {
1998 		dev_err(dev, "V4l2 init failed: %d\n", ret);
1999 		goto err_power_off;
2000 	}
2001 
2002 	ret = v4l2_async_register_subdev(&sensor->sd);
2003 	if (ret) {
2004 		dev_err(dev, "async subdev register failed %d\n", ret);
2005 		goto err_subdev;
2006 	}
2007 
2008 	return 0;
2009 
2010 err_subdev:
2011 	vd55g1_subdev_cleanup(sensor);
2012 err_power_off:
2013 	pm_runtime_disable(dev);
2014 	pm_runtime_put_noidle(dev);
2015 	pm_runtime_dont_use_autosuspend(dev);
2016 	vd55g1_power_off(dev);
2017 
2018 	return ret;
2019 }
2020 
2021 static void vd55g1_remove(struct i2c_client *client)
2022 {
2023 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2024 	struct vd55g1 *sensor = to_vd55g1(sd);
2025 
2026 	vd55g1_subdev_cleanup(sensor);
2027 
2028 	pm_runtime_disable(&client->dev);
2029 	if (!pm_runtime_status_suspended(&client->dev))
2030 		vd55g1_power_off(&client->dev);
2031 	pm_runtime_set_suspended(&client->dev);
2032 	pm_runtime_dont_use_autosuspend(&client->dev);
2033 }
2034 
2035 static const struct of_device_id vd55g1_dt_ids[] = {
2036 	{ .compatible = "st,vd55g1", .data = (void *)VD55G1_MODEL_ID_VD55G1 },
2037 	{ .compatible = "st,vd65g4", .data = (void *)VD55G1_MODEL_ID_VD65G4 },
2038 	{ /* sentinel */ }
2039 };
2040 MODULE_DEVICE_TABLE(of, vd55g1_dt_ids);
2041 
2042 static const struct dev_pm_ops vd55g1_pm_ops = {
2043 	SET_RUNTIME_PM_OPS(vd55g1_power_off, vd55g1_power_on, NULL)
2044 };
2045 
2046 static struct i2c_driver vd55g1_i2c_driver = {
2047 	.driver = {
2048 		.name  = "vd55g1",
2049 		.of_match_table = vd55g1_dt_ids,
2050 		.pm = &vd55g1_pm_ops,
2051 	},
2052 	.probe = vd55g1_probe,
2053 	.remove = vd55g1_remove,
2054 };
2055 
2056 module_i2c_driver(vd55g1_i2c_driver);
2057 
2058 MODULE_AUTHOR("Benjamin Mugnier <benjamin.mugnier@foss.st.com>");
2059 MODULE_AUTHOR("Sylvain Petinot <sylvain.petinot@foss.st.com>");
2060 MODULE_DESCRIPTION("VD55G1 camera subdev driver");
2061 MODULE_LICENSE("GPL");
2062