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