xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/imx378.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * imx378 driver
4  *
5  * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
6  * V0.0X01.0X01 add imx378 driver.
7  * V0.0X01.0X02 add imx378 support mirror and flip.
8  * V0.0X01.0X03 add quick stream on/off
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/delay.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/i2c.h>
16 #include <linux/module.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/sysfs.h>
20 #include <linux/slab.h>
21 #include <linux/version.h>
22 #include <linux/rk-camera-module.h>
23 #include <media/media-entity.h>
24 #include <media/v4l2-async.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-subdev.h>
27 #include <media/v4l2-fwnode.h>
28 #include <linux/pinctrl/consumer.h>
29 #include <linux/of.h>
30 #include <linux/of_device.h>
31 #include <linux/of_graph.h>
32 #include <linux/of_platform.h>
33 #include <linux/of_gpio.h>
34 #include <linux/mfd/syscon.h>
35 #include <linux/rk-preisp.h>
36 
37 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x03)
38 
39 #ifndef V4L2_CID_DIGITAL_GAIN
40 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
41 #endif
42 
43 #define IMX378_LINK_FREQ_848		848000000// 1696Mbps
44 
45 #define IMX378_LANES			4
46 
47 #define PIXEL_RATE_WITH_848M_10BIT	(IMX378_LINK_FREQ_848 * 2 / 10 * 4)
48 #define PIXEL_RATE_WITH_848M_12BIT	(IMX378_LINK_FREQ_848 * 2 / 12 * 4)
49 
50 #define IMX378_XVCLK_FREQ		24000000
51 
52 #define CHIP_ID				0x0378
53 #define IMX378_REG_CHIP_ID_H		0x0016
54 #define IMX378_REG_CHIP_ID_L		0x0017
55 
56 #define IMX378_REG_CTRL_MODE		0x0100
57 #define IMX378_MODE_SW_STANDBY		0x0
58 #define IMX378_MODE_STREAMING		0x1
59 
60 #define IMX378_REG_EXPOSURE_H		0x0202
61 #define IMX378_REG_EXPOSURE_L		0x0203
62 #define IMX378_EXPOSURE_MIN		2
63 #define IMX378_EXPOSURE_STEP		1
64 #define IMX378_VTS_MAX			0x7fff
65 
66 #define IMX378_REG_GAIN_H		0x0204
67 #define IMX378_REG_GAIN_L		0x0205
68 #define IMX378_GAIN_MIN			0x00
69 #define IMX378_GAIN_MAX			0x13AB
70 #define IMX378_GAIN_STEP		1
71 #define IMX378_GAIN_DEFAULT		0x0080
72 
73 #define IMX378_REG_DGAIN		0x3ff9
74 #define IMX378_DGAIN_MODE		1
75 #define IMX378_REG_DGAINGR_H		0x020e
76 #define IMX378_REG_DGAINGR_L		0x020f
77 #define IMX378_REG_DGAINR_H		0x0210
78 #define IMX378_REG_DGAINR_L		0x0211
79 #define IMX378_REG_DGAINB_H		0x0212
80 #define IMX378_REG_DGAINB_L		0x0213
81 #define IMX378_REG_DGAINGB_H		0x0214
82 #define IMX378_REG_DGAINGB_L		0x0215
83 #define IMX378_REG_GAIN_GLOBAL_H	0x3ffc
84 #define IMX378_REG_GAIN_GLOBAL_L	0x3ffd
85 
86 //#define IMX378_REG_TEST_PATTERN_H	0x0600
87 #define IMX378_REG_TEST_PATTERN	0x0601
88 #define IMX378_TEST_PATTERN_ENABLE	0x1
89 #define IMX378_TEST_PATTERN_DISABLE	0x0
90 
91 #define IMX378_REG_VTS_H		0x0340
92 #define IMX378_REG_VTS_L		0x0341
93 
94 #define IMX378_FLIP_MIRROR_REG		0x0101
95 #define IMX378_MIRROR_BIT_MASK		BIT(0)
96 #define IMX378_FLIP_BIT_MASK		BIT(1)
97 
98 #define IMX378_FETCH_EXP_H(VAL)		(((VAL) >> 8) & 0xFF)
99 #define IMX378_FETCH_EXP_L(VAL)		((VAL) & 0xFF)
100 
101 #define IMX378_FETCH_AGAIN_H(VAL)		(((VAL) >> 8) & 0x03)
102 #define IMX378_FETCH_AGAIN_L(VAL)		((VAL) & 0xFF)
103 
104 #define IMX378_FETCH_DGAIN_H(VAL)		(((VAL) >> 8) & 0x0F)
105 #define IMX378_FETCH_DGAIN_L(VAL)		((VAL) & 0xFF)
106 
107 #define IMX378_FETCH_RHS1_H(VAL)	(((VAL) >> 16) & 0x0F)
108 #define IMX378_FETCH_RHS1_M(VAL)	(((VAL) >> 8) & 0xFF)
109 #define IMX378_FETCH_RHS1_L(VAL)	((VAL) & 0xFF)
110 
111 #define REG_DELAY			0xFFFE
112 #define REG_NULL			0xFFFF
113 
114 #define IMX378_REG_VALUE_08BIT		1
115 #define IMX378_REG_VALUE_16BIT		2
116 #define IMX378_REG_VALUE_24BIT		3
117 
118 #define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
119 
120 #define IMX378_NAME			"imx378"
121 
122 static const char * const imx378_supply_names[] = {
123 	"avdd",		/* Analog power */
124 	"dovdd",	/* Digital I/O power */
125 	"dvdd",		/* Digital core power */
126 };
127 
128 #define IMX378_NUM_SUPPLIES ARRAY_SIZE(imx378_supply_names)
129 
130 struct regval {
131 	u16 addr;
132 	u8 val;
133 };
134 
135 struct imx378_mode {
136 	u32 bus_fmt;
137 	u32 width;
138 	u32 height;
139 	struct v4l2_fract max_fps;
140 	u32 hts_def;
141 	u32 vts_def;
142 	u32 exp_def;
143 	const struct regval *reg_list;
144 	u32 hdr_mode;
145 	u32 vc[PAD_MAX];
146 };
147 
148 struct imx378 {
149 	struct i2c_client	*client;
150 	struct clk		*xvclk;
151 	struct gpio_desc	*reset_gpio;
152 	struct gpio_desc	*pwdn_gpio;
153 	struct regulator_bulk_data supplies[IMX378_NUM_SUPPLIES];
154 
155 	struct pinctrl		*pinctrl;
156 	struct pinctrl_state	*pins_default;
157 	struct pinctrl_state	*pins_sleep;
158 
159 	struct v4l2_subdev	subdev;
160 	struct media_pad	pad;
161 	struct v4l2_ctrl_handler ctrl_handler;
162 	struct v4l2_ctrl	*exposure;
163 	struct v4l2_ctrl	*anal_gain;
164 	struct v4l2_ctrl	*digi_gain;
165 	struct v4l2_ctrl	*hblank;
166 	struct v4l2_ctrl	*vblank;
167 	struct v4l2_ctrl	*h_flip;
168 	struct v4l2_ctrl	*v_flip;
169 	struct v4l2_ctrl	*test_pattern;
170 	struct v4l2_ctrl	*pixel_rate;
171 	struct v4l2_ctrl	*link_freq;
172 	struct mutex		mutex;
173 	bool			streaming;
174 	bool			power_on;
175 	const struct imx378_mode *cur_mode;
176 	u32			cfg_num;
177 	u32			cur_pixel_rate;
178 	u32			cur_link_freq;
179 	u32			module_index;
180 	const char		*module_facing;
181 	const char		*module_name;
182 	const char		*len_name;
183 	u32			cur_vts;
184 	bool			has_init_exp;
185 	struct preisp_hdrae_exp_s init_hdrae_exp;
186 	u8			flip;
187 };
188 
189 #define to_imx378(sd) container_of(sd, struct imx378, subdev)
190 
191 /*
192  *IMX378LQR All-pixel scan CSI-2_4lane 24Mhz
193  *AD:10bit Output:10bit 1696Mbps Master Mode 30fps
194  *Tool ver : Ver4.0
195  */
196 static const struct regval imx378_linear_10_4056x3040_regs[] = {
197 	{0x0101, 0x00},
198 	{0x0136, 0x18},
199 	{0x0137, 0x00},
200 	{0xE000, 0x00},
201 	{0x4AE9, 0x18},
202 	{0x4AEA, 0x08},
203 	{0xF61C, 0x04},
204 	{0xF61E, 0x04},
205 	{0x4AE9, 0x21},
206 	{0x4AEA, 0x80},
207 	{0x38A8, 0x1F},
208 	{0x38A9, 0xFF},
209 	{0x38AA, 0x1F},
210 	{0x38AB, 0xFF},
211 	{0x55D4, 0x00},
212 	{0x55D5, 0x00},
213 	{0x55D6, 0x07},
214 	{0x55D7, 0xFF},
215 	{0x55E8, 0x07},
216 	{0x55E9, 0xFF},
217 	{0x55EA, 0x00},
218 	{0x55EB, 0x00},
219 	{0x574C, 0x07},
220 	{0x574D, 0xFF},
221 	{0x574E, 0x00},
222 	{0x574F, 0x00},
223 	{0x5754, 0x00},
224 	{0x5755, 0x00},
225 	{0x5756, 0x07},
226 	{0x5757, 0xFF},
227 	{0x5973, 0x04},
228 	{0x5974, 0x01},
229 	{0x5D13, 0xC3},
230 	{0x5D14, 0x58},
231 	{0x5D15, 0xA3},
232 	{0x5D16, 0x1D},
233 	{0x5D17, 0x65},
234 	{0x5D18, 0x8C},
235 	{0x5D1A, 0x06},
236 	{0x5D1B, 0xA9},
237 	{0x5D1C, 0x45},
238 	{0x5D1D, 0x3A},
239 	{0x5D1E, 0xAB},
240 	{0x5D1F, 0x15},
241 	{0x5D21, 0x0E},
242 	{0x5D22, 0x52},
243 	{0x5D23, 0xAA},
244 	{0x5D24, 0x7D},
245 	{0x5D25, 0x57},
246 	{0x5D26, 0xA8},
247 	{0x5D37, 0x5A},
248 	{0x5D38, 0x5A},
249 	{0x5D77, 0x7F},
250 	{0x7B75, 0x0E},
251 	{0x7B76, 0x0B},
252 	{0x7B77, 0x08},
253 	{0x7B78, 0x0A},
254 	{0x7B79, 0x47},
255 	{0x7B7C, 0x00},
256 	{0x7B7D, 0x00},
257 	{0x8D1F, 0x00},
258 	{0x8D27, 0x00},
259 	{0x9004, 0x03},
260 	{0x9200, 0x50},
261 	{0x9201, 0x6C},
262 	{0x9202, 0x71},
263 	{0x9203, 0x00},
264 	{0x9204, 0x71},
265 	{0x9205, 0x01},
266 	{0x9371, 0x6A},
267 	{0x9373, 0x6A},
268 	{0x9375, 0x64},
269 	{0x991A, 0x00},
270 	{0x996B, 0x8C},
271 	{0x996C, 0x64},
272 	{0x996D, 0x50},
273 	{0x9A4C, 0x0D},
274 	{0x9A4D, 0x0D},
275 	{0xA001, 0x0A},
276 	{0xA003, 0x0A},
277 	{0xA005, 0x0A},
278 	{0xA006, 0x01},
279 	{0xA007, 0xC0},
280 	{0xA009, 0xC0},
281 
282 	{0x3D8A, 0x01},
283 	{0x4421, 0x08},
284 	{0x7B3B, 0x01},
285 	{0x7B4C, 0x00},
286 	{0x9905, 0x00},
287 	{0x9907, 0x00},
288 	{0x9909, 0x00},
289 	{0x990B, 0x00},
290 	{0x9944, 0x3C},
291 	{0x9947, 0x3C},
292 	{0x994A, 0x8C},
293 	{0x994B, 0x50},
294 	{0x994C, 0x1B},
295 	{0x994D, 0x8C},
296 	{0x994E, 0x50},
297 	{0x994F, 0x1B},
298 	{0x9950, 0x8C},
299 	{0x9951, 0x1B},
300 	{0x9952, 0x0A},
301 	{0x9953, 0x8C},
302 	{0x9954, 0x1B},
303 	{0x9955, 0x0A},
304 	{0x9A13, 0x04},
305 	{0x9A14, 0x04},
306 	{0x9A19, 0x00},
307 	{0x9A1C, 0x04},
308 	{0x9A1D, 0x04},
309 	{0x9A26, 0x05},
310 	{0x9A27, 0x05},
311 	{0x9A2C, 0x01},
312 	{0x9A2D, 0x03},
313 	{0x9A2F, 0x05},
314 	{0x9A30, 0x05},
315 	{0x9A41, 0x00},
316 	{0x9A46, 0x00},
317 	{0x9A47, 0x00},
318 	{0x9C17, 0x35},
319 	{0x9C1D, 0x31},
320 	{0x9C29, 0x50},
321 	{0x9C3B, 0x2F},
322 	{0x9C41, 0x6B},
323 	{0x9C47, 0x2D},
324 	{0x9C4D, 0x40},
325 	{0x9C6B, 0x00},
326 	{0x9C71, 0xC8},
327 	{0x9C73, 0x32},
328 	{0x9C75, 0x04},
329 	{0x9C7D, 0x2D},
330 	{0x9C83, 0x40},
331 	{0x9C94, 0x3F},
332 	{0x9C95, 0x3F},
333 	{0x9C96, 0x3F},
334 	{0x9C97, 0x00},
335 	{0x9C98, 0x00},
336 	{0x9C99, 0x00},
337 	{0x9C9A, 0x3F},
338 	{0x9C9B, 0x3F},
339 	{0x9C9C, 0x3F},
340 	{0x9CA0, 0x0F},
341 	{0x9CA1, 0x0F},
342 	{0x9CA2, 0x0F},
343 	{0x9CA3, 0x00},
344 	{0x9CA4, 0x00},
345 	{0x9CA5, 0x00},
346 	{0x9CA6, 0x1E},
347 	{0x9CA7, 0x1E},
348 	{0x9CA8, 0x1E},
349 	{0x9CA9, 0x00},
350 	{0x9CAA, 0x00},
351 	{0x9CAB, 0x00},
352 	{0x9CAC, 0x09},
353 	{0x9CAD, 0x09},
354 	{0x9CAE, 0x09},
355 	{0x9CBD, 0x50},
356 	{0x9CBF, 0x50},
357 	{0x9CC1, 0x50},
358 	{0x9CC3, 0x40},
359 	{0x9CC5, 0x40},
360 	{0x9CC7, 0x40},
361 	{0x9CC9, 0x0A},
362 	{0x9CCB, 0x0A},
363 	{0x9CCD, 0x0A},
364 	{0x9D17, 0x35},
365 	{0x9D1D, 0x31},
366 	{0x9D29, 0x50},
367 	{0x9D3B, 0x2F},
368 	{0x9D41, 0x6B},
369 	{0x9D47, 0x42},
370 	{0x9D4D, 0x5A},
371 	{0x9D6B, 0x00},
372 	{0x9D71, 0xC8},
373 	{0x9D73, 0x32},
374 	{0x9D75, 0x04},
375 	{0x9D7D, 0x42},
376 	{0x9D83, 0x5A},
377 	{0x9D94, 0x3F},
378 	{0x9D95, 0x3F},
379 	{0x9D96, 0x3F},
380 	{0x9D97, 0x00},
381 	{0x9D98, 0x00},
382 	{0x9D99, 0x00},
383 	{0x9D9A, 0x3F},
384 	{0x9D9B, 0x3F},
385 	{0x9D9C, 0x3F},
386 	{0x9D9D, 0x1F},
387 	{0x9D9E, 0x1F},
388 	{0x9D9F, 0x1F},
389 	{0x9DA0, 0x0F},
390 	{0x9DA1, 0x0F},
391 	{0x9DA2, 0x0F},
392 	{0x9DA3, 0x00},
393 	{0x9DA4, 0x00},
394 	{0x9DA5, 0x00},
395 	{0x9DA6, 0x1E},
396 	{0x9DA7, 0x1E},
397 	{0x9DA8, 0x1E},
398 	{0x9DA9, 0x00},
399 	{0x9DAA, 0x00},
400 	{0x9DAB, 0x00},
401 	{0x9DAC, 0x09},
402 	{0x9DAD, 0x09},
403 	{0x9DAE, 0x09},
404 	{0x9DC9, 0x0A},
405 	{0x9DCB, 0x0A},
406 	{0x9DCD, 0x0A},
407 	{0x9E17, 0x35},
408 	{0x9E1D, 0x31},
409 	{0x9E29, 0x50},
410 	{0x9E3B, 0x2F},
411 	{0x9E41, 0x6B},
412 	{0x9E47, 0x2D},
413 	{0x9E4D, 0x40},
414 	{0x9E6B, 0x00},
415 	{0x9E71, 0xC8},
416 	{0x9E73, 0x32},
417 	{0x9E75, 0x04},
418 	{0x9E94, 0x0F},
419 	{0x9E95, 0x0F},
420 	{0x9E96, 0x0F},
421 	{0x9E97, 0x00},
422 	{0x9E98, 0x00},
423 	{0x9E99, 0x00},
424 	{0x9EA0, 0x0F},
425 	{0x9EA1, 0x0F},
426 	{0x9EA2, 0x0F},
427 	{0x9EA3, 0x00},
428 	{0x9EA4, 0x00},
429 	{0x9EA5, 0x00},
430 	{0x9EA6, 0x3F},
431 	{0x9EA7, 0x3F},
432 	{0x9EA8, 0x3F},
433 	{0x9EA9, 0x00},
434 	{0x9EAA, 0x00},
435 	{0x9EAB, 0x00},
436 	{0x9EAC, 0x09},
437 	{0x9EAD, 0x09},
438 	{0x9EAE, 0x09},
439 	{0x9EC9, 0x0A},
440 	{0x9ECB, 0x0A},
441 	{0x9ECD, 0x0A},
442 	{0x9F17, 0x35},
443 	{0x9F1D, 0x31},
444 	{0x9F29, 0x50},
445 	{0x9F3B, 0x2F},
446 	{0x9F41, 0x6B},
447 	{0x9F47, 0x42},
448 	{0x9F4D, 0x5A},
449 	{0x9F6B, 0x00},
450 	{0x9F71, 0xC8},
451 	{0x9F73, 0x32},
452 	{0x9F75, 0x04},
453 	{0x9F94, 0x0F},
454 	{0x9F95, 0x0F},
455 	{0x9F96, 0x0F},
456 	{0x9F97, 0x00},
457 	{0x9F98, 0x00},
458 	{0x9F99, 0x00},
459 	{0x9F9A, 0x2F},
460 	{0x9F9B, 0x2F},
461 	{0x9F9C, 0x2F},
462 	{0x9F9D, 0x00},
463 	{0x9F9E, 0x00},
464 	{0x9F9F, 0x00},
465 	{0x9FA0, 0x0F},
466 	{0x9FA1, 0x0F},
467 	{0x9FA2, 0x0F},
468 	{0x9FA3, 0x00},
469 	{0x9FA4, 0x00},
470 	{0x9FA5, 0x00},
471 	{0x9FA6, 0x1E},
472 	{0x9FA7, 0x1E},
473 	{0x9FA8, 0x1E},
474 	{0x9FA9, 0x00},
475 	{0x9FAA, 0x00},
476 	{0x9FAB, 0x00},
477 	{0x9FAC, 0x09},
478 	{0x9FAD, 0x09},
479 	{0x9FAE, 0x09},
480 	{0x9FC9, 0x0A},
481 	{0x9FCB, 0x0A},
482 	{0x9FCD, 0x0A},
483 	{0xA14B, 0xFF},
484 	{0xA151, 0x0C},
485 	{0xA153, 0x50},
486 	{0xA155, 0x02},
487 	{0xA157, 0x00},
488 	{0xA1AD, 0xFF},
489 	{0xA1B3, 0x0C},
490 	{0xA1B5, 0x50},
491 	{0xA1B9, 0x00},
492 	{0xA24B, 0xFF},
493 	{0xA257, 0x00},
494 	{0xA2AD, 0xFF},
495 	{0xA2B9, 0x00},
496 	{0xB21F, 0x04},
497 	{0xB35C, 0x00},
498 	{0xB35E, 0x08},
499 
500 	{0x0112, 0x0A},
501 	{0x0113, 0x0A},
502 	{0x0114, 0x03},
503 	{0x0342, 0x16},
504 	{0x0343, 0xA8},
505 	{0x0340, 0x0F},
506 	{0x0341, 0x3C},
507 	{0x0344, 0x00},
508 	{0x0345, 0x00},
509 	{0x0346, 0x00},
510 	{0x0347, 0x00},
511 	{0x0348, 0x0F},
512 	{0x0349, 0xD7},
513 	{0x034A, 0x0B},
514 	{0x034B, 0xDF},
515 	{0x0220, 0x00},
516 	{0x0221, 0x11},
517 	{0x0381, 0x01},
518 	{0x0383, 0x01},
519 	{0x0385, 0x01},
520 	{0x0387, 0x01},
521 	{0x0900, 0x00},
522 	{0x0901, 0x11},
523 	{0x0902, 0x02},
524 	{0x3140, 0x02},
525 	{0x3C00, 0x00},
526 	{0x3C01, 0x03},
527 	{0x3C02, 0xDC},
528 	{0x3F0D, 0x00},
529 	{0x5748, 0x07},
530 	{0x5749, 0xFF},
531 	{0x574A, 0x00},
532 	{0x574B, 0x00},
533 	{0x7B53, 0x01},
534 	{0x9369, 0x5A},
535 	{0x936B, 0x55},
536 	{0x936D, 0x28},
537 	{0x9304, 0x03},
538 	{0x9305, 0x00},
539 	{0x9E9A, 0x2F},
540 	{0x9E9B, 0x2F},
541 	{0x9E9C, 0x2F},
542 	{0x9E9D, 0x00},
543 	{0x9E9E, 0x00},
544 	{0x9E9F, 0x00},
545 	{0xA2A9, 0x60},
546 	{0xA2B7, 0x00},
547 	{0x0401, 0x00},
548 	{0x0404, 0x00},
549 	{0x0405, 0x10},
550 	{0x0408, 0x00},
551 	{0x0409, 0x00},
552 	{0x040A, 0x00},
553 	{0x040B, 0x00},
554 	{0x040C, 0x0F},
555 	{0x040D, 0xD8},
556 	{0x040E, 0x0B},
557 	{0x040F, 0xE0},
558 	{0x034C, 0x0F},
559 	{0x034D, 0xD8},
560 	{0x034E, 0x0B},
561 	{0x034F, 0xE0},
562 	{0x0301, 0x05},
563 	{0x0303, 0x02},
564 	{0x0305, 0x03},
565 	{0x0306, 0x00},
566 	{0x0307, 0xD4},
567 	{0x0309, 0x0A},
568 	{0x030B, 0x01},
569 	{0x030D, 0x02},
570 	{0x030E, 0x01},
571 	{0x030F, 0x5E},
572 	{0x0310, 0x00},
573 	{0x0820, 0x1A},
574 	{0x0821, 0x80},
575 	{0x0822, 0x00},
576 	{0x0823, 0x00},
577 	{0x3E20, 0x01},
578 	{0x3E37, 0x01},
579 	{0x3F50, 0x00},
580 	{0x3F56, 0x00},
581 	{0x3F57, 0xA0},
582 	{REG_NULL, 0x00},
583 };
584 
585 static const struct regval imx378_linear_10_3840x2160_regs[] = {
586 	{0x0101, 0x00},
587 	{0x0136, 0x18},
588 	{0x0137, 0x00},
589 	{0xE000, 0x00},
590 	{0x4AE9, 0x18},
591 	{0x4AEA, 0x08},
592 	{0xF61C, 0x04},
593 	{0xF61E, 0x04},
594 	{0x4AE9, 0x21},
595 	{0x4AEA, 0x80},
596 	{0x38A8, 0x1F},
597 	{0x38A9, 0xFF},
598 	{0x38AA, 0x1F},
599 	{0x38AB, 0xFF},
600 	{0x55D4, 0x00},
601 	{0x55D5, 0x00},
602 	{0x55D6, 0x07},
603 	{0x55D7, 0xFF},
604 	{0x55E8, 0x07},
605 	{0x55E9, 0xFF},
606 	{0x55EA, 0x00},
607 	{0x55EB, 0x00},
608 	{0x574C, 0x07},
609 	{0x574D, 0xFF},
610 	{0x574E, 0x00},
611 	{0x574F, 0x00},
612 	{0x5754, 0x00},
613 	{0x5755, 0x00},
614 	{0x5756, 0x07},
615 	{0x5757, 0xFF},
616 	{0x5973, 0x04},
617 	{0x5974, 0x01},
618 	{0x5D13, 0xC3},
619 	{0x5D14, 0x58},
620 	{0x5D15, 0xA3},
621 	{0x5D16, 0x1D},
622 	{0x5D17, 0x65},
623 	{0x5D18, 0x8C},
624 	{0x5D1A, 0x06},
625 	{0x5D1B, 0xA9},
626 	{0x5D1C, 0x45},
627 	{0x5D1D, 0x3A},
628 	{0x5D1E, 0xAB},
629 	{0x5D1F, 0x15},
630 	{0x5D21, 0x0E},
631 	{0x5D22, 0x52},
632 	{0x5D23, 0xAA},
633 	{0x5D24, 0x7D},
634 	{0x5D25, 0x57},
635 	{0x5D26, 0xA8},
636 	{0x5D37, 0x5A},
637 	{0x5D38, 0x5A},
638 	{0x5D77, 0x7F},
639 	{0x7B75, 0x0E},
640 	{0x7B76, 0x0B},
641 	{0x7B77, 0x08},
642 	{0x7B78, 0x0A},
643 	{0x7B79, 0x47},
644 	{0x7B7C, 0x00},
645 	{0x7B7D, 0x00},
646 	{0x8D1F, 0x00},
647 	{0x8D27, 0x00},
648 	{0x9004, 0x03},
649 	{0x9200, 0x50},
650 	{0x9201, 0x6C},
651 	{0x9202, 0x71},
652 	{0x9203, 0x00},
653 	{0x9204, 0x71},
654 	{0x9205, 0x01},
655 	{0x9371, 0x6A},
656 	{0x9373, 0x6A},
657 	{0x9375, 0x64},
658 	{0x991A, 0x00},
659 	{0x996B, 0x8C},
660 	{0x996C, 0x64},
661 	{0x996D, 0x50},
662 	{0x9A4C, 0x0D},
663 	{0x9A4D, 0x0D},
664 	{0xA001, 0x0A},
665 	{0xA003, 0x0A},
666 	{0xA005, 0x0A},
667 	{0xA006, 0x01},
668 	{0xA007, 0xC0},
669 	{0xA009, 0xC0},
670 
671 	{0x3D8A, 0x01},
672 	{0x4421, 0x08},
673 	{0x7B3B, 0x01},
674 	{0x7B4C, 0x00},
675 	{0x9905, 0x00},
676 	{0x9907, 0x00},
677 	{0x9909, 0x00},
678 	{0x990B, 0x00},
679 	{0x9944, 0x3C},
680 	{0x9947, 0x3C},
681 	{0x994A, 0x8C},
682 	{0x994B, 0x50},
683 	{0x994C, 0x1B},
684 	{0x994D, 0x8C},
685 	{0x994E, 0x50},
686 	{0x994F, 0x1B},
687 	{0x9950, 0x8C},
688 	{0x9951, 0x1B},
689 	{0x9952, 0x0A},
690 	{0x9953, 0x8C},
691 	{0x9954, 0x1B},
692 	{0x9955, 0x0A},
693 	{0x9A13, 0x04},
694 	{0x9A14, 0x04},
695 	{0x9A19, 0x00},
696 	{0x9A1C, 0x04},
697 	{0x9A1D, 0x04},
698 	{0x9A26, 0x05},
699 	{0x9A27, 0x05},
700 	{0x9A2C, 0x01},
701 	{0x9A2D, 0x03},
702 	{0x9A2F, 0x05},
703 	{0x9A30, 0x05},
704 	{0x9A41, 0x00},
705 	{0x9A46, 0x00},
706 	{0x9A47, 0x00},
707 	{0x9C17, 0x35},
708 	{0x9C1D, 0x31},
709 	{0x9C29, 0x50},
710 	{0x9C3B, 0x2F},
711 	{0x9C41, 0x6B},
712 	{0x9C47, 0x2D},
713 	{0x9C4D, 0x40},
714 	{0x9C6B, 0x00},
715 	{0x9C71, 0xC8},
716 	{0x9C73, 0x32},
717 	{0x9C75, 0x04},
718 	{0x9C7D, 0x2D},
719 	{0x9C83, 0x40},
720 	{0x9C94, 0x3F},
721 	{0x9C95, 0x3F},
722 	{0x9C96, 0x3F},
723 	{0x9C97, 0x00},
724 	{0x9C98, 0x00},
725 	{0x9C99, 0x00},
726 	{0x9C9A, 0x3F},
727 	{0x9C9B, 0x3F},
728 	{0x9C9C, 0x3F},
729 	{0x9CA0, 0x0F},
730 	{0x9CA1, 0x0F},
731 	{0x9CA2, 0x0F},
732 	{0x9CA3, 0x00},
733 	{0x9CA4, 0x00},
734 	{0x9CA5, 0x00},
735 	{0x9CA6, 0x1E},
736 	{0x9CA7, 0x1E},
737 	{0x9CA8, 0x1E},
738 	{0x9CA9, 0x00},
739 	{0x9CAA, 0x00},
740 	{0x9CAB, 0x00},
741 	{0x9CAC, 0x09},
742 	{0x9CAD, 0x09},
743 	{0x9CAE, 0x09},
744 	{0x9CBD, 0x50},
745 	{0x9CBF, 0x50},
746 	{0x9CC1, 0x50},
747 	{0x9CC3, 0x40},
748 	{0x9CC5, 0x40},
749 	{0x9CC7, 0x40},
750 	{0x9CC9, 0x0A},
751 	{0x9CCB, 0x0A},
752 	{0x9CCD, 0x0A},
753 	{0x9D17, 0x35},
754 	{0x9D1D, 0x31},
755 	{0x9D29, 0x50},
756 	{0x9D3B, 0x2F},
757 	{0x9D41, 0x6B},
758 	{0x9D47, 0x42},
759 	{0x9D4D, 0x5A},
760 	{0x9D6B, 0x00},
761 	{0x9D71, 0xC8},
762 	{0x9D73, 0x32},
763 	{0x9D75, 0x04},
764 	{0x9D7D, 0x42},
765 	{0x9D83, 0x5A},
766 	{0x9D94, 0x3F},
767 	{0x9D95, 0x3F},
768 	{0x9D96, 0x3F},
769 	{0x9D97, 0x00},
770 	{0x9D98, 0x00},
771 	{0x9D99, 0x00},
772 	{0x9D9A, 0x3F},
773 	{0x9D9B, 0x3F},
774 	{0x9D9C, 0x3F},
775 	{0x9D9D, 0x1F},
776 	{0x9D9E, 0x1F},
777 	{0x9D9F, 0x1F},
778 	{0x9DA0, 0x0F},
779 	{0x9DA1, 0x0F},
780 	{0x9DA2, 0x0F},
781 	{0x9DA3, 0x00},
782 	{0x9DA4, 0x00},
783 	{0x9DA5, 0x00},
784 	{0x9DA6, 0x1E},
785 	{0x9DA7, 0x1E},
786 	{0x9DA8, 0x1E},
787 	{0x9DA9, 0x00},
788 	{0x9DAA, 0x00},
789 	{0x9DAB, 0x00},
790 	{0x9DAC, 0x09},
791 	{0x9DAD, 0x09},
792 	{0x9DAE, 0x09},
793 	{0x9DC9, 0x0A},
794 	{0x9DCB, 0x0A},
795 	{0x9DCD, 0x0A},
796 	{0x9E17, 0x35},
797 	{0x9E1D, 0x31},
798 	{0x9E29, 0x50},
799 	{0x9E3B, 0x2F},
800 	{0x9E41, 0x6B},
801 	{0x9E47, 0x2D},
802 	{0x9E4D, 0x40},
803 	{0x9E6B, 0x00},
804 	{0x9E71, 0xC8},
805 	{0x9E73, 0x32},
806 	{0x9E75, 0x04},
807 	{0x9E94, 0x0F},
808 	{0x9E95, 0x0F},
809 	{0x9E96, 0x0F},
810 	{0x9E97, 0x00},
811 	{0x9E98, 0x00},
812 	{0x9E99, 0x00},
813 	{0x9EA0, 0x0F},
814 	{0x9EA1, 0x0F},
815 	{0x9EA2, 0x0F},
816 	{0x9EA3, 0x00},
817 	{0x9EA4, 0x00},
818 	{0x9EA5, 0x00},
819 	{0x9EA6, 0x3F},
820 	{0x9EA7, 0x3F},
821 	{0x9EA8, 0x3F},
822 	{0x9EA9, 0x00},
823 	{0x9EAA, 0x00},
824 	{0x9EAB, 0x00},
825 	{0x9EAC, 0x09},
826 	{0x9EAD, 0x09},
827 	{0x9EAE, 0x09},
828 	{0x9EC9, 0x0A},
829 	{0x9ECB, 0x0A},
830 	{0x9ECD, 0x0A},
831 	{0x9F17, 0x35},
832 	{0x9F1D, 0x31},
833 	{0x9F29, 0x50},
834 	{0x9F3B, 0x2F},
835 	{0x9F41, 0x6B},
836 	{0x9F47, 0x42},
837 	{0x9F4D, 0x5A},
838 	{0x9F6B, 0x00},
839 	{0x9F71, 0xC8},
840 	{0x9F73, 0x32},
841 	{0x9F75, 0x04},
842 	{0x9F94, 0x0F},
843 	{0x9F95, 0x0F},
844 	{0x9F96, 0x0F},
845 	{0x9F97, 0x00},
846 	{0x9F98, 0x00},
847 	{0x9F99, 0x00},
848 	{0x9F9A, 0x2F},
849 	{0x9F9B, 0x2F},
850 	{0x9F9C, 0x2F},
851 	{0x9F9D, 0x00},
852 	{0x9F9E, 0x00},
853 	{0x9F9F, 0x00},
854 	{0x9FA0, 0x0F},
855 	{0x9FA1, 0x0F},
856 	{0x9FA2, 0x0F},
857 	{0x9FA3, 0x00},
858 	{0x9FA4, 0x00},
859 	{0x9FA5, 0x00},
860 	{0x9FA6, 0x1E},
861 	{0x9FA7, 0x1E},
862 	{0x9FA8, 0x1E},
863 	{0x9FA9, 0x00},
864 	{0x9FAA, 0x00},
865 	{0x9FAB, 0x00},
866 	{0x9FAC, 0x09},
867 	{0x9FAD, 0x09},
868 	{0x9FAE, 0x09},
869 	{0x9FC9, 0x0A},
870 	{0x9FCB, 0x0A},
871 	{0x9FCD, 0x0A},
872 	{0xA14B, 0xFF},
873 	{0xA151, 0x0C},
874 	{0xA153, 0x50},
875 	{0xA155, 0x02},
876 	{0xA157, 0x00},
877 	{0xA1AD, 0xFF},
878 	{0xA1B3, 0x0C},
879 	{0xA1B5, 0x50},
880 	{0xA1B9, 0x00},
881 	{0xA24B, 0xFF},
882 	{0xA257, 0x00},
883 	{0xA2AD, 0xFF},
884 	{0xA2B9, 0x00},
885 	{0xB21F, 0x04},
886 	{0xB35C, 0x00},
887 	{0xB35E, 0x08},
888 
889 	{0x0112, 0x0A},
890 	{0x0113, 0x0A},
891 	{0x0114, 0x03},
892 	{0x0342, 0x16},
893 	{0x0343, 0xA8},
894 	{0x0340, 0x0F},
895 	{0x0341, 0x3C},
896 	{0x0344, 0x00},
897 	{0x0345, 0x6C},
898 	{0x0346, 0x01},
899 	{0x0347, 0xB8},
900 	{0x0348, 0x0F},
901 	{0x0349, 0x6B},
902 	{0x034A, 0x0A},
903 	{0x034B, 0x27},
904 	{0x0220, 0x00},
905 	{0x0221, 0x11},
906 	{0x0381, 0x01},
907 	{0x0383, 0x01},
908 	{0x0385, 0x01},
909 	{0x0387, 0x01},
910 	{0x0900, 0x00},
911 	{0x0901, 0x11},
912 	{0x0902, 0x02},
913 	{0x3140, 0x02},
914 	{0x3C00, 0x00},
915 	{0x3C01, 0x03},
916 	{0x3C02, 0xDC},
917 	{0x3F0D, 0x00},
918 	{0x5748, 0x07},
919 	{0x5749, 0xFF},
920 	{0x574A, 0x00},
921 	{0x574B, 0x00},
922 	{0x7B53, 0x01},
923 	{0x9369, 0x5A},
924 	{0x936B, 0x55},
925 	{0x936D, 0x28},
926 	{0x9304, 0x03},
927 	{0x9305, 0x00},
928 	{0x9E9A, 0x2F},
929 	{0x9E9B, 0x2F},
930 	{0x9E9C, 0x2F},
931 	{0x9E9D, 0x00},
932 	{0x9E9E, 0x00},
933 	{0x9E9F, 0x00},
934 	{0xA2A9, 0x60},
935 	{0xA2B7, 0x00},
936 	{0x0401, 0x00},
937 	{0x0404, 0x00},
938 	{0x0405, 0x10},
939 	{0x0408, 0x00},
940 	{0x0409, 0x00},
941 	{0x040A, 0x00},
942 	{0x040B, 0x00},
943 	{0x040C, 0x0F},
944 	{0x040D, 0x00},
945 	{0x040E, 0x08},
946 	{0x040F, 0x70},
947 	{0x034C, 0x0F},
948 	{0x034D, 0x00},
949 	{0x034E, 0x08},
950 	{0x034F, 0x70},
951 	{0x0301, 0x05},
952 	{0x0303, 0x02},
953 	{0x0305, 0x03},
954 	{0x0306, 0x00},
955 	{0x0307, 0xD4},
956 	{0x0309, 0x0A},
957 	{0x030B, 0x01},
958 	{0x030D, 0x02},
959 	{0x030E, 0x01},
960 	{0x030F, 0x5E},
961 	{0x0310, 0x00},
962 	{0x0820, 0x1A},
963 	{0x0821, 0x80},
964 	{0x0822, 0x00},
965 	{0x0823, 0x00},
966 	{0x3E20, 0x01},
967 	{0x3E37, 0x01},
968 	{0x3F50, 0x00},
969 	{0x3F56, 0x00},
970 	{0x3F57, 0xA0},
971 	{REG_NULL, 0x00},
972 };
973 
974 /*
975  *IMX378LQR All-pixel scan CSI-2_4lane 24Mhz
976  *AD:12bit Output:12bit 1696Mbps Master Mode 30fps
977  *Tool ver : Ver4.0
978  */
979 static const struct regval imx378_linear_12_4056x3040_regs[] = {
980 	{0x0101, 0x00},
981 	{0x0136, 0x18},
982 	{0x0137, 0x00},
983 	{0xE000, 0x00},
984 	{0x4AE9, 0x18},
985 	{0x4AEA, 0x08},
986 	{0xF61C, 0x04},
987 	{0xF61E, 0x04},
988 	{0x4AE9, 0x21},
989 	{0x4AEA, 0x80},
990 	{0x38A8, 0x1F},
991 	{0x38A9, 0xFF},
992 	{0x38AA, 0x1F},
993 	{0x38AB, 0xFF},
994 	{0x55D4, 0x00},
995 	{0x55D5, 0x00},
996 	{0x55D6, 0x07},
997 	{0x55D7, 0xFF},
998 	{0x55E8, 0x07},
999 	{0x55E9, 0xFF},
1000 	{0x55EA, 0x00},
1001 	{0x55EB, 0x00},
1002 	{0x574C, 0x07},
1003 	{0x574D, 0xFF},
1004 	{0x574E, 0x00},
1005 	{0x574F, 0x00},
1006 	{0x5754, 0x00},
1007 	{0x5755, 0x00},
1008 	{0x5756, 0x07},
1009 	{0x5757, 0xFF},
1010 	{0x5973, 0x04},
1011 	{0x5974, 0x01},
1012 	{0x5D13, 0xC3},
1013 	{0x5D14, 0x58},
1014 	{0x5D15, 0xA3},
1015 	{0x5D16, 0x1D},
1016 	{0x5D17, 0x65},
1017 	{0x5D18, 0x8C},
1018 	{0x5D1A, 0x06},
1019 	{0x5D1B, 0xA9},
1020 	{0x5D1C, 0x45},
1021 	{0x5D1D, 0x3A},
1022 	{0x5D1E, 0xAB},
1023 	{0x5D1F, 0x15},
1024 	{0x5D21, 0x0E},
1025 	{0x5D22, 0x52},
1026 	{0x5D23, 0xAA},
1027 	{0x5D24, 0x7D},
1028 	{0x5D25, 0x57},
1029 	{0x5D26, 0xA8},
1030 	{0x5D37, 0x5A},
1031 	{0x5D38, 0x5A},
1032 	{0x5D77, 0x7F},
1033 	{0x7B75, 0x0E},
1034 	{0x7B76, 0x0B},
1035 	{0x7B77, 0x08},
1036 	{0x7B78, 0x0A},
1037 	{0x7B79, 0x47},
1038 	{0x7B7C, 0x00},
1039 	{0x7B7D, 0x00},
1040 	{0x8D1F, 0x00},
1041 	{0x8D27, 0x00},
1042 	{0x9004, 0x03},
1043 	{0x9200, 0x50},
1044 	{0x9201, 0x6C},
1045 	{0x9202, 0x71},
1046 	{0x9203, 0x00},
1047 	{0x9204, 0x71},
1048 	{0x9205, 0x01},
1049 	{0x9371, 0x6A},
1050 	{0x9373, 0x6A},
1051 	{0x9375, 0x64},
1052 	{0x991A, 0x00},
1053 	{0x996B, 0x8C},
1054 	{0x996C, 0x64},
1055 	{0x996D, 0x50},
1056 	{0x9A4C, 0x0D},
1057 	{0x9A4D, 0x0D},
1058 	{0xA001, 0x0A},
1059 	{0xA003, 0x0A},
1060 	{0xA005, 0x0A},
1061 	{0xA006, 0x01},
1062 	{0xA007, 0xC0},
1063 	{0xA009, 0xC0},
1064 
1065 	{0x3D8A, 0x01},
1066 	{0x4421, 0x08},
1067 	{0x7B3B, 0x01},
1068 	{0x7B4C, 0x00},
1069 	{0x9905, 0x00},
1070 	{0x9907, 0x00},
1071 	{0x9909, 0x00},
1072 	{0x990B, 0x00},
1073 	{0x9944, 0x3C},
1074 	{0x9947, 0x3C},
1075 	{0x994A, 0x8C},
1076 	{0x994B, 0x50},
1077 	{0x994C, 0x1B},
1078 	{0x994D, 0x8C},
1079 	{0x994E, 0x50},
1080 	{0x994F, 0x1B},
1081 	{0x9950, 0x8C},
1082 	{0x9951, 0x1B},
1083 	{0x9952, 0x0A},
1084 	{0x9953, 0x8C},
1085 	{0x9954, 0x1B},
1086 	{0x9955, 0x0A},
1087 	{0x9A13, 0x04},
1088 	{0x9A14, 0x04},
1089 	{0x9A19, 0x00},
1090 	{0x9A1C, 0x04},
1091 	{0x9A1D, 0x04},
1092 	{0x9A26, 0x05},
1093 	{0x9A27, 0x05},
1094 	{0x9A2C, 0x01},
1095 	{0x9A2D, 0x03},
1096 	{0x9A2F, 0x05},
1097 	{0x9A30, 0x05},
1098 	{0x9A41, 0x00},
1099 	{0x9A46, 0x00},
1100 	{0x9A47, 0x00},
1101 	{0x9C17, 0x35},
1102 	{0x9C1D, 0x31},
1103 	{0x9C29, 0x50},
1104 	{0x9C3B, 0x2F},
1105 	{0x9C41, 0x6B},
1106 	{0x9C47, 0x2D},
1107 	{0x9C4D, 0x40},
1108 	{0x9C6B, 0x00},
1109 	{0x9C71, 0xC8},
1110 	{0x9C73, 0x32},
1111 	{0x9C75, 0x04},
1112 	{0x9C7D, 0x2D},
1113 	{0x9C83, 0x40},
1114 	{0x9C94, 0x3F},
1115 	{0x9C95, 0x3F},
1116 	{0x9C96, 0x3F},
1117 	{0x9C97, 0x00},
1118 	{0x9C98, 0x00},
1119 	{0x9C99, 0x00},
1120 	{0x9C9A, 0x3F},
1121 	{0x9C9B, 0x3F},
1122 	{0x9C9C, 0x3F},
1123 	{0x9CA0, 0x0F},
1124 	{0x9CA1, 0x0F},
1125 	{0x9CA2, 0x0F},
1126 	{0x9CA3, 0x00},
1127 	{0x9CA4, 0x00},
1128 	{0x9CA5, 0x00},
1129 	{0x9CA6, 0x1E},
1130 	{0x9CA7, 0x1E},
1131 	{0x9CA8, 0x1E},
1132 	{0x9CA9, 0x00},
1133 	{0x9CAA, 0x00},
1134 	{0x9CAB, 0x00},
1135 	{0x9CAC, 0x09},
1136 	{0x9CAD, 0x09},
1137 	{0x9CAE, 0x09},
1138 	{0x9CBD, 0x50},
1139 	{0x9CBF, 0x50},
1140 	{0x9CC1, 0x50},
1141 	{0x9CC3, 0x40},
1142 	{0x9CC5, 0x40},
1143 	{0x9CC7, 0x40},
1144 	{0x9CC9, 0x0A},
1145 	{0x9CCB, 0x0A},
1146 	{0x9CCD, 0x0A},
1147 	{0x9D17, 0x35},
1148 	{0x9D1D, 0x31},
1149 	{0x9D29, 0x50},
1150 	{0x9D3B, 0x2F},
1151 	{0x9D41, 0x6B},
1152 	{0x9D47, 0x42},
1153 	{0x9D4D, 0x5A},
1154 	{0x9D6B, 0x00},
1155 	{0x9D71, 0xC8},
1156 	{0x9D73, 0x32},
1157 	{0x9D75, 0x04},
1158 	{0x9D7D, 0x42},
1159 	{0x9D83, 0x5A},
1160 	{0x9D94, 0x3F},
1161 	{0x9D95, 0x3F},
1162 	{0x9D96, 0x3F},
1163 	{0x9D97, 0x00},
1164 	{0x9D98, 0x00},
1165 	{0x9D99, 0x00},
1166 	{0x9D9A, 0x3F},
1167 	{0x9D9B, 0x3F},
1168 	{0x9D9C, 0x3F},
1169 	{0x9D9D, 0x1F},
1170 	{0x9D9E, 0x1F},
1171 	{0x9D9F, 0x1F},
1172 	{0x9DA0, 0x0F},
1173 	{0x9DA1, 0x0F},
1174 	{0x9DA2, 0x0F},
1175 	{0x9DA3, 0x00},
1176 	{0x9DA4, 0x00},
1177 	{0x9DA5, 0x00},
1178 	{0x9DA6, 0x1E},
1179 	{0x9DA7, 0x1E},
1180 	{0x9DA8, 0x1E},
1181 	{0x9DA9, 0x00},
1182 	{0x9DAA, 0x00},
1183 	{0x9DAB, 0x00},
1184 	{0x9DAC, 0x09},
1185 	{0x9DAD, 0x09},
1186 	{0x9DAE, 0x09},
1187 	{0x9DC9, 0x0A},
1188 	{0x9DCB, 0x0A},
1189 	{0x9DCD, 0x0A},
1190 	{0x9E17, 0x35},
1191 	{0x9E1D, 0x31},
1192 	{0x9E29, 0x50},
1193 	{0x9E3B, 0x2F},
1194 	{0x9E41, 0x6B},
1195 	{0x9E47, 0x2D},
1196 	{0x9E4D, 0x40},
1197 	{0x9E6B, 0x00},
1198 	{0x9E71, 0xC8},
1199 	{0x9E73, 0x32},
1200 	{0x9E75, 0x04},
1201 	{0x9E94, 0x0F},
1202 	{0x9E95, 0x0F},
1203 	{0x9E96, 0x0F},
1204 	{0x9E97, 0x00},
1205 	{0x9E98, 0x00},
1206 	{0x9E99, 0x00},
1207 	{0x9EA0, 0x0F},
1208 	{0x9EA1, 0x0F},
1209 	{0x9EA2, 0x0F},
1210 	{0x9EA3, 0x00},
1211 	{0x9EA4, 0x00},
1212 	{0x9EA5, 0x00},
1213 	{0x9EA6, 0x3F},
1214 	{0x9EA7, 0x3F},
1215 	{0x9EA8, 0x3F},
1216 	{0x9EA9, 0x00},
1217 	{0x9EAA, 0x00},
1218 	{0x9EAB, 0x00},
1219 	{0x9EAC, 0x09},
1220 	{0x9EAD, 0x09},
1221 	{0x9EAE, 0x09},
1222 	{0x9EC9, 0x0A},
1223 	{0x9ECB, 0x0A},
1224 	{0x9ECD, 0x0A},
1225 	{0x9F17, 0x35},
1226 	{0x9F1D, 0x31},
1227 	{0x9F29, 0x50},
1228 	{0x9F3B, 0x2F},
1229 	{0x9F41, 0x6B},
1230 	{0x9F47, 0x42},
1231 	{0x9F4D, 0x5A},
1232 	{0x9F6B, 0x00},
1233 	{0x9F71, 0xC8},
1234 	{0x9F73, 0x32},
1235 	{0x9F75, 0x04},
1236 	{0x9F94, 0x0F},
1237 	{0x9F95, 0x0F},
1238 	{0x9F96, 0x0F},
1239 	{0x9F97, 0x00},
1240 	{0x9F98, 0x00},
1241 	{0x9F99, 0x00},
1242 	{0x9F9A, 0x2F},
1243 	{0x9F9B, 0x2F},
1244 	{0x9F9C, 0x2F},
1245 	{0x9F9D, 0x00},
1246 	{0x9F9E, 0x00},
1247 	{0x9F9F, 0x00},
1248 	{0x9FA0, 0x0F},
1249 	{0x9FA1, 0x0F},
1250 	{0x9FA2, 0x0F},
1251 	{0x9FA3, 0x00},
1252 	{0x9FA4, 0x00},
1253 	{0x9FA5, 0x00},
1254 	{0x9FA6, 0x1E},
1255 	{0x9FA7, 0x1E},
1256 	{0x9FA8, 0x1E},
1257 	{0x9FA9, 0x00},
1258 	{0x9FAA, 0x00},
1259 	{0x9FAB, 0x00},
1260 	{0x9FAC, 0x09},
1261 	{0x9FAD, 0x09},
1262 	{0x9FAE, 0x09},
1263 	{0x9FC9, 0x0A},
1264 	{0x9FCB, 0x0A},
1265 	{0x9FCD, 0x0A},
1266 	{0xA14B, 0xFF},
1267 	{0xA151, 0x0C},
1268 	{0xA153, 0x50},
1269 	{0xA155, 0x02},
1270 	{0xA157, 0x00},
1271 	{0xA1AD, 0xFF},
1272 	{0xA1B3, 0x0C},
1273 	{0xA1B5, 0x50},
1274 	{0xA1B9, 0x00},
1275 	{0xA24B, 0xFF},
1276 	{0xA257, 0x00},
1277 	{0xA2AD, 0xFF},
1278 	{0xA2B9, 0x00},
1279 	{0xB21F, 0x04},
1280 	{0xB35C, 0x00},
1281 	{0xB35E, 0x08},
1282 
1283 	{0x0112, 0x0C},
1284 	{0x0113, 0x0C},
1285 	{0x0114, 0x03},
1286 	{0x0342, 0x1B},
1287 	{0x0343, 0xD8},
1288 	{0x0340, 0x0F},
1289 	{0x0341, 0x57},
1290 	{0x0344, 0x00},
1291 	{0x0345, 0x00},
1292 	{0x0346, 0x00},
1293 	{0x0347, 0x00},
1294 	{0x0348, 0x0F},
1295 	{0x0349, 0xD7},
1296 	{0x034A, 0x0B},
1297 	{0x034B, 0xDF},
1298 	{0x0220, 0x00},
1299 	{0x0221, 0x11},
1300 	{0x0381, 0x01},
1301 	{0x0383, 0x01},
1302 	{0x0385, 0x01},
1303 	{0x0387, 0x01},
1304 	{0x0900, 0x00},
1305 	{0x0901, 0x11},
1306 	{0x0902, 0x02},
1307 	{0x3140, 0x02},
1308 	{0x3C00, 0x00},
1309 	{0x3C01, 0x03},
1310 	{0x3C02, 0xA2},
1311 	{0x3F0D, 0x01},
1312 	{0x5748, 0x07},
1313 	{0x5749, 0xFF},
1314 	{0x574A, 0x00},
1315 	{0x574B, 0x00},
1316 	{0x7B53, 0x01},
1317 	{0x9369, 0x5A},
1318 	{0x936B, 0x55},
1319 	{0x936D, 0x28},
1320 	{0x9304, 0x03},
1321 	{0x9305, 0x00},
1322 	{0x9E9A, 0x2F},
1323 	{0x9E9B, 0x2F},
1324 	{0x9E9C, 0x2F},
1325 	{0x9E9D, 0x00},
1326 	{0x9E9E, 0x00},
1327 	{0x9E9F, 0x00},
1328 	{0xA2A9, 0x60},
1329 	{0xA2B7, 0x00},
1330 	{0x0401, 0x00},
1331 	{0x0404, 0x00},
1332 	{0x0405, 0x10},
1333 	{0x0408, 0x00},
1334 	{0x0409, 0x00},
1335 	{0x040A, 0x00},
1336 	{0x040B, 0x00},
1337 	{0x040C, 0x0F},
1338 	{0x040D, 0xD8},
1339 	{0x040E, 0x0B},
1340 	{0x040F, 0xE0},
1341 	{0x034C, 0x0F},
1342 	{0x034D, 0xD8},
1343 	{0x034E, 0x0B},
1344 	{0x034F, 0xE0},
1345 	{0x0301, 0x05},
1346 	{0x0303, 0x02},
1347 	{0x0305, 0x02},
1348 	{0x0306, 0x00},
1349 	{0x0307, 0xAF},
1350 	{0x0309, 0x0C},
1351 	{0x030B, 0x01},
1352 	{0x030D, 0x03},
1353 	{0x030E, 0x00},
1354 	{0x030F, 0xD4},
1355 	{0x0310, 0x01},
1356 	{0x0820, 0x1A},
1357 	{0x0821, 0x80},
1358 	{0x0822, 0x00},
1359 	{0x0823, 0x00},
1360 	{0x3E20, 0x01},
1361 	{0x3E37, 0x01},
1362 	{0x3F50, 0x00},
1363 	{0x3F56, 0x00},
1364 	{0x3F57, 0xB8},
1365 	{REG_NULL, 0x00},
1366 };
1367 
1368 static const struct regval imx378_linear_12_2028x1520_regs[] = {
1369 	{0x0101, 0x00},
1370 	{0x0136, 0x18},
1371 	{0x0137, 0x00},
1372 	{0xE000, 0x00},
1373 	{0x4AE9, 0x18},
1374 	{0x4AEA, 0x08},
1375 	{0xF61C, 0x04},
1376 	{0xF61E, 0x04},
1377 	{0x4AE9, 0x21},
1378 	{0x4AEA, 0x80},
1379 	{0x38A8, 0x1F},
1380 	{0x38A9, 0xFF},
1381 	{0x38AA, 0x1F},
1382 	{0x38AB, 0xFF},
1383 	{0x55D4, 0x00},
1384 	{0x55D5, 0x00},
1385 	{0x55D6, 0x07},
1386 	{0x55D7, 0xFF},
1387 	{0x55E8, 0x07},
1388 	{0x55E9, 0xFF},
1389 	{0x55EA, 0x00},
1390 	{0x55EB, 0x00},
1391 	{0x574C, 0x07},
1392 	{0x574D, 0xFF},
1393 	{0x574E, 0x00},
1394 	{0x574F, 0x00},
1395 	{0x5754, 0x00},
1396 	{0x5755, 0x00},
1397 	{0x5756, 0x07},
1398 	{0x5757, 0xFF},
1399 	{0x5973, 0x04},
1400 	{0x5974, 0x01},
1401 	{0x5D13, 0xC3},
1402 	{0x5D14, 0x58},
1403 	{0x5D15, 0xA3},
1404 	{0x5D16, 0x1D},
1405 	{0x5D17, 0x65},
1406 	{0x5D18, 0x8C},
1407 	{0x5D1A, 0x06},
1408 	{0x5D1B, 0xA9},
1409 	{0x5D1C, 0x45},
1410 	{0x5D1D, 0x3A},
1411 	{0x5D1E, 0xAB},
1412 	{0x5D1F, 0x15},
1413 	{0x5D21, 0x0E},
1414 	{0x5D22, 0x52},
1415 	{0x5D23, 0xAA},
1416 	{0x5D24, 0x7D},
1417 	{0x5D25, 0x57},
1418 	{0x5D26, 0xA8},
1419 	{0x5D37, 0x5A},
1420 	{0x5D38, 0x5A},
1421 	{0x5D77, 0x7F},
1422 	{0x7B75, 0x0E},
1423 	{0x7B76, 0x0B},
1424 	{0x7B77, 0x08},
1425 	{0x7B78, 0x0A},
1426 	{0x7B79, 0x47},
1427 	{0x7B7C, 0x00},
1428 	{0x7B7D, 0x00},
1429 	{0x8D1F, 0x00},
1430 	{0x8D27, 0x00},
1431 	{0x9004, 0x03},
1432 	{0x9200, 0x50},
1433 	{0x9201, 0x6C},
1434 	{0x9202, 0x71},
1435 	{0x9203, 0x00},
1436 	{0x9204, 0x71},
1437 	{0x9205, 0x01},
1438 	{0x9371, 0x6A},
1439 	{0x9373, 0x6A},
1440 	{0x9375, 0x64},
1441 	{0x991A, 0x00},
1442 	{0x996B, 0x8C},
1443 	{0x996C, 0x64},
1444 	{0x996D, 0x50},
1445 	{0x9A4C, 0x0D},
1446 	{0x9A4D, 0x0D},
1447 	{0xA001, 0x0A},
1448 	{0xA003, 0x0A},
1449 	{0xA005, 0x0A},
1450 	{0xA006, 0x01},
1451 	{0xA007, 0xC0},
1452 	{0xA009, 0xC0},
1453 
1454 	{0x3D8A, 0x01},
1455 	{0x4421, 0x08},
1456 	{0x7B3B, 0x01},
1457 	{0x7B4C, 0x00},
1458 	{0x9905, 0x00},
1459 	{0x9907, 0x00},
1460 	{0x9909, 0x00},
1461 	{0x990B, 0x00},
1462 	{0x9944, 0x3C},
1463 	{0x9947, 0x3C},
1464 	{0x994A, 0x8C},
1465 	{0x994B, 0x50},
1466 	{0x994C, 0x1B},
1467 	{0x994D, 0x8C},
1468 	{0x994E, 0x50},
1469 	{0x994F, 0x1B},
1470 	{0x9950, 0x8C},
1471 	{0x9951, 0x1B},
1472 	{0x9952, 0x0A},
1473 	{0x9953, 0x8C},
1474 	{0x9954, 0x1B},
1475 	{0x9955, 0x0A},
1476 	{0x9A13, 0x04},
1477 	{0x9A14, 0x04},
1478 	{0x9A19, 0x00},
1479 	{0x9A1C, 0x04},
1480 	{0x9A1D, 0x04},
1481 	{0x9A26, 0x05},
1482 	{0x9A27, 0x05},
1483 	{0x9A2C, 0x01},
1484 	{0x9A2D, 0x03},
1485 	{0x9A2F, 0x05},
1486 	{0x9A30, 0x05},
1487 	{0x9A41, 0x00},
1488 	{0x9A46, 0x00},
1489 	{0x9A47, 0x00},
1490 	{0x9C17, 0x35},
1491 	{0x9C1D, 0x31},
1492 	{0x9C29, 0x50},
1493 	{0x9C3B, 0x2F},
1494 	{0x9C41, 0x6B},
1495 	{0x9C47, 0x2D},
1496 	{0x9C4D, 0x40},
1497 	{0x9C6B, 0x00},
1498 	{0x9C71, 0xC8},
1499 	{0x9C73, 0x32},
1500 	{0x9C75, 0x04},
1501 	{0x9C7D, 0x2D},
1502 	{0x9C83, 0x40},
1503 	{0x9C94, 0x3F},
1504 	{0x9C95, 0x3F},
1505 	{0x9C96, 0x3F},
1506 	{0x9C97, 0x00},
1507 	{0x9C98, 0x00},
1508 	{0x9C99, 0x00},
1509 	{0x9C9A, 0x3F},
1510 	{0x9C9B, 0x3F},
1511 	{0x9C9C, 0x3F},
1512 	{0x9CA0, 0x0F},
1513 	{0x9CA1, 0x0F},
1514 	{0x9CA2, 0x0F},
1515 	{0x9CA3, 0x00},
1516 	{0x9CA4, 0x00},
1517 	{0x9CA5, 0x00},
1518 	{0x9CA6, 0x1E},
1519 	{0x9CA7, 0x1E},
1520 	{0x9CA8, 0x1E},
1521 	{0x9CA9, 0x00},
1522 	{0x9CAA, 0x00},
1523 	{0x9CAB, 0x00},
1524 	{0x9CAC, 0x09},
1525 	{0x9CAD, 0x09},
1526 	{0x9CAE, 0x09},
1527 	{0x9CBD, 0x50},
1528 	{0x9CBF, 0x50},
1529 	{0x9CC1, 0x50},
1530 	{0x9CC3, 0x40},
1531 	{0x9CC5, 0x40},
1532 	{0x9CC7, 0x40},
1533 	{0x9CC9, 0x0A},
1534 	{0x9CCB, 0x0A},
1535 	{0x9CCD, 0x0A},
1536 	{0x9D17, 0x35},
1537 	{0x9D1D, 0x31},
1538 	{0x9D29, 0x50},
1539 	{0x9D3B, 0x2F},
1540 	{0x9D41, 0x6B},
1541 	{0x9D47, 0x42},
1542 	{0x9D4D, 0x5A},
1543 	{0x9D6B, 0x00},
1544 	{0x9D71, 0xC8},
1545 	{0x9D73, 0x32},
1546 	{0x9D75, 0x04},
1547 	{0x9D7D, 0x42},
1548 	{0x9D83, 0x5A},
1549 	{0x9D94, 0x3F},
1550 	{0x9D95, 0x3F},
1551 	{0x9D96, 0x3F},
1552 	{0x9D97, 0x00},
1553 	{0x9D98, 0x00},
1554 	{0x9D99, 0x00},
1555 	{0x9D9A, 0x3F},
1556 	{0x9D9B, 0x3F},
1557 	{0x9D9C, 0x3F},
1558 	{0x9D9D, 0x1F},
1559 	{0x9D9E, 0x1F},
1560 	{0x9D9F, 0x1F},
1561 	{0x9DA0, 0x0F},
1562 	{0x9DA1, 0x0F},
1563 	{0x9DA2, 0x0F},
1564 	{0x9DA3, 0x00},
1565 	{0x9DA4, 0x00},
1566 	{0x9DA5, 0x00},
1567 	{0x9DA6, 0x1E},
1568 	{0x9DA7, 0x1E},
1569 	{0x9DA8, 0x1E},
1570 	{0x9DA9, 0x00},
1571 	{0x9DAA, 0x00},
1572 	{0x9DAB, 0x00},
1573 	{0x9DAC, 0x09},
1574 	{0x9DAD, 0x09},
1575 	{0x9DAE, 0x09},
1576 	{0x9DC9, 0x0A},
1577 	{0x9DCB, 0x0A},
1578 	{0x9DCD, 0x0A},
1579 	{0x9E17, 0x35},
1580 	{0x9E1D, 0x31},
1581 	{0x9E29, 0x50},
1582 	{0x9E3B, 0x2F},
1583 	{0x9E41, 0x6B},
1584 	{0x9E47, 0x2D},
1585 	{0x9E4D, 0x40},
1586 	{0x9E6B, 0x00},
1587 	{0x9E71, 0xC8},
1588 	{0x9E73, 0x32},
1589 	{0x9E75, 0x04},
1590 	{0x9E94, 0x0F},
1591 	{0x9E95, 0x0F},
1592 	{0x9E96, 0x0F},
1593 	{0x9E97, 0x00},
1594 	{0x9E98, 0x00},
1595 	{0x9E99, 0x00},
1596 	{0x9EA0, 0x0F},
1597 	{0x9EA1, 0x0F},
1598 	{0x9EA2, 0x0F},
1599 	{0x9EA3, 0x00},
1600 	{0x9EA4, 0x00},
1601 	{0x9EA5, 0x00},
1602 	{0x9EA6, 0x3F},
1603 	{0x9EA7, 0x3F},
1604 	{0x9EA8, 0x3F},
1605 	{0x9EA9, 0x00},
1606 	{0x9EAA, 0x00},
1607 	{0x9EAB, 0x00},
1608 	{0x9EAC, 0x09},
1609 	{0x9EAD, 0x09},
1610 	{0x9EAE, 0x09},
1611 	{0x9EC9, 0x0A},
1612 	{0x9ECB, 0x0A},
1613 	{0x9ECD, 0x0A},
1614 	{0x9F17, 0x35},
1615 	{0x9F1D, 0x31},
1616 	{0x9F29, 0x50},
1617 	{0x9F3B, 0x2F},
1618 	{0x9F41, 0x6B},
1619 	{0x9F47, 0x42},
1620 	{0x9F4D, 0x5A},
1621 	{0x9F6B, 0x00},
1622 	{0x9F71, 0xC8},
1623 	{0x9F73, 0x32},
1624 	{0x9F75, 0x04},
1625 	{0x9F94, 0x0F},
1626 	{0x9F95, 0x0F},
1627 	{0x9F96, 0x0F},
1628 	{0x9F97, 0x00},
1629 	{0x9F98, 0x00},
1630 	{0x9F99, 0x00},
1631 	{0x9F9A, 0x2F},
1632 	{0x9F9B, 0x2F},
1633 	{0x9F9C, 0x2F},
1634 	{0x9F9D, 0x00},
1635 	{0x9F9E, 0x00},
1636 	{0x9F9F, 0x00},
1637 	{0x9FA0, 0x0F},
1638 	{0x9FA1, 0x0F},
1639 	{0x9FA2, 0x0F},
1640 	{0x9FA3, 0x00},
1641 	{0x9FA4, 0x00},
1642 	{0x9FA5, 0x00},
1643 	{0x9FA6, 0x1E},
1644 	{0x9FA7, 0x1E},
1645 	{0x9FA8, 0x1E},
1646 	{0x9FA9, 0x00},
1647 	{0x9FAA, 0x00},
1648 	{0x9FAB, 0x00},
1649 	{0x9FAC, 0x09},
1650 	{0x9FAD, 0x09},
1651 	{0x9FAE, 0x09},
1652 	{0x9FC9, 0x0A},
1653 	{0x9FCB, 0x0A},
1654 	{0x9FCD, 0x0A},
1655 	{0xA14B, 0xFF},
1656 	{0xA151, 0x0C},
1657 	{0xA153, 0x50},
1658 	{0xA155, 0x02},
1659 	{0xA157, 0x00},
1660 	{0xA1AD, 0xFF},
1661 	{0xA1B3, 0x0C},
1662 	{0xA1B5, 0x50},
1663 	{0xA1B9, 0x00},
1664 	{0xA24B, 0xFF},
1665 	{0xA257, 0x00},
1666 	{0xA2AD, 0xFF},
1667 	{0xA2B9, 0x00},
1668 	{0xB21F, 0x04},
1669 	{0xB35C, 0x00},
1670 	{0xB35E, 0x08},
1671 
1672 	{0x0112, 0x0C},
1673 	{0x0113, 0x0C},
1674 	{0x0114, 0x03},
1675 	{0x0342, 0x1B},
1676 	{0x0343, 0xD8},
1677 	{0x0340, 0x0F},
1678 	{0x0341, 0x57},
1679 	{0x0344, 0x00},
1680 	{0x0345, 0x00},
1681 	{0x0346, 0x00},
1682 	{0x0347, 0x00},
1683 	{0x0348, 0x0F},
1684 	{0x0349, 0xD7},
1685 	{0x034A, 0x0B},
1686 	{0x034B, 0xDF},
1687 	{0x0220, 0x00},
1688 	{0x0221, 0x11},
1689 	{0x0381, 0x01},
1690 	{0x0383, 0x01},
1691 	{0x0385, 0x01},
1692 	{0x0387, 0x01},
1693 	{0x0900, 0x01},
1694 	{0x0901, 0x22},
1695 	{0x0902, 0x02},
1696 	{0x3140, 0x02},
1697 	{0x3C00, 0x00},
1698 	{0x3C01, 0x01},
1699 	{0x3C02, 0x9C},
1700 	{0x3F0D, 0x00},
1701 	{0x5748, 0x00},
1702 	{0x5749, 0x00},
1703 	{0x574A, 0x00},
1704 	{0x574B, 0xA4},
1705 	{0x7B53, 0x00},
1706 	{0x9369, 0x73},
1707 	{0x936B, 0x64},
1708 	{0x936D, 0x5F},
1709 	{0x9304, 0x03},
1710 	{0x9305, 0x80},
1711 	{0x9E9A, 0x2F},
1712 	{0x9E9B, 0x2F},
1713 	{0x9E9C, 0x2F},
1714 	{0x9E9D, 0x00},
1715 	{0x9E9E, 0x00},
1716 	{0x9E9F, 0x00},
1717 	{0xA2A9, 0x27},
1718 	{0xA2B7, 0x03},
1719 	{0x0401, 0x00},
1720 	{0x0404, 0x00},
1721 	{0x0405, 0x10},
1722 	{0x0408, 0x00},
1723 	{0x0409, 0x00},
1724 	{0x040A, 0x00},
1725 	{0x040B, 0x00},
1726 	{0x040C, 0x07},
1727 	{0x040D, 0xEC},
1728 	{0x040E, 0x05},
1729 	{0x040F, 0xF0},
1730 	{0x034C, 0x07},
1731 	{0x034D, 0xEC},
1732 	{0x034E, 0x05},
1733 	{0x034F, 0xF0},
1734 	{0x0301, 0x05},
1735 	{0x0303, 0x02},
1736 	{0x0305, 0x02},
1737 	{0x0306, 0x00},
1738 	{0x0307, 0xAF},
1739 	{0x0309, 0x0C},
1740 	{0x030B, 0x01},
1741 	{0x030D, 0x03},
1742 	{0x030E, 0x00},
1743 	{0x030F, 0xD4},
1744 	{0x0310, 0x01},
1745 	{0x0820, 0x1A},
1746 	{0x0821, 0x80},
1747 	{0x0822, 0x00},
1748 	{0x0823, 0x00},
1749 	{0x3E20, 0x01},
1750 	{0x3E37, 0x01},
1751 	{0x3F50, 0x00},
1752 	{0x3F56, 0x00},
1753 	{0x3F57, 0xCC},
1754 	{REG_NULL, 0x00},
1755 };
1756 
1757 static const struct imx378_mode supported_modes[] = {
1758 	{
1759 		.width = 3840,
1760 		.height = 2160,
1761 		.max_fps = {
1762 			.numerator = 10000,
1763 			.denominator = 300000,
1764 		},
1765 		.exp_def = 0x0600,
1766 		.hts_def = 0x16A8,
1767 		.vts_def = 0x0F3C,
1768 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1769 		.reg_list = imx378_linear_10_3840x2160_regs,
1770 		.hdr_mode = NO_HDR,
1771 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1772 	}, {
1773 		.width = 4056,
1774 		.height = 3040,
1775 		.max_fps = {
1776 			.numerator = 10000,
1777 			.denominator = 300000,
1778 		},
1779 		.exp_def = 0x0600,
1780 		.hts_def = 0x16A8,
1781 		.vts_def = 0x0F3C,
1782 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1783 		.reg_list = imx378_linear_10_4056x3040_regs,
1784 		.hdr_mode = NO_HDR,
1785 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1786 	}, {
1787 		.width = 2028,
1788 		.height = 1520,
1789 		.max_fps = {
1790 			.numerator = 10000,
1791 			.denominator = 300000,
1792 		},
1793 		.exp_def = 0x0C80,
1794 		.hts_def = 0x1BD8,
1795 		.vts_def = 0x0F57,
1796 		.bus_fmt = MEDIA_BUS_FMT_SRGGB12_1X12,
1797 		.reg_list = imx378_linear_12_2028x1520_regs,
1798 		.hdr_mode = NO_HDR,
1799 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1800 	}, {
1801 		.width = 4056,
1802 		.height = 3040,
1803 		.max_fps = {
1804 			.numerator = 10000,
1805 			.denominator = 300000,
1806 		},
1807 		.exp_def = 0x0600,
1808 		.hts_def = 0x1BD8,
1809 		.vts_def = 0x0F57,
1810 		.bus_fmt = MEDIA_BUS_FMT_SRGGB12_1X12,
1811 		.reg_list = imx378_linear_12_4056x3040_regs,
1812 		.hdr_mode = NO_HDR,
1813 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1814 	},
1815 };
1816 
1817 static const s64 link_freq_menu_items[] = {
1818 	IMX378_LINK_FREQ_848,
1819 };
1820 
1821 static const char * const imx378_test_pattern_menu[] = {
1822 	"Disabled",
1823 	"Vertical Color Bar Type 1",
1824 	"Vertical Color Bar Type 2",
1825 	"Vertical Color Bar Type 3",
1826 	"Vertical Color Bar Type 4"
1827 };
1828 
1829 /* Write registers up to 4 at a time */
imx378_write_reg(struct i2c_client * client,u16 reg,int len,u32 val)1830 static int imx378_write_reg(struct i2c_client *client, u16 reg,
1831 			    int len, u32 val)
1832 {
1833 	u32 buf_i, val_i;
1834 	u8 buf[6];
1835 	u8 *val_p;
1836 	__be32 val_be;
1837 
1838 	if (len > 4)
1839 		return -EINVAL;
1840 
1841 	buf[0] = reg >> 8;
1842 	buf[1] = reg & 0xff;
1843 
1844 	val_be = cpu_to_be32(val);
1845 	val_p = (u8 *)&val_be;
1846 	buf_i = 2;
1847 	val_i = 4 - len;
1848 
1849 	while (val_i < 4)
1850 		buf[buf_i++] = val_p[val_i++];
1851 
1852 	if (i2c_master_send(client, buf, len + 2) != len + 2)
1853 		return -EIO;
1854 
1855 	return 0;
1856 }
1857 
imx378_write_array(struct i2c_client * client,const struct regval * regs)1858 static int imx378_write_array(struct i2c_client *client,
1859 			      const struct regval *regs)
1860 {
1861 	u32 i;
1862 	int ret = 0;
1863 
1864 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
1865 		if (unlikely(regs[i].addr == REG_DELAY))
1866 			usleep_range(regs[i].val, regs[i].val * 2);
1867 		else
1868 			ret = imx378_write_reg(client, regs[i].addr,
1869 					       IMX378_REG_VALUE_08BIT,
1870 					       regs[i].val);
1871 
1872 	return ret;
1873 }
1874 
1875 /* Read registers up to 4 at a time */
imx378_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)1876 static int imx378_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
1877 			   u32 *val)
1878 {
1879 	struct i2c_msg msgs[2];
1880 	u8 *data_be_p;
1881 	__be32 data_be = 0;
1882 	__be16 reg_addr_be = cpu_to_be16(reg);
1883 	int ret, i;
1884 
1885 	if (len > 4 || !len)
1886 		return -EINVAL;
1887 
1888 	data_be_p = (u8 *)&data_be;
1889 	/* Write register address */
1890 	msgs[0].addr = client->addr;
1891 	msgs[0].flags = 0;
1892 	msgs[0].len = 2;
1893 	msgs[0].buf = (u8 *)&reg_addr_be;
1894 
1895 	/* Read data from register */
1896 	msgs[1].addr = client->addr;
1897 	msgs[1].flags = I2C_M_RD;
1898 	msgs[1].len = len;
1899 	msgs[1].buf = &data_be_p[4 - len];
1900 
1901 	for (i = 0; i < 3; i++) {
1902 		ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1903 		if (ret == ARRAY_SIZE(msgs))
1904 			break;
1905 	}
1906 	if (ret != ARRAY_SIZE(msgs) && i == 3)
1907 		return -EIO;
1908 
1909 	*val = be32_to_cpu(data_be);
1910 
1911 	return 0;
1912 }
1913 
imx378_get_reso_dist(const struct imx378_mode * mode,struct v4l2_mbus_framefmt * framefmt)1914 static int imx378_get_reso_dist(const struct imx378_mode *mode,
1915 				struct v4l2_mbus_framefmt *framefmt)
1916 {
1917 	return abs(mode->width - framefmt->width) +
1918 		   abs(mode->height - framefmt->height);
1919 }
1920 
1921 static const struct imx378_mode *
imx378_find_best_fit(struct imx378 * imx378,struct v4l2_subdev_format * fmt)1922 imx378_find_best_fit(struct imx378 *imx378, struct v4l2_subdev_format *fmt)
1923 {
1924 	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
1925 	int dist;
1926 	int cur_best_fit = 0;
1927 	int cur_best_fit_dist = -1;
1928 	unsigned int i;
1929 
1930 	for (i = 0; i < imx378->cfg_num; i++) {
1931 		dist = imx378_get_reso_dist(&supported_modes[i], framefmt);
1932 		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
1933 			cur_best_fit_dist = dist;
1934 			cur_best_fit = i;
1935 		}
1936 	}
1937 
1938 	return &supported_modes[cur_best_fit];
1939 }
1940 
imx378_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1941 static int imx378_set_fmt(struct v4l2_subdev *sd,
1942 			  struct v4l2_subdev_pad_config *cfg,
1943 			  struct v4l2_subdev_format *fmt)
1944 {
1945 	struct imx378 *imx378 = to_imx378(sd);
1946 	const struct imx378_mode *mode;
1947 	s64 h_blank, vblank_def;
1948 
1949 	mutex_lock(&imx378->mutex);
1950 
1951 	mode = imx378_find_best_fit(imx378, fmt);
1952 	fmt->format.code = mode->bus_fmt;
1953 	fmt->format.width = mode->width;
1954 	fmt->format.height = mode->height;
1955 	fmt->format.field = V4L2_FIELD_NONE;
1956 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1957 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1958 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
1959 #else
1960 		mutex_unlock(&imx378->mutex);
1961 		return -ENOTTY;
1962 #endif
1963 	} else {
1964 		imx378->cur_mode = mode;
1965 		h_blank = mode->hts_def - mode->width;
1966 		__v4l2_ctrl_modify_range(imx378->hblank, h_blank,
1967 					 h_blank, 1, h_blank);
1968 		vblank_def = mode->vts_def - mode->height;
1969 		__v4l2_ctrl_modify_range(imx378->vblank, vblank_def,
1970 					 IMX378_VTS_MAX - mode->height,
1971 					 1, vblank_def);
1972 
1973 		if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
1974 			imx378->cur_link_freq = 0;
1975 			imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_10BIT;
1976 		} else if (imx378->cur_mode->bus_fmt ==
1977 			   MEDIA_BUS_FMT_SRGGB12_1X12) {
1978 			imx378->cur_link_freq = 0;
1979 			imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_12BIT;
1980 		}
1981 
1982 		__v4l2_ctrl_s_ctrl_int64(imx378->pixel_rate,
1983 					 imx378->cur_pixel_rate);
1984 		__v4l2_ctrl_s_ctrl(imx378->link_freq,
1985 				   imx378->cur_link_freq);
1986 	}
1987 
1988 	mutex_unlock(&imx378->mutex);
1989 
1990 	return 0;
1991 }
1992 
imx378_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1993 static int imx378_get_fmt(struct v4l2_subdev *sd,
1994 			  struct v4l2_subdev_pad_config *cfg,
1995 			  struct v4l2_subdev_format *fmt)
1996 {
1997 	struct imx378 *imx378 = to_imx378(sd);
1998 	const struct imx378_mode *mode = imx378->cur_mode;
1999 
2000 	mutex_lock(&imx378->mutex);
2001 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2002 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2003 		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2004 #else
2005 		mutex_unlock(&imx378->mutex);
2006 		return -ENOTTY;
2007 #endif
2008 	} else {
2009 		fmt->format.width = mode->width;
2010 		fmt->format.height = mode->height;
2011 		if (imx378->flip & IMX378_MIRROR_BIT_MASK) {
2012 			fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
2013 			if (imx378->flip & IMX378_FLIP_BIT_MASK)
2014 				fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
2015 		} else if (imx378->flip & IMX378_FLIP_BIT_MASK) {
2016 			fmt->format.code = MEDIA_BUS_FMT_SGBRG10_1X10;
2017 		} else {
2018 			fmt->format.code = mode->bus_fmt;
2019 		}
2020 		fmt->format.field = V4L2_FIELD_NONE;
2021 		/* format info: width/height/data type/virctual channel */
2022 		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
2023 			fmt->reserved[0] = mode->vc[fmt->pad];
2024 		else
2025 			fmt->reserved[0] = mode->vc[PAD0];
2026 	}
2027 	mutex_unlock(&imx378->mutex);
2028 
2029 	return 0;
2030 }
2031 
imx378_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)2032 static int imx378_enum_mbus_code(struct v4l2_subdev *sd,
2033 				 struct v4l2_subdev_pad_config *cfg,
2034 				 struct v4l2_subdev_mbus_code_enum *code)
2035 {
2036 	struct imx378 *imx378 = to_imx378(sd);
2037 
2038 	if (code->index != 0)
2039 		return -EINVAL;
2040 	code->code = imx378->cur_mode->bus_fmt;
2041 
2042 	return 0;
2043 }
2044 
imx378_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)2045 static int imx378_enum_frame_sizes(struct v4l2_subdev *sd,
2046 				   struct v4l2_subdev_pad_config *cfg,
2047 				   struct v4l2_subdev_frame_size_enum *fse)
2048 {
2049 	struct imx378 *imx378 = to_imx378(sd);
2050 
2051 	if (fse->index >= imx378->cfg_num)
2052 		return -EINVAL;
2053 
2054 	if (fse->code != supported_modes[0].bus_fmt)
2055 		return -EINVAL;
2056 
2057 	fse->min_width = supported_modes[fse->index].width;
2058 	fse->max_width = supported_modes[fse->index].width;
2059 	fse->max_height = supported_modes[fse->index].height;
2060 	fse->min_height = supported_modes[fse->index].height;
2061 
2062 	return 0;
2063 }
2064 
imx378_enable_test_pattern(struct imx378 * imx378,u32 pattern)2065 static int imx378_enable_test_pattern(struct imx378 *imx378, u32 pattern)
2066 {
2067 	u32 val;
2068 
2069 	if (pattern)
2070 		val = (pattern - 1) | IMX378_TEST_PATTERN_ENABLE;
2071 	else
2072 		val = IMX378_TEST_PATTERN_DISABLE;
2073 
2074 	return imx378_write_reg(imx378->client,
2075 				IMX378_REG_TEST_PATTERN,
2076 				IMX378_REG_VALUE_08BIT,
2077 				val);
2078 }
2079 
imx378_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)2080 static int imx378_g_frame_interval(struct v4l2_subdev *sd,
2081 				   struct v4l2_subdev_frame_interval *fi)
2082 {
2083 	struct imx378 *imx378 = to_imx378(sd);
2084 	const struct imx378_mode *mode = imx378->cur_mode;
2085 
2086 	fi->interval = mode->max_fps;
2087 
2088 	return 0;
2089 }
2090 
imx378_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)2091 static int imx378_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
2092 				struct v4l2_mbus_config *config)
2093 {
2094 	struct imx378 *imx378 = to_imx378(sd);
2095 	const struct imx378_mode *mode = imx378->cur_mode;
2096 	u32 val = 0;
2097 
2098 	if (mode->hdr_mode == NO_HDR)
2099 		val = 1 << (IMX378_LANES - 1) |
2100 		V4L2_MBUS_CSI2_CHANNEL_0 |
2101 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
2102 
2103 	if (mode->hdr_mode == HDR_X2)
2104 		val = 1 << (IMX378_LANES - 1) |
2105 		V4L2_MBUS_CSI2_CHANNEL_0 |
2106 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
2107 		V4L2_MBUS_CSI2_CHANNEL_1;
2108 
2109 	config->type = V4L2_MBUS_CSI2_DPHY;
2110 	config->flags = val;
2111 
2112 	return 0;
2113 }
2114 
imx378_get_module_inf(struct imx378 * imx378,struct rkmodule_inf * inf)2115 static void imx378_get_module_inf(struct imx378 *imx378,
2116 				  struct rkmodule_inf *inf)
2117 {
2118 	memset(inf, 0, sizeof(*inf));
2119 	strlcpy(inf->base.sensor, IMX378_NAME, sizeof(inf->base.sensor));
2120 	strlcpy(inf->base.module, imx378->module_name,
2121 		sizeof(inf->base.module));
2122 	strlcpy(inf->base.lens, imx378->len_name, sizeof(inf->base.lens));
2123 }
2124 
imx378_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)2125 static long imx378_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
2126 {
2127 	struct imx378 *imx378 = to_imx378(sd);
2128 	struct rkmodule_hdr_cfg *hdr;
2129 	long ret = 0;
2130 	u32 i, h, w;
2131 	u32 stream = 0;
2132 
2133 	switch (cmd) {
2134 	case PREISP_CMD_SET_HDRAE_EXP:
2135 		break;
2136 	case RKMODULE_GET_MODULE_INFO:
2137 		imx378_get_module_inf(imx378, (struct rkmodule_inf *)arg);
2138 		break;
2139 	case RKMODULE_GET_HDR_CFG:
2140 		hdr = (struct rkmodule_hdr_cfg *)arg;
2141 		hdr->esp.mode = HDR_NORMAL_VC;
2142 		hdr->hdr_mode = imx378->cur_mode->hdr_mode;
2143 		break;
2144 	case RKMODULE_SET_HDR_CFG:
2145 		hdr = (struct rkmodule_hdr_cfg *)arg;
2146 		w = imx378->cur_mode->width;
2147 		h = imx378->cur_mode->height;
2148 		for (i = 0; i < imx378->cfg_num; i++) {
2149 			if (w == supported_modes[i].width &&
2150 			    h == supported_modes[i].height &&
2151 			    supported_modes[i].hdr_mode == hdr->hdr_mode) {
2152 				imx378->cur_mode = &supported_modes[i];
2153 				break;
2154 			}
2155 		}
2156 		if (i == imx378->cfg_num) {
2157 			dev_err(&imx378->client->dev,
2158 				"not find hdr mode:%d %dx%d config\n",
2159 				hdr->hdr_mode, w, h);
2160 			ret = -EINVAL;
2161 		} else {
2162 			w = imx378->cur_mode->hts_def -
2163 			    imx378->cur_mode->width;
2164 			h = imx378->cur_mode->vts_def -
2165 			    imx378->cur_mode->height;
2166 			__v4l2_ctrl_modify_range(imx378->hblank, w, w, 1, w);
2167 			__v4l2_ctrl_modify_range(imx378->vblank, h,
2168 						 IMX378_VTS_MAX -
2169 						 imx378->cur_mode->height,
2170 						 1, h);
2171 
2172 			if (imx378->cur_mode->bus_fmt ==
2173 			    MEDIA_BUS_FMT_SRGGB10_1X10) {
2174 				imx378->cur_link_freq = 0;
2175 				imx378->cur_pixel_rate =
2176 				PIXEL_RATE_WITH_848M_10BIT;
2177 			} else if (imx378->cur_mode->bus_fmt ==
2178 				   MEDIA_BUS_FMT_SRGGB12_1X12) {
2179 				imx378->cur_link_freq = 0;
2180 				imx378->cur_pixel_rate =
2181 				PIXEL_RATE_WITH_848M_12BIT;
2182 			}
2183 
2184 			__v4l2_ctrl_s_ctrl_int64(imx378->pixel_rate,
2185 						 imx378->cur_pixel_rate);
2186 			__v4l2_ctrl_s_ctrl(imx378->link_freq,
2187 					   imx378->cur_link_freq);
2188 		}
2189 		break;
2190 	case RKMODULE_SET_QUICK_STREAM:
2191 
2192 		stream = *((u32 *)arg);
2193 
2194 		if (stream)
2195 			ret = imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2196 				IMX378_REG_VALUE_08BIT, IMX378_MODE_STREAMING);
2197 		else
2198 			ret = imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2199 				IMX378_REG_VALUE_08BIT, IMX378_MODE_SW_STANDBY);
2200 		break;
2201 	default:
2202 		ret = -ENOIOCTLCMD;
2203 		break;
2204 	}
2205 
2206 	return ret;
2207 }
2208 
2209 #ifdef CONFIG_COMPAT
imx378_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)2210 static long imx378_compat_ioctl32(struct v4l2_subdev *sd,
2211 				  unsigned int cmd, unsigned long arg)
2212 {
2213 	void __user *up = compat_ptr(arg);
2214 	struct rkmodule_inf *inf;
2215 	struct rkmodule_awb_cfg *cfg;
2216 	struct rkmodule_hdr_cfg *hdr;
2217 	struct preisp_hdrae_exp_s *hdrae;
2218 	long ret;
2219 	u32 stream = 0;
2220 
2221 	switch (cmd) {
2222 	case RKMODULE_GET_MODULE_INFO:
2223 		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
2224 		if (!inf) {
2225 			ret = -ENOMEM;
2226 			return ret;
2227 		}
2228 
2229 		ret = imx378_ioctl(sd, cmd, inf);
2230 		if (!ret)
2231 			ret = copy_to_user(up, inf, sizeof(*inf));
2232 		kfree(inf);
2233 		break;
2234 	case RKMODULE_AWB_CFG:
2235 		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
2236 		if (!cfg) {
2237 			ret = -ENOMEM;
2238 			return ret;
2239 		}
2240 
2241 		ret = copy_from_user(cfg, up, sizeof(*cfg));
2242 		if (!ret)
2243 			ret = imx378_ioctl(sd, cmd, cfg);
2244 		kfree(cfg);
2245 		break;
2246 	case RKMODULE_GET_HDR_CFG:
2247 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2248 		if (!hdr) {
2249 			ret = -ENOMEM;
2250 			return ret;
2251 		}
2252 
2253 		ret = imx378_ioctl(sd, cmd, hdr);
2254 		if (!ret)
2255 			ret = copy_to_user(up, hdr, sizeof(*hdr));
2256 		kfree(hdr);
2257 		break;
2258 	case RKMODULE_SET_HDR_CFG:
2259 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2260 		if (!hdr) {
2261 			ret = -ENOMEM;
2262 			return ret;
2263 		}
2264 
2265 		ret = copy_from_user(hdr, up, sizeof(*hdr));
2266 		if (!ret)
2267 			ret = imx378_ioctl(sd, cmd, hdr);
2268 		kfree(hdr);
2269 		break;
2270 	case PREISP_CMD_SET_HDRAE_EXP:
2271 		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
2272 		if (!hdrae) {
2273 			ret = -ENOMEM;
2274 			return ret;
2275 		}
2276 
2277 		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
2278 		if (!ret)
2279 			ret = imx378_ioctl(sd, cmd, hdrae);
2280 		kfree(hdrae);
2281 		break;
2282 	case RKMODULE_SET_QUICK_STREAM:
2283 		ret = copy_from_user(&stream, up, sizeof(u32));
2284 		if (!ret)
2285 			ret = imx378_ioctl(sd, cmd, &stream);
2286 		break;
2287 	default:
2288 		ret = -ENOIOCTLCMD;
2289 		break;
2290 	}
2291 
2292 	return ret;
2293 }
2294 #endif
2295 
imx378_set_flip(struct imx378 * imx378)2296 static int imx378_set_flip(struct imx378 *imx378)
2297 {
2298 	int ret = 0;
2299 	u32 val = 0;
2300 
2301 	ret = imx378_read_reg(imx378->client, IMX378_FLIP_MIRROR_REG,
2302 			      IMX378_REG_VALUE_08BIT, &val);
2303 	if (imx378->flip & IMX378_MIRROR_BIT_MASK)
2304 		val |= IMX378_MIRROR_BIT_MASK;
2305 	else
2306 		val &= ~IMX378_MIRROR_BIT_MASK;
2307 	if (imx378->flip & IMX378_FLIP_BIT_MASK)
2308 		val |= IMX378_FLIP_BIT_MASK;
2309 	else
2310 		val &= ~IMX378_FLIP_BIT_MASK;
2311 	ret |= imx378_write_reg(imx378->client, IMX378_FLIP_MIRROR_REG,
2312 				IMX378_REG_VALUE_08BIT, val);
2313 
2314 	return ret;
2315 }
2316 
__imx378_start_stream(struct imx378 * imx378)2317 static int __imx378_start_stream(struct imx378 *imx378)
2318 {
2319 	int ret;
2320 
2321 	ret = imx378_write_array(imx378->client, imx378->cur_mode->reg_list);
2322 	if (ret)
2323 		return ret;
2324 	imx378->cur_vts = imx378->cur_mode->vts_def;
2325 	/* In case these controls are set before streaming */
2326 	ret = __v4l2_ctrl_handler_setup(&imx378->ctrl_handler);
2327 	if (ret)
2328 		return ret;
2329 	if (imx378->has_init_exp && imx378->cur_mode->hdr_mode != NO_HDR) {
2330 		ret = imx378_ioctl(&imx378->subdev, PREISP_CMD_SET_HDRAE_EXP,
2331 			&imx378->init_hdrae_exp);
2332 		if (ret) {
2333 			dev_err(&imx378->client->dev,
2334 				"init exp fail in hdr mode\n");
2335 			return ret;
2336 		}
2337 	}
2338 
2339 	imx378_set_flip(imx378);
2340 
2341 	return imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2342 				IMX378_REG_VALUE_08BIT, IMX378_MODE_STREAMING);
2343 }
2344 
__imx378_stop_stream(struct imx378 * imx378)2345 static int __imx378_stop_stream(struct imx378 *imx378)
2346 {
2347 	return imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2348 				IMX378_REG_VALUE_08BIT, IMX378_MODE_SW_STANDBY);
2349 }
2350 
imx378_s_stream(struct v4l2_subdev * sd,int on)2351 static int imx378_s_stream(struct v4l2_subdev *sd, int on)
2352 {
2353 	struct imx378 *imx378 = to_imx378(sd);
2354 	struct i2c_client *client = imx378->client;
2355 	int ret = 0;
2356 
2357 	mutex_lock(&imx378->mutex);
2358 	on = !!on;
2359 	if (on == imx378->streaming)
2360 		goto unlock_and_return;
2361 
2362 	if (on) {
2363 		ret = pm_runtime_get_sync(&client->dev);
2364 		if (ret < 0) {
2365 			pm_runtime_put_noidle(&client->dev);
2366 			goto unlock_and_return;
2367 		}
2368 
2369 		ret = __imx378_start_stream(imx378);
2370 		if (ret) {
2371 			v4l2_err(sd, "start stream failed while write regs\n");
2372 			pm_runtime_put(&client->dev);
2373 			goto unlock_and_return;
2374 		}
2375 	} else {
2376 		__imx378_stop_stream(imx378);
2377 		pm_runtime_put(&client->dev);
2378 	}
2379 
2380 	imx378->streaming = on;
2381 
2382 unlock_and_return:
2383 	mutex_unlock(&imx378->mutex);
2384 
2385 	return ret;
2386 }
2387 
imx378_s_power(struct v4l2_subdev * sd,int on)2388 static int imx378_s_power(struct v4l2_subdev *sd, int on)
2389 {
2390 	struct imx378 *imx378 = to_imx378(sd);
2391 	struct i2c_client *client = imx378->client;
2392 	int ret = 0;
2393 
2394 	mutex_lock(&imx378->mutex);
2395 
2396 	/* If the power state is not modified - no work to do. */
2397 	if (imx378->power_on == !!on)
2398 		goto unlock_and_return;
2399 
2400 	if (on) {
2401 		ret = pm_runtime_get_sync(&client->dev);
2402 		if (ret < 0) {
2403 			pm_runtime_put_noidle(&client->dev);
2404 			goto unlock_and_return;
2405 		}
2406 
2407 		imx378->power_on = true;
2408 	} else {
2409 		pm_runtime_put(&client->dev);
2410 		imx378->power_on = false;
2411 	}
2412 
2413 unlock_and_return:
2414 	mutex_unlock(&imx378->mutex);
2415 
2416 	return ret;
2417 }
2418 
2419 /* Calculate the delay in us by clock rate and clock cycles */
imx378_cal_delay(u32 cycles)2420 static inline u32 imx378_cal_delay(u32 cycles)
2421 {
2422 	return DIV_ROUND_UP(cycles, IMX378_XVCLK_FREQ / 1000 / 1000);
2423 }
2424 
__imx378_power_on(struct imx378 * imx378)2425 static int __imx378_power_on(struct imx378 *imx378)
2426 {
2427 	int ret;
2428 	u32 delay_us;
2429 	struct device *dev = &imx378->client->dev;
2430 
2431 	ret = clk_set_rate(imx378->xvclk, IMX378_XVCLK_FREQ);
2432 	if (ret < 0) {
2433 		dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
2434 		return ret;
2435 	}
2436 	if (clk_get_rate(imx378->xvclk) != IMX378_XVCLK_FREQ)
2437 		dev_warn(dev, "xvclk mismatched, modes are based on 37.125MHz\n");
2438 	ret = clk_prepare_enable(imx378->xvclk);
2439 	if (ret < 0) {
2440 		dev_err(dev, "Failed to enable xvclk\n");
2441 		return ret;
2442 	}
2443 
2444 	if (!IS_ERR(imx378->reset_gpio))
2445 		gpiod_set_value_cansleep(imx378->reset_gpio, 0);
2446 
2447 	ret = regulator_bulk_enable(IMX378_NUM_SUPPLIES, imx378->supplies);
2448 	if (ret < 0) {
2449 		dev_err(dev, "Failed to enable regulators\n");
2450 		goto disable_clk;
2451 	}
2452 
2453 	if (!IS_ERR(imx378->reset_gpio))
2454 		gpiod_set_value_cansleep(imx378->reset_gpio, 1);
2455 
2456 	usleep_range(500, 1000);
2457 	if (!IS_ERR(imx378->pwdn_gpio))
2458 		gpiod_set_value_cansleep(imx378->pwdn_gpio, 1);
2459 
2460 	/* 8192 cycles prior to first SCCB transaction */
2461 	delay_us = imx378_cal_delay(8192);
2462 	usleep_range(delay_us, delay_us * 2);
2463 
2464 	return 0;
2465 
2466 disable_clk:
2467 	clk_disable_unprepare(imx378->xvclk);
2468 
2469 	return ret;
2470 }
2471 
__imx378_power_off(struct imx378 * imx378)2472 static void __imx378_power_off(struct imx378 *imx378)
2473 {
2474 	if (!IS_ERR(imx378->pwdn_gpio))
2475 		gpiod_set_value_cansleep(imx378->pwdn_gpio, 0);
2476 	clk_disable_unprepare(imx378->xvclk);
2477 	if (!IS_ERR(imx378->reset_gpio))
2478 		gpiod_set_value_cansleep(imx378->reset_gpio, 0);
2479 	regulator_bulk_disable(IMX378_NUM_SUPPLIES, imx378->supplies);
2480 }
2481 
imx378_runtime_resume(struct device * dev)2482 static int imx378_runtime_resume(struct device *dev)
2483 {
2484 	struct i2c_client *client = to_i2c_client(dev);
2485 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2486 	struct imx378 *imx378 = to_imx378(sd);
2487 
2488 	return __imx378_power_on(imx378);
2489 }
2490 
imx378_runtime_suspend(struct device * dev)2491 static int imx378_runtime_suspend(struct device *dev)
2492 {
2493 	struct i2c_client *client = to_i2c_client(dev);
2494 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2495 	struct imx378 *imx378 = to_imx378(sd);
2496 
2497 	__imx378_power_off(imx378);
2498 
2499 	return 0;
2500 }
2501 
2502 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
imx378_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2503 static int imx378_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2504 {
2505 	struct imx378 *imx378 = to_imx378(sd);
2506 	struct v4l2_mbus_framefmt *try_fmt =
2507 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
2508 	const struct imx378_mode *def_mode = &supported_modes[0];
2509 
2510 	mutex_lock(&imx378->mutex);
2511 	/* Initialize try_fmt */
2512 	try_fmt->width = def_mode->width;
2513 	try_fmt->height = def_mode->height;
2514 	try_fmt->code = def_mode->bus_fmt;
2515 	try_fmt->field = V4L2_FIELD_NONE;
2516 
2517 	mutex_unlock(&imx378->mutex);
2518 	/* No crop or compose */
2519 
2520 	return 0;
2521 }
2522 #endif
2523 
imx378_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2524 static int imx378_enum_frame_interval(struct v4l2_subdev *sd,
2525 				      struct v4l2_subdev_pad_config *cfg,
2526 				struct v4l2_subdev_frame_interval_enum *fie)
2527 {
2528 	struct imx378 *imx378 = to_imx378(sd);
2529 
2530 	if (fie->index >= imx378->cfg_num)
2531 		return -EINVAL;
2532 
2533 	fie->code = supported_modes[fie->index].bus_fmt;
2534 	fie->width = supported_modes[fie->index].width;
2535 	fie->height = supported_modes[fie->index].height;
2536 	fie->interval = supported_modes[fie->index].max_fps;
2537 	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
2538 	return 0;
2539 }
2540 
2541 static const struct dev_pm_ops imx378_pm_ops = {
2542 	SET_RUNTIME_PM_OPS(imx378_runtime_suspend,
2543 			   imx378_runtime_resume, NULL)
2544 };
2545 
2546 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2547 static const struct v4l2_subdev_internal_ops imx378_internal_ops = {
2548 	.open = imx378_open,
2549 };
2550 #endif
2551 
2552 static const struct v4l2_subdev_core_ops imx378_core_ops = {
2553 	.s_power = imx378_s_power,
2554 	.ioctl = imx378_ioctl,
2555 #ifdef CONFIG_COMPAT
2556 	.compat_ioctl32 = imx378_compat_ioctl32,
2557 #endif
2558 };
2559 
2560 static const struct v4l2_subdev_video_ops imx378_video_ops = {
2561 	.s_stream = imx378_s_stream,
2562 	.g_frame_interval = imx378_g_frame_interval,
2563 };
2564 
2565 static const struct v4l2_subdev_pad_ops imx378_pad_ops = {
2566 	.enum_mbus_code = imx378_enum_mbus_code,
2567 	.enum_frame_size = imx378_enum_frame_sizes,
2568 	.enum_frame_interval = imx378_enum_frame_interval,
2569 	.get_fmt = imx378_get_fmt,
2570 	.set_fmt = imx378_set_fmt,
2571 	.get_mbus_config = imx378_g_mbus_config,
2572 };
2573 
2574 static const struct v4l2_subdev_ops imx378_subdev_ops = {
2575 	.core	= &imx378_core_ops,
2576 	.video	= &imx378_video_ops,
2577 	.pad	= &imx378_pad_ops,
2578 };
2579 
imx378_set_ctrl(struct v4l2_ctrl * ctrl)2580 static int imx378_set_ctrl(struct v4l2_ctrl *ctrl)
2581 {
2582 	struct imx378 *imx378 = container_of(ctrl->handler,
2583 					     struct imx378, ctrl_handler);
2584 	struct i2c_client *client = imx378->client;
2585 	s64 max;
2586 	int ret = 0;
2587 	u32 again = 0;
2588 	u32 dgain = 0;
2589 
2590 	/* Propagate change of current control to all related controls */
2591 	switch (ctrl->id) {
2592 	case V4L2_CID_VBLANK:
2593 		/* Update max exposure while meeting expected vblanking */
2594 		max = imx378->cur_mode->height + ctrl->val - 4;
2595 		__v4l2_ctrl_modify_range(imx378->exposure,
2596 					 imx378->exposure->minimum, max,
2597 					 imx378->exposure->step,
2598 					 imx378->exposure->default_value);
2599 		break;
2600 	}
2601 
2602 	if (!pm_runtime_get_if_in_use(&client->dev))
2603 		return 0;
2604 
2605 	switch (ctrl->id) {
2606 	case V4L2_CID_EXPOSURE:
2607 		/* 4 least significant bits of expsoure are fractional part */
2608 		ret = imx378_write_reg(imx378->client,
2609 				       IMX378_REG_EXPOSURE_H,
2610 				       IMX378_REG_VALUE_08BIT,
2611 				       IMX378_FETCH_EXP_H(ctrl->val));
2612 		ret |= imx378_write_reg(imx378->client,
2613 					IMX378_REG_EXPOSURE_L,
2614 					IMX378_REG_VALUE_08BIT,
2615 					IMX378_FETCH_EXP_L(ctrl->val));
2616 		break;
2617 	case V4L2_CID_ANALOGUE_GAIN:
2618 		again = ctrl->val > 978 ? 978 : ctrl->val;
2619 		dgain = ctrl->val > 978 ? ctrl->val - 978 : 256;
2620 		ret = imx378_write_reg(imx378->client, IMX378_REG_GAIN_H,
2621 				       IMX378_REG_VALUE_08BIT,
2622 				       IMX378_FETCH_AGAIN_H(again));
2623 		ret |= imx378_write_reg(imx378->client, IMX378_REG_GAIN_L,
2624 					IMX378_REG_VALUE_08BIT,
2625 					IMX378_FETCH_AGAIN_L(again));
2626 		ret |= imx378_write_reg(imx378->client, IMX378_REG_DGAIN,
2627 					IMX378_REG_VALUE_08BIT,
2628 					IMX378_DGAIN_MODE);
2629 		if (IMX378_DGAIN_MODE && dgain > 0) {
2630 			ret |= imx378_write_reg(imx378->client,
2631 						IMX378_REG_DGAINGR_H,
2632 						IMX378_REG_VALUE_08BIT,
2633 						IMX378_FETCH_DGAIN_H(dgain));
2634 			ret |= imx378_write_reg(imx378->client,
2635 						IMX378_REG_DGAINGR_L,
2636 						IMX378_REG_VALUE_08BIT,
2637 						IMX378_FETCH_DGAIN_L(dgain));
2638 		} else if (dgain > 0) {
2639 			ret |= imx378_write_reg(imx378->client,
2640 						IMX378_REG_DGAINR_H,
2641 						IMX378_REG_VALUE_08BIT,
2642 						IMX378_FETCH_DGAIN_H(dgain));
2643 			ret |= imx378_write_reg(imx378->client,
2644 						IMX378_REG_DGAINR_L,
2645 						IMX378_REG_VALUE_08BIT,
2646 						IMX378_FETCH_DGAIN_L(dgain));
2647 			ret |= imx378_write_reg(imx378->client,
2648 						IMX378_REG_DGAINB_H,
2649 						IMX378_REG_VALUE_08BIT,
2650 						IMX378_FETCH_DGAIN_H(dgain));
2651 			ret |= imx378_write_reg(imx378->client,
2652 						IMX378_REG_DGAINB_L,
2653 						IMX378_REG_VALUE_08BIT,
2654 						IMX378_FETCH_DGAIN_L(dgain));
2655 			ret |= imx378_write_reg(imx378->client,
2656 						IMX378_REG_DGAINGB_H,
2657 						IMX378_REG_VALUE_08BIT,
2658 						IMX378_FETCH_DGAIN_H(dgain));
2659 			ret |= imx378_write_reg(imx378->client,
2660 						IMX378_REG_DGAINGB_L,
2661 						IMX378_REG_VALUE_08BIT,
2662 						IMX378_FETCH_DGAIN_L(dgain));
2663 			ret |= imx378_write_reg(imx378->client,
2664 						IMX378_REG_GAIN_GLOBAL_H,
2665 						IMX378_REG_VALUE_08BIT,
2666 						IMX378_FETCH_DGAIN_H(dgain));
2667 			ret |= imx378_write_reg(imx378->client,
2668 						IMX378_REG_GAIN_GLOBAL_L,
2669 						IMX378_REG_VALUE_08BIT,
2670 						IMX378_FETCH_DGAIN_L(dgain));
2671 		}
2672 		break;
2673 	case V4L2_CID_VBLANK:
2674 		ret = imx378_write_reg(imx378->client,
2675 				       IMX378_REG_VTS_H,
2676 				       IMX378_REG_VALUE_08BIT,
2677 				       (ctrl->val + imx378->cur_mode->height)
2678 				       >> 8);
2679 		ret |= imx378_write_reg(imx378->client,
2680 					IMX378_REG_VTS_L,
2681 					IMX378_REG_VALUE_08BIT,
2682 					(ctrl->val + imx378->cur_mode->height)
2683 					& 0xff);
2684 		imx378->cur_vts = ctrl->val + imx378->cur_mode->height;
2685 		break;
2686 	case V4L2_CID_HFLIP:
2687 		if (ctrl->val)
2688 			imx378->flip |= IMX378_MIRROR_BIT_MASK;
2689 		else
2690 			imx378->flip &= ~IMX378_MIRROR_BIT_MASK;
2691 		break;
2692 	case V4L2_CID_VFLIP:
2693 		if (ctrl->val)
2694 			imx378->flip |= IMX378_FLIP_BIT_MASK;
2695 		else
2696 			imx378->flip &= ~IMX378_FLIP_BIT_MASK;
2697 		break;
2698 	case V4L2_CID_TEST_PATTERN:
2699 		ret = imx378_enable_test_pattern(imx378, ctrl->val);
2700 		break;
2701 	default:
2702 		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
2703 			 __func__, ctrl->id, ctrl->val);
2704 		break;
2705 	}
2706 
2707 	pm_runtime_put(&client->dev);
2708 
2709 	return ret;
2710 }
2711 
2712 static const struct v4l2_ctrl_ops imx378_ctrl_ops = {
2713 	.s_ctrl = imx378_set_ctrl,
2714 };
2715 
imx378_initialize_controls(struct imx378 * imx378)2716 static int imx378_initialize_controls(struct imx378 *imx378)
2717 {
2718 	const struct imx378_mode *mode;
2719 	struct v4l2_ctrl_handler *handler;
2720 	s64 exposure_max, vblank_def;
2721 	u32 h_blank;
2722 	int ret;
2723 
2724 	handler = &imx378->ctrl_handler;
2725 	mode = imx378->cur_mode;
2726 	ret = v4l2_ctrl_handler_init(handler, 9);
2727 	if (ret)
2728 		return ret;
2729 	handler->lock = &imx378->mutex;
2730 
2731 	imx378->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
2732 						   V4L2_CID_LINK_FREQ,
2733 						   0, 0, link_freq_menu_items);
2734 
2735 	if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
2736 		imx378->cur_link_freq = 0;
2737 		imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_10BIT;
2738 	} else if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB12_1X12) {
2739 		imx378->cur_link_freq = 0;
2740 		imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_12BIT;
2741 	}
2742 
2743 	imx378->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2744 					       V4L2_CID_PIXEL_RATE,
2745 					       0, PIXEL_RATE_WITH_848M_10BIT,
2746 					       1, imx378->cur_pixel_rate);
2747 	v4l2_ctrl_s_ctrl(imx378->link_freq,
2748 			   imx378->cur_link_freq);
2749 
2750 	h_blank = mode->hts_def - mode->width;
2751 	imx378->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
2752 					   h_blank, h_blank, 1, h_blank);
2753 	if (imx378->hblank)
2754 		imx378->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2755 
2756 	vblank_def = mode->vts_def - mode->height;
2757 	imx378->vblank = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2758 					   V4L2_CID_VBLANK, vblank_def,
2759 					   IMX378_VTS_MAX - mode->height,
2760 					   1, vblank_def);
2761 	imx378->cur_vts = mode->vts_def;
2762 	exposure_max = mode->vts_def - 4;
2763 	imx378->exposure = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2764 					     V4L2_CID_EXPOSURE,
2765 					     IMX378_EXPOSURE_MIN,
2766 					     exposure_max,
2767 					     IMX378_EXPOSURE_STEP,
2768 					     mode->exp_def);
2769 	imx378->anal_gain = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2770 					      V4L2_CID_ANALOGUE_GAIN,
2771 					      IMX378_GAIN_MIN,
2772 					      IMX378_GAIN_MAX,
2773 					      IMX378_GAIN_STEP,
2774 					      IMX378_GAIN_DEFAULT);
2775 	imx378->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
2776 							    &imx378_ctrl_ops,
2777 				V4L2_CID_TEST_PATTERN,
2778 				ARRAY_SIZE(imx378_test_pattern_menu) - 1,
2779 				0, 0, imx378_test_pattern_menu);
2780 
2781 	imx378->h_flip = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2782 				V4L2_CID_HFLIP, 0, 1, 1, 0);
2783 
2784 	imx378->v_flip = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2785 				V4L2_CID_VFLIP, 0, 1, 1, 0);
2786 	imx378->flip = 0;
2787 
2788 	if (handler->error) {
2789 		ret = handler->error;
2790 		dev_err(&imx378->client->dev,
2791 			"Failed to init controls(  %d  )\n", ret);
2792 		goto err_free_handler;
2793 	}
2794 
2795 	imx378->subdev.ctrl_handler = handler;
2796 	imx378->has_init_exp = false;
2797 	return 0;
2798 
2799 err_free_handler:
2800 	v4l2_ctrl_handler_free(handler);
2801 
2802 	return ret;
2803 }
2804 
imx378_check_sensor_id(struct imx378 * imx378,struct i2c_client * client)2805 static int imx378_check_sensor_id(struct imx378 *imx378,
2806 				  struct i2c_client *client)
2807 {
2808 	struct device *dev = &imx378->client->dev;
2809 	u16 id = 0;
2810 	u32 reg_H = 0;
2811 	u32 reg_L = 0;
2812 	int ret;
2813 
2814 	ret = imx378_read_reg(client, IMX378_REG_CHIP_ID_H,
2815 			      IMX378_REG_VALUE_08BIT, &reg_H);
2816 	ret |= imx378_read_reg(client, IMX378_REG_CHIP_ID_L,
2817 			       IMX378_REG_VALUE_08BIT, &reg_L);
2818 	id = ((reg_H << 8) & 0xff00) | (reg_L & 0xff);
2819 	if (!(reg_H == (CHIP_ID >> 8) || reg_L == (CHIP_ID & 0xff))) {
2820 		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
2821 		return -ENODEV;
2822 	}
2823 	dev_info(dev, "detected imx378 %04x sensor\n", id);
2824 	return 0;
2825 }
2826 
imx378_configure_regulators(struct imx378 * imx378)2827 static int imx378_configure_regulators(struct imx378 *imx378)
2828 {
2829 	unsigned int i;
2830 
2831 	for (i = 0; i < IMX378_NUM_SUPPLIES; i++)
2832 		imx378->supplies[i].supply = imx378_supply_names[i];
2833 
2834 	return devm_regulator_bulk_get(&imx378->client->dev,
2835 				       IMX378_NUM_SUPPLIES,
2836 				       imx378->supplies);
2837 }
2838 
imx378_probe(struct i2c_client * client,const struct i2c_device_id * id)2839 static int imx378_probe(struct i2c_client *client,
2840 			const struct i2c_device_id *id)
2841 {
2842 	struct device *dev = &client->dev;
2843 	struct device_node *node = dev->of_node;
2844 	struct imx378 *imx378;
2845 	struct v4l2_subdev *sd;
2846 	char facing[2];
2847 	int ret;
2848 	u32 i, hdr_mode = 0;
2849 
2850 	dev_info(dev, "driver version: %02x.%02x.%02x",
2851 		 DRIVER_VERSION >> 16,
2852 		 (DRIVER_VERSION & 0xff00) >> 8,
2853 		 DRIVER_VERSION & 0x00ff);
2854 
2855 	imx378 = devm_kzalloc(dev, sizeof(*imx378), GFP_KERNEL);
2856 	if (!imx378)
2857 		return -ENOMEM;
2858 
2859 	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
2860 				   &imx378->module_index);
2861 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
2862 				       &imx378->module_facing);
2863 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
2864 				       &imx378->module_name);
2865 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
2866 				       &imx378->len_name);
2867 	if (ret) {
2868 		dev_err(dev, "could not get module information!\n");
2869 		return -EINVAL;
2870 	}
2871 
2872 	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
2873 	if (ret) {
2874 		hdr_mode = NO_HDR;
2875 		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
2876 	}
2877 
2878 	imx378->client = client;
2879 	imx378->cfg_num = ARRAY_SIZE(supported_modes);
2880 	for (i = 0; i < imx378->cfg_num; i++) {
2881 		if (hdr_mode == supported_modes[i].hdr_mode) {
2882 			imx378->cur_mode = &supported_modes[i];
2883 			break;
2884 		}
2885 	}
2886 
2887 	if (i == imx378->cfg_num)
2888 		imx378->cur_mode = &supported_modes[0];
2889 
2890 	imx378->xvclk = devm_clk_get(dev, "xvclk");
2891 	if (IS_ERR(imx378->xvclk)) {
2892 		dev_err(dev, "Failed to get xvclk\n");
2893 		return -EINVAL;
2894 	}
2895 
2896 	imx378->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2897 	if (IS_ERR(imx378->reset_gpio))
2898 		dev_warn(dev, "Failed to get reset-gpios\n");
2899 
2900 	imx378->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2901 	if (IS_ERR(imx378->pwdn_gpio))
2902 		dev_warn(dev, "Failed to get pwdn-gpios\n");
2903 
2904 	ret = imx378_configure_regulators(imx378);
2905 	if (ret) {
2906 		dev_err(dev, "Failed to get power regulators\n");
2907 		return ret;
2908 	}
2909 
2910 	mutex_init(&imx378->mutex);
2911 
2912 	sd = &imx378->subdev;
2913 	v4l2_i2c_subdev_init(sd, client, &imx378_subdev_ops);
2914 
2915 	ret = imx378_initialize_controls(imx378);
2916 	if (ret)
2917 		goto err_destroy_mutex;
2918 
2919 	ret = __imx378_power_on(imx378);
2920 	if (ret)
2921 		goto err_free_handler;
2922 
2923 	ret = imx378_check_sensor_id(imx378, client);
2924 	if (ret)
2925 		goto err_power_off;
2926 
2927 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2928 	sd->internal_ops = &imx378_internal_ops;
2929 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2930 #endif
2931 #if defined(CONFIG_MEDIA_CONTROLLER)
2932 	imx378->pad.flags = MEDIA_PAD_FL_SOURCE;
2933 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
2934 	ret = media_entity_pads_init(&sd->entity, 1, &imx378->pad);
2935 	if (ret < 0)
2936 		goto err_power_off;
2937 #endif
2938 
2939 	memset(facing, 0, sizeof(facing));
2940 	if (strcmp(imx378->module_facing, "back") == 0)
2941 		facing[0] = 'b';
2942 	else
2943 		facing[0] = 'f';
2944 
2945 	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
2946 		 imx378->module_index, facing,
2947 		 IMX378_NAME, dev_name(sd->dev));
2948 	ret = v4l2_async_register_subdev_sensor_common(sd);
2949 	if (ret) {
2950 		dev_err(dev, "v4l2 async register subdev failed\n");
2951 		goto err_clean_entity;
2952 	}
2953 
2954 	pm_runtime_set_active(dev);
2955 	pm_runtime_enable(dev);
2956 	pm_runtime_idle(dev);
2957 
2958 	return 0;
2959 
2960 err_clean_entity:
2961 #if defined(CONFIG_MEDIA_CONTROLLER)
2962 	media_entity_cleanup(&sd->entity);
2963 #endif
2964 err_power_off:
2965 	__imx378_power_off(imx378);
2966 err_free_handler:
2967 	v4l2_ctrl_handler_free(&imx378->ctrl_handler);
2968 err_destroy_mutex:
2969 	mutex_destroy(&imx378->mutex);
2970 
2971 	return ret;
2972 }
2973 
imx378_remove(struct i2c_client * client)2974 static int imx378_remove(struct i2c_client *client)
2975 {
2976 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2977 	struct imx378 *imx378 = to_imx378(sd);
2978 
2979 	v4l2_async_unregister_subdev(sd);
2980 #if defined(CONFIG_MEDIA_CONTROLLER)
2981 	media_entity_cleanup(&sd->entity);
2982 #endif
2983 	v4l2_ctrl_handler_free(&imx378->ctrl_handler);
2984 	mutex_destroy(&imx378->mutex);
2985 
2986 	pm_runtime_disable(&client->dev);
2987 	if (!pm_runtime_status_suspended(&client->dev))
2988 		__imx378_power_off(imx378);
2989 	pm_runtime_set_suspended(&client->dev);
2990 
2991 	return 0;
2992 }
2993 
2994 #if IS_ENABLED(CONFIG_OF)
2995 static const struct of_device_id imx378_of_match[] = {
2996 	{ .compatible = "sony,imx378" },
2997 	{},
2998 };
2999 MODULE_DEVICE_TABLE(of, imx378_of_match);
3000 #endif
3001 
3002 static const struct i2c_device_id imx378_match_id[] = {
3003 	{ "sony,imx378", 0 },
3004 	{ },
3005 };
3006 
3007 static struct i2c_driver imx378_i2c_driver = {
3008 	.driver = {
3009 		.name = IMX378_NAME,
3010 		.pm = &imx378_pm_ops,
3011 		.of_match_table = of_match_ptr(imx378_of_match),
3012 	},
3013 	.probe		= &imx378_probe,
3014 	.remove		= &imx378_remove,
3015 	.id_table	= imx378_match_id,
3016 };
3017 
sensor_mod_init(void)3018 static int __init sensor_mod_init(void)
3019 {
3020 	return i2c_add_driver(&imx378_i2c_driver);
3021 }
3022 
sensor_mod_exit(void)3023 static void __exit sensor_mod_exit(void)
3024 {
3025 	i2c_del_driver(&imx378_i2c_driver);
3026 }
3027 
3028 device_initcall_sync(sensor_mod_init);
3029 module_exit(sensor_mod_exit);
3030 
3031 MODULE_DESCRIPTION("Sony imx378 sensor driver");
3032 MODULE_LICENSE("GPL v2");
3033