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