xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/imx464.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * IMX464 driver
4  *
5  * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd.
6  *
7  * V0.0X01.0X00 first version
8  * V0.0X01.0X01 add conversion gain control
9  * V0.0X01.0X02 add debug interface for conversion gain control
10  * V0.0X01.0X03 support enum sensor fmt
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/device.h>
15 #include <linux/delay.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/i2c.h>
18 #include <linux/module.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/sysfs.h>
22 #include <linux/slab.h>
23 #include <linux/version.h>
24 #include <linux/rk-camera-module.h>
25 #include <media/media-entity.h>
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-subdev.h>
29 #include <media/v4l2-fwnode.h>
30 #include <media/v4l2-mediabus.h>
31 #include <linux/pinctrl/consumer.h>
32 #include <linux/rk-preisp.h>
33 #include <linux/of_graph.h>
34 
35 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x03)
36 
37 #ifndef V4L2_CID_DIGITAL_GAIN
38 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
39 #endif
40 
41 #define MIPI_FREQ_360M			360000000
42 #define MIPI_FREQ_445M			445600000
43 #define MIPI_FREQ_594M			594000000
44 
45 #define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
46 
47 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
48 #define IMX464_10BIT_HDR2_PIXEL_RATE	(MIPI_FREQ_594M * 2 / 10 * 4)
49 #define IMX464_XVCLK_FREQ_37M		37125000
50 #define IMX464_XVCLK_FREQ_24M		24000000
51 
52 #define CHIP_ID				0x06
53 #define IMX464_REG_CHIP_ID		0x3057
54 
55 #define IMX464_REG_CTRL_MODE		0x3000
56 #define IMX464_MODE_SW_STANDBY		BIT(0)
57 #define IMX464_MODE_STREAMING		0x0
58 
59 #define IMX464_REG_MARSTER_MODE		0x3002
60 #define IMX464_MODE_STOP		BIT(0)
61 #define IMX464_MODE_START		0x0
62 
63 #define IMX464_GAIN_SWITCH_REG		0x3019
64 
65 #define IMX464_LF_GAIN_REG_H		0x30E9
66 #define IMX464_LF_GAIN_REG_L		0x30E8
67 
68 #define IMX464_SF1_GAIN_REG_H		0x30EB
69 #define IMX464_SF1_GAIN_REG_L		0x30EA
70 
71 #define IMX464_SF2_GAIN_REG_H		0x30ED
72 #define IMX464_SF2_GAIN_REG_L		0x30EC
73 
74 #define IMX464_LF_EXPO_REG_H		0x305A
75 #define IMX464_LF_EXPO_REG_M		0x3059
76 #define IMX464_LF_EXPO_REG_L		0x3058
77 
78 #define IMX464_SF1_EXPO_REG_H		0x305E
79 #define IMX464_SF1_EXPO_REG_M		0x305D
80 #define IMX464_SF1_EXPO_REG_L		0x305C
81 
82 #define IMX464_SF2_EXPO_REG_H		0x3062
83 #define IMX464_SF2_EXPO_REG_M		0x3061
84 #define IMX464_SF2_EXPO_REG_L		0x3060
85 #define IMX464_RHS1_DEFAULT		0x06d
86 #define IMX464_RHS1_X3_DEFAULT		0x0a3
87 
88 #define IMX464_RHS1_REG_H		0x306a
89 #define IMX464_RHS1_REG_M		0x3069
90 #define IMX464_RHS1_REG_L		0x3068
91 
92 #define IMX464_RHS2_REG_H		0x306E
93 #define IMX464_RHS2_REG_M		0x306D
94 #define IMX464_RHS2_REG_L		0x306C
95 #define IMX464_RHS2_X3_DEFAULT		0x0ce
96 
97 
98 #define	IMX464_EXPOSURE_MIN		2
99 #define	IMX464_EXPOSURE_STEP		1
100 #define IMX464_VTS_MAX			0x7fff
101 
102 #define IMX464_GAIN_MIN			0x00
103 #define IMX464_GAIN_MAX			0xee
104 #define IMX464_GAIN_STEP		1
105 #define IMX464_GAIN_DEFAULT		0x00
106 
107 #define IMX464_FETCH_GAIN_H(VAL)	(((VAL) >> 8) & 0x07)
108 #define IMX464_FETCH_GAIN_L(VAL)	((VAL) & 0xFF)
109 
110 #define IMX464_FETCH_EXP_H(VAL)		(((VAL) >> 16) & 0x0F)
111 #define IMX464_FETCH_EXP_M(VAL)		(((VAL) >> 8) & 0xFF)
112 #define IMX464_FETCH_EXP_L(VAL)		((VAL) & 0xFF)
113 
114 #define IMX464_FETCH_RHS1_H(VAL)	(((VAL) >> 16) & 0x0F)
115 #define IMX464_FETCH_RHS1_M(VAL)	(((VAL) >> 8) & 0xFF)
116 #define IMX464_FETCH_RHS1_L(VAL)	((VAL) & 0xFF)
117 
118 #define IMX464_FETCH_VTS_H(VAL)		(((VAL) >> 16) & 0x0F)
119 #define IMX464_FETCH_VTS_M(VAL)		(((VAL) >> 8) & 0xFF)
120 #define IMX464_FETCH_VTS_L(VAL)		((VAL) & 0xFF)
121 
122 #define IMX464_GROUP_HOLD_REG		0x3001
123 #define IMX464_GROUP_HOLD_START		0x01
124 #define IMX464_GROUP_HOLD_END		0x00
125 
126 #define IMX464_VTS_REG_L		0x3030
127 #define IMX464_VTS_REG_M		0x3031
128 #define IMX464_VTS_REG_H		0x3032
129 
130 #define REG_NULL			0xFFFF
131 
132 #define IMX464_REG_VALUE_08BIT		1
133 #define IMX464_REG_VALUE_16BIT		2
134 #define IMX464_REG_VALUE_24BIT		3
135 
136 #define IMX464_BITS_PER_SAMPLE		10
137 
138 #define IMX464_VREVERSE_REG	0x304f
139 #define IMX464_HREVERSE_REG	0x304e
140 
141 #define BRL				1558
142 #define RHS1_MAX			((BRL * 2 - 1) / 4 * 4 + 1) // <3*BRL=2*1558 && 6n+1
143 #define SHR1_MIN			9u
144 
145 /* Readout timing setting of SEF1(DOL3): RHS1 < 3 * BRL and should be 6n + 1 */
146 #define RHS1_MAX_X3			((BRL * 3 - 1) / 6 * 6 + 1)
147 #define SHR1_MIN_X3			13u
148 
149 #define USED_SYS_DEBUG
150 
151 #define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
152 #define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
153 
154 #define IMX464_NAME			"imx464"
155 
156 static const char * const IMX464_supply_names[] = {
157 	"avdd",		/* Analog power */
158 	"dovdd",	/* Digital I/O power */
159 	"dvdd",		/* Digital core power */
160 };
161 
162 #define IMX464_NUM_SUPPLIES ARRAY_SIZE(IMX464_supply_names)
163 
164 struct regval {
165 	u16 addr;
166 	u8 val;
167 };
168 
169 struct IMX464_mode {
170 	u32 bus_fmt;
171 	u32 width;
172 	u32 height;
173 	struct v4l2_fract max_fps;
174 	u32 hts_def;
175 	u32 vts_def;
176 	u32 exp_def;
177 	u32 mipi_freq_idx;
178 	u32 mclk;
179 	u32 bpp;
180 	const struct regval *reg_list;
181 	u32 hdr_mode;
182 	u32 vc[PAD_MAX];
183 };
184 
185 struct IMX464 {
186 	struct i2c_client	*client;
187 	struct clk		*xvclk;
188 	struct gpio_desc	*reset_gpio;
189 	struct gpio_desc	*pwdn_gpio;
190 	struct regulator_bulk_data supplies[IMX464_NUM_SUPPLIES];
191 
192 	struct pinctrl		*pinctrl;
193 	struct pinctrl_state	*pins_default;
194 	struct pinctrl_state	*pins_sleep;
195 
196 	struct v4l2_subdev	subdev;
197 	struct media_pad	pad;
198 	struct v4l2_ctrl_handler ctrl_handler;
199 	struct v4l2_ctrl	*exposure;
200 	struct v4l2_ctrl	*anal_a_gain;
201 	struct v4l2_ctrl	*digi_gain;
202 	struct v4l2_ctrl	*hblank;
203 	struct v4l2_ctrl	*vblank;
204 	struct v4l2_ctrl	*pixel_rate;
205 	struct v4l2_ctrl	*link_freq;
206 	struct mutex		mutex;
207 	struct v4l2_fwnode_endpoint bus_cfg;
208 	bool			streaming;
209 	bool			power_on;
210 	bool			has_init_exp;
211 	const struct IMX464_mode *support_modes;
212 	const struct IMX464_mode *cur_mode;
213 	u32			module_index;
214 	u32			cfg_num;
215 	u32			cur_vts;
216 	u32			cur_mclk;
217 	const char		*module_facing;
218 	const char		*module_name;
219 	const char		*len_name;
220 	enum rkmodule_sync_mode	sync_mode;
221 	struct preisp_hdrae_exp_s init_hdrae_exp;
222 	bool			isHCG;
223 };
224 
225 #define to_IMX464(sd) container_of(sd, struct IMX464, subdev)
226 
227 /*
228  * Xclk 37.125Mhz
229  */
230 static const struct regval IMX464_global_regs[] = {
231 	{REG_NULL, 0x00},
232 };
233 
234 static __maybe_unused const struct regval IMX464_linear_10bit_2688x1520_2lane_37m_regs[] = {
235 	{0x3000, 0x01},
236 	{0x3002, 0x01},
237 	{0x300C, 0x5B},
238 	{0x300D, 0x40},
239 	{0x3034, 0xDC},
240 	{0x3035, 0x05},
241 	{0x3050, 0x00},
242 	{0x3058, 0x83},
243 	{0x3059, 0x04},
244 	{0x30BE, 0x5E},
245 	{0x30E8, 0x14},
246 	{0x3110, 0x02},
247 	{0x314C, 0xC0},
248 	{0x315A, 0x06},
249 	{0x316A, 0x7E},
250 	{0x319D, 0x00},
251 	{0x319E, 0x02},
252 	{0x31A1, 0x00},
253 	{0x3288, 0x22},
254 	{0x328A, 0x02},
255 	{0x328C, 0xA2},
256 	{0x328E, 0x22},
257 	{0x3415, 0x27},
258 	{0x3418, 0x27},
259 	{0x3428, 0xFE},
260 	{0x349E, 0x6A},
261 	{0x34A2, 0x9A},
262 	{0x34A4, 0x8A},
263 	{0x34A6, 0x8E},
264 	{0x34AA, 0xD8},
265 	{0x35BC, 0x00},
266 	{0x35BE, 0xFF},
267 	{0x35CC, 0x1B},
268 	{0x35CD, 0x00},
269 	{0x35CE, 0x2A},
270 	{0x35CF, 0x00},
271 	{0x35DC, 0x07},
272 	{0x35DE, 0x1A},
273 	{0x35DF, 0x00},
274 	{0x35E4, 0x2B},
275 	{0x35E5, 0x00},
276 	{0x35E6, 0x07},
277 	{0x35E7, 0x01},
278 	{0x3648, 0x01},
279 	{0x3678, 0x01},
280 	{0x367C, 0x69},
281 	{0x367E, 0x69},
282 	{0x3680, 0x69},
283 	{0x3682, 0x69},
284 	{0x3718, 0x1C},
285 	{0x371D, 0x05},
286 	{0x375D, 0x11},
287 	{0x375E, 0x43},
288 	{0x375F, 0x76},
289 	{0x3760, 0x07},
290 	{0x3768, 0x1B},
291 	{0x3769, 0x1B},
292 	{0x376A, 0x1A},
293 	{0x376B, 0x19},
294 	{0x376C, 0x17},
295 	{0x376D, 0x0F},
296 	{0x376E, 0x0B},
297 	{0x376F, 0x0B},
298 	{0x3770, 0x0B},
299 	{0x3776, 0x89},
300 	{0x3777, 0x00},
301 	{0x3778, 0xCA},
302 	{0x3779, 0x00},
303 	{0x377A, 0x45},
304 	{0x377B, 0x01},
305 	{0x377C, 0x56},
306 	{0x377D, 0x02},
307 	{0x377E, 0xFE},
308 	{0x377F, 0x03},
309 	{0x3780, 0xFE},
310 	{0x3781, 0x05},
311 	{0x3782, 0xFE},
312 	{0x3783, 0x06},
313 	{0x3784, 0x7F},
314 	{0x3788, 0x1F},
315 	{0x378A, 0xCA},
316 	{0x378B, 0x00},
317 	{0x378C, 0x45},
318 	{0x378D, 0x01},
319 	{0x378E, 0x56},
320 	{0x378F, 0x02},
321 	{0x3790, 0xFE},
322 	{0x3791, 0x03},
323 	{0x3792, 0xFE},
324 	{0x3793, 0x05},
325 	{0x3794, 0xFE},
326 	{0x3795, 0x06},
327 	{0x3796, 0x7F},
328 	{0x3798, 0xBF},
329 	{0x3A01, 0x01},
330 	{0x3A18, 0x7F},
331 	{0x3A1A, 0x37},
332 	{0x3A1C, 0x37},
333 	{0x3A1E, 0xF7},
334 	{0x3A1F, 0x00},
335 	{0x3A20, 0x3F},
336 	{0x3A22, 0x6F},
337 	{0x3A24, 0x3F},
338 	{0x3A26, 0x5F},
339 	{0x3A28, 0x2F},
340 	{REG_NULL, 0x00},
341 };
342 
343 static __maybe_unused const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_37m_regs[] = {
344 	{0x3000, 0x01},
345 	{0x3002, 0x01},
346 	{0x300C, 0x5B},
347 	{0x300D, 0x40},
348 	{0x3034, 0xDC},
349 	{0x3035, 0x05},
350 	{0x3048, 0x01},
351 	{0x3049, 0x01},
352 	{0x304A, 0x01},
353 	{0x304B, 0x01},
354 	{0x304C, 0x13},
355 	{0x304D, 0x00},
356 	{0x3050, 0x00},
357 	{0x3058, 0xF4},
358 	{0x3059, 0x0A},
359 	{0x3068, 0x3D},
360 	{0x30BE, 0x5E},
361 	{0x30E8, 0x0A},
362 	{0x3110, 0x02},
363 	{0x314C, 0x80},//
364 	{0x315A, 0x02},
365 	{0x316A, 0x7E},
366 	{0x319D, 0x00},
367 	{0x319E, 0x01},//1188M
368 	{0x31A1, 0x00},
369 	{0x31D7, 0x01},
370 	{0x3200, 0x10},
371 	{0x3288, 0x22},
372 	{0x328A, 0x02},
373 	{0x328C, 0xA2},
374 	{0x328E, 0x22},
375 	{0x3415, 0x27},
376 	{0x3418, 0x27},
377 	{0x3428, 0xFE},
378 	{0x349E, 0x6A},
379 	{0x34A2, 0x9A},
380 	{0x34A4, 0x8A},
381 	{0x34A6, 0x8E},
382 	{0x34AA, 0xD8},
383 	{0x35BC, 0x00},
384 	{0x35BE, 0xFF},
385 	{0x35CC, 0x1B},
386 	{0x35CD, 0x00},
387 	{0x35CE, 0x2A},
388 	{0x35CF, 0x00},
389 	{0x35DC, 0x07},
390 	{0x35DE, 0x1A},
391 	{0x35DF, 0x00},
392 	{0x35E4, 0x2B},
393 	{0x35E5, 0x00},
394 	{0x35E6, 0x07},
395 	{0x35E7, 0x01},
396 	{0x3648, 0x01},
397 	{0x3678, 0x01},
398 	{0x367C, 0x69},
399 	{0x367E, 0x69},
400 	{0x3680, 0x69},
401 	{0x3682, 0x69},
402 	{0x3718, 0x1C},
403 	{0x371D, 0x05},
404 	{0x375D, 0x11},
405 	{0x375E, 0x43},
406 	{0x375F, 0x76},
407 	{0x3760, 0x07},
408 	{0x3768, 0x1B},
409 	{0x3769, 0x1B},
410 	{0x376A, 0x1A},
411 	{0x376B, 0x19},
412 	{0x376C, 0x17},
413 	{0x376D, 0x0F},
414 	{0x376E, 0x0B},
415 	{0x376F, 0x0B},
416 	{0x3770, 0x0B},
417 	{0x3776, 0x89},
418 	{0x3777, 0x00},
419 	{0x3778, 0xCA},
420 	{0x3779, 0x00},
421 	{0x377A, 0x45},
422 	{0x377B, 0x01},
423 	{0x377C, 0x56},
424 	{0x377D, 0x02},
425 	{0x377E, 0xFE},
426 	{0x377F, 0x03},
427 	{0x3780, 0xFE},
428 	{0x3781, 0x05},
429 	{0x3782, 0xFE},
430 	{0x3783, 0x06},
431 	{0x3784, 0x7F},
432 	{0x3788, 0x1F},
433 	{0x378A, 0xCA},
434 	{0x378B, 0x00},
435 	{0x378C, 0x45},
436 	{0x378D, 0x01},
437 	{0x378E, 0x56},
438 	{0x378F, 0x02},
439 	{0x3790, 0xFE},
440 	{0x3791, 0x03},
441 	{0x3792, 0xFE},
442 	{0x3793, 0x05},
443 	{0x3794, 0xFE},
444 	{0x3795, 0x06},
445 	{0x3796, 0x7F},
446 	{0x3798, 0xBF},
447 	{0x3A01, 0x01},
448 	{0x3A18, 0x8F},
449 	{0x3A1A, 0x4F},
450 	{0x3A1C, 0x47},
451 	{0x3A1E, 0x37},
452 	{0x3A1F, 0x01},
453 	{0x3A20, 0x4F},
454 	{0x3A22, 0x87},
455 	{0x3A24, 0x4F},
456 	{0x3A26, 0x7F},
457 	{0x3A28, 0x3F},
458 	{REG_NULL, 0x00},
459 };
460 
461 static const struct regval IMX464_linear_10bit_2688x1520_2lane_regs[] = {
462 	{0x3000, 0x01},
463 	{0x3002, 0x01},
464 	{0x300C, 0x3b},
465 	{0x300D, 0x2a},
466 	{0x3034, 0xDC},
467 	{0x3035, 0x05},
468 	{0x3048, 0x00},
469 	{0x3049, 0x00},
470 	{0x304A, 0x03},
471 	{0x304B, 0x02},
472 	{0x304C, 0x14},
473 	{0x304D, 0x03},
474 	{0x3050, 0x00},
475 	{0x3058, 0x83},
476 	{0x3059, 0x04},
477 	{0x3068, 0xc9},
478 	{0x30BE, 0x5E},
479 	{0x30E8, 0x14},
480 	{0x3110, 0x02},
481 	{0x314C, 0x29},
482 	{0x314D, 0x01},
483 	{0x315A, 0x06},
484 	{0x3168, 0xA0},
485 	{0x316A, 0x7E},
486 	{0x319D, 0x00},
487 	{0x319E, 0x02},
488 	{0x31A1, 0x00},
489 	{0x31D7, 0x00},
490 	{0x3200, 0x11},
491 	{0x3288, 0x22},
492 	{0x328A, 0x02},
493 	{0x328C, 0xA2},
494 	{0x328E, 0x22},
495 	{0x3415, 0x27},
496 	{0x3418, 0x27},
497 	{0x3428, 0xFE},
498 	{0x349E, 0x6A},
499 	{0x34A2, 0x9A},
500 	{0x34A4, 0x8A},
501 	{0x34A6, 0x8E},
502 	{0x34AA, 0xD8},
503 	{0x35BC, 0x00},
504 	{0x35BE, 0xFF},
505 	{0x35CC, 0x1B},
506 	{0x35CD, 0x00},
507 	{0x35CE, 0x2A},
508 	{0x35CF, 0x00},
509 	{0x35DC, 0x07},
510 	{0x35DE, 0x1A},
511 	{0x35DF, 0x00},
512 	{0x35E4, 0x2B},
513 	{0x35E5, 0x00},
514 	{0x35E6, 0x07},
515 	{0x35E7, 0x01},
516 	{0x3648, 0x01},
517 	{0x3678, 0x01},
518 	{0x367C, 0x69},
519 	{0x367E, 0x69},
520 	{0x3680, 0x69},
521 	{0x3682, 0x69},
522 	{0x3718, 0x1C},
523 	{0x371D, 0x05},
524 	{0x375D, 0x11},
525 	{0x375E, 0x43},
526 	{0x375F, 0x76},
527 	{0x3760, 0x07},
528 	{0x3768, 0x1B},
529 	{0x3769, 0x1B},
530 	{0x376A, 0x1A},
531 	{0x376B, 0x19},
532 	{0x376C, 0x17},
533 	{0x376D, 0x0F},
534 	{0x376E, 0x0B},
535 	{0x376F, 0x0B},
536 	{0x3770, 0x0B},
537 	{0x3776, 0x89},
538 	{0x3777, 0x00},
539 	{0x3778, 0xCA},
540 	{0x3779, 0x00},
541 	{0x377A, 0x45},
542 	{0x377B, 0x01},
543 	{0x377C, 0x56},
544 	{0x377D, 0x02},
545 	{0x377E, 0xFE},
546 	{0x377F, 0x03},
547 	{0x3780, 0xFE},
548 	{0x3781, 0x05},
549 	{0x3782, 0xFE},
550 	{0x3783, 0x06},
551 	{0x3784, 0x7F},
552 	{0x3788, 0x1F},
553 	{0x378A, 0xCA},
554 	{0x378B, 0x00},
555 	{0x378C, 0x45},
556 	{0x378D, 0x01},
557 	{0x378E, 0x56},
558 	{0x378F, 0x02},
559 	{0x3790, 0xFE},
560 	{0x3791, 0x03},
561 	{0x3792, 0xFE},
562 	{0x3793, 0x05},
563 	{0x3794, 0xFE},
564 	{0x3795, 0x06},
565 	{0x3796, 0x7F},
566 	{0x3798, 0xBF},
567 	{0x3A01, 0x01},
568 	{0x3A18, 0x7F},
569 	{0x3A1A, 0x37},
570 	{0x3A1C, 0x37},
571 	{0x3A1E, 0xF7},
572 	{0x3A1F, 0x00},
573 	{0x3A20, 0x3F},
574 	{0x3A22, 0x6F},
575 	{0x3A24, 0x3F},
576 	{0x3A26, 0x5F},
577 	{0x3A28, 0x2F},
578 	{REG_NULL, 0x00},
579 };
580 
581 static const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_regs[] = {
582 	{0x3000, 0x01},
583 	{0x3002, 0x01},
584 	{0x300C, 0x3B},
585 	{0x300D, 0x2A},
586 	{0x3034, 0xDC},
587 	{0x3035, 0x05},
588 	{0x3048, 0x01},
589 	{0x3049, 0x01},
590 	{0x304A, 0x04},
591 	{0x304B, 0x04},
592 	{0x304C, 0x13},
593 	{0x304D, 0x00},
594 	{0x3050, 0x00},
595 	{0x3058, 0xF4},
596 	{0x3059, 0x0A},
597 	{0x3068, 0x3D},
598 	{0x30BE, 0x5E},
599 	{0x30E8, 0x14},
600 	{0x3110, 0x02},
601 	{0x314C, 0x29},//
602 	{0x314D, 0x01},//
603 	{0x315A, 0x06},
604 	{0x3168, 0xA0},
605 	{0x316A, 0x7E},
606 	{0x319D, 0x00},
607 	{0x319E, 0x02},//1188M
608 	{0x31A1, 0x00},
609 	{0x31D7, 0x01},
610 	{0x3200, 0x10},
611 	{0x3288, 0x22},
612 	{0x328A, 0x02},
613 	{0x328C, 0xA2},
614 	{0x328E, 0x22},
615 	{0x3415, 0x27},
616 	{0x3418, 0x27},
617 	{0x3428, 0xFE},
618 	{0x349E, 0x6A},
619 	{0x34A2, 0x9A},
620 	{0x34A4, 0x8A},
621 	{0x34A6, 0x8E},
622 	{0x34AA, 0xD8},
623 	{0x35BC, 0x00},
624 	{0x35BE, 0xFF},
625 	{0x35CC, 0x1B},
626 	{0x35CD, 0x00},
627 	{0x35CE, 0x2A},
628 	{0x35CF, 0x00},
629 	{0x35DC, 0x07},
630 	{0x35DE, 0x1A},
631 	{0x35DF, 0x00},
632 	{0x35E4, 0x2B},
633 	{0x35E5, 0x00},
634 	{0x35E6, 0x07},
635 	{0x35E7, 0x01},
636 	{0x3648, 0x01},
637 	{0x3678, 0x01},
638 	{0x367C, 0x69},
639 	{0x367E, 0x69},
640 	{0x3680, 0x69},
641 	{0x3682, 0x69},
642 	{0x3718, 0x1C},
643 	{0x371D, 0x05},
644 	{0x375D, 0x11},
645 	{0x375E, 0x43},
646 	{0x375F, 0x76},
647 	{0x3760, 0x07},
648 	{0x3768, 0x1B},
649 	{0x3769, 0x1B},
650 	{0x376A, 0x1A},
651 	{0x376B, 0x19},
652 	{0x376C, 0x17},
653 	{0x376D, 0x0F},
654 	{0x376E, 0x0B},
655 	{0x376F, 0x0B},
656 	{0x3770, 0x0B},
657 	{0x3776, 0x89},
658 	{0x3777, 0x00},
659 	{0x3778, 0xCA},
660 	{0x3779, 0x00},
661 	{0x377A, 0x45},
662 	{0x377B, 0x01},
663 	{0x377C, 0x56},
664 	{0x377D, 0x02},
665 	{0x377E, 0xFE},
666 	{0x377F, 0x03},
667 	{0x3780, 0xFE},
668 	{0x3781, 0x05},
669 	{0x3782, 0xFE},
670 	{0x3783, 0x06},
671 	{0x3784, 0x7F},
672 	{0x3788, 0x1F},
673 	{0x378A, 0xCA},
674 	{0x378B, 0x00},
675 	{0x378C, 0x45},
676 	{0x378D, 0x01},
677 	{0x378E, 0x56},
678 	{0x378F, 0x02},
679 	{0x3790, 0xFE},
680 	{0x3791, 0x03},
681 	{0x3792, 0xFE},
682 	{0x3793, 0x05},
683 	{0x3794, 0xFE},
684 	{0x3795, 0x06},
685 	{0x3796, 0x7F},
686 	{0x3798, 0xBF},
687 	{0x3A01, 0x01},
688 	{0x3A18, 0x7F},
689 	{0x3A1A, 0x37},
690 	{0x3A1C, 0x37},
691 	{0x3A1E, 0xF7},
692 	{0x3A1F, 0x00},
693 	{0x3A20, 0x3F},
694 	{0x3A22, 0x6F},
695 	{0x3A24, 0x3F},
696 	{0x3A26, 0x5F},
697 	{0x3A28, 0x2F},
698 	{REG_NULL, 0x00},
699 };
700 
701 static const struct regval IMX464_linear_10bit_2688x1520_regs[] = {
702 	{0x3000, 0x01},
703 	{0x3002, 0x01},
704 	{0x300C, 0x5B},
705 	{0x300D, 0x40},
706 	{0x3030, 0xE4},
707 	{0x3031, 0x0C},
708 	{0x3034, 0xee},
709 	{0x3035, 0x02},
710 	{0x3048, 0x00},
711 	{0x3049, 0x00},
712 	{0x304A, 0x03},
713 	{0x304B, 0x02},
714 	{0x304C, 0x14},
715 	{0x3050, 0x00},
716 	{0x3058, 0x06},
717 	{0x3059, 0x09},
718 	{0x305C, 0x09},
719 	{0x3060, 0x21},
720 	{0x3061, 0x01},
721 	{0x3068, 0xc9},
722 	{0x306C, 0x56},
723 	{0x306D, 0x09},
724 	{0x30BE, 0x5E},
725 	{0x30E8, 0x14},
726 	{0x3110, 0x02},
727 	{0x314C, 0xC0},
728 	{0x315A, 0x06},
729 	{0x316A, 0x7E},
730 	{0x319D, 0x00},
731 	{0x319E, 0x02},
732 	{0x31A1, 0x00},
733 	{0x31D7, 0x00},
734 	{0x3200, 0x11},
735 	{0x3288, 0x22},
736 	{0x328A, 0x02},
737 	{0x328C, 0xA2},
738 	{0x328E, 0x22},
739 	{0x3415, 0x27},
740 	{0x3418, 0x27},
741 	{0x3428, 0xFE},
742 	{0x349E, 0x6A},
743 	{0x34A2, 0x9A},
744 	{0x34A4, 0x8A},
745 	{0x34A6, 0x8E},
746 	{0x34AA, 0xD8},
747 	{0x35BC, 0x00},
748 	{0x35BE, 0xFF},
749 	{0x35CC, 0x1B},
750 	{0x35CD, 0x00},
751 	{0x35CE, 0x2A},
752 	{0x35CF, 0x00},
753 	{0x35DC, 0x07},
754 	{0x35DE, 0x1A},
755 	{0x35DF, 0x00},
756 	{0x35E4, 0x2B},
757 	{0x35E5, 0x00},
758 	{0x35E6, 0x07},
759 	{0x35E7, 0x01},
760 	{0x3648, 0x01},
761 	{0x3678, 0x01},
762 	{0x367C, 0x69},
763 	{0x367E, 0x69},
764 	{0x3680, 0x69},
765 	{0x3682, 0x69},
766 	{0x3718, 0x1C},
767 	{0x371D, 0x05},
768 	{0x375D, 0x11},
769 	{0x375E, 0x43},
770 	{0x375F, 0x76},
771 	{0x3760, 0x07},
772 	{0x3768, 0x1B},
773 	{0x3769, 0x1B},
774 	{0x376A, 0x1A},
775 	{0x376B, 0x19},
776 	{0x376C, 0x17},
777 	{0x376D, 0x0F},
778 	{0x376E, 0x0B},
779 	{0x376F, 0x0B},
780 	{0x3770, 0x0B},
781 	{0x3776, 0x89},
782 	{0x3777, 0x00},
783 	{0x3778, 0xCA},
784 	{0x3779, 0x00},
785 	{0x377A, 0x45},
786 	{0x377B, 0x01},
787 	{0x377C, 0x56},
788 	{0x377D, 0x02},
789 	{0x377E, 0xFE},
790 	{0x377F, 0x03},
791 	{0x3780, 0xFE},
792 	{0x3781, 0x05},
793 	{0x3782, 0xFE},
794 	{0x3783, 0x06},
795 	{0x3784, 0x7F},
796 	{0x3788, 0x1F},
797 	{0x378A, 0xCA},
798 	{0x378B, 0x00},
799 	{0x378C, 0x45},
800 	{0x378D, 0x01},
801 	{0x378E, 0x56},
802 	{0x378F, 0x02},
803 	{0x3790, 0xFE},
804 	{0x3791, 0x03},
805 	{0x3792, 0xFE},
806 	{0x3793, 0x05},
807 	{0x3794, 0xFE},
808 	{0x3795, 0x06},
809 	{0x3796, 0x7F},
810 	{0x3798, 0xBF},
811 	{0x3A18, 0x7F},
812 	{0x3A1A, 0x37},
813 	{0x3A1C, 0x37},
814 	{0x3A1E, 0xF7},
815 	{0x3A1F, 0x00},
816 	{0x3A20, 0x3F},
817 	{0x3A22, 0x6F},
818 	{0x3A24, 0x3F},
819 	{0x3A26, 0x5F},
820 	{0x3A28, 0x2F},
821 	{REG_NULL, 0x00},
822 };
823 
824 static const struct regval IMX464_hdr_2x_10bit_2688x1520_regs[] = {
825 	{0x3000, 0x01},
826 	{0x3002, 0x01},
827 	{0x300C, 0x5B},
828 	{0x300D, 0x40},
829 	{0x3030, 0x72},
830 	{0x3031, 0x06},
831 	{0x3034, 0xee},
832 	{0x3035, 0x02},
833 	{0x3048, 0x01},
834 	{0x3049, 0x01},
835 	{0x304A, 0x04},
836 	{0x304B, 0x04},
837 	{0x304C, 0x13},
838 	{0x3050, 0x00},
839 	{0x3058, 0x06},
840 	{0x3059, 0x09},
841 	{0x305C, 0x09},
842 	{0x3060, 0x21},
843 	{0x3061, 0x01},
844 	{0x3068, 0x6D},
845 	{0x306C, 0x56},
846 	{0x306D, 0x09},
847 	{0x30BE, 0x5E},
848 	{0x30E8, 0x14},
849 	{0x3110, 0x02},
850 	{0x314C, 0xC0},
851 	{0x315A, 0x06},
852 	{0x316A, 0x7E},
853 	{0x319D, 0x00},
854 	{0x319E, 0x02},
855 	{0x31A1, 0x00},
856 	{0x31D7, 0x01},
857 	{0x3200, 0x10},
858 	{0x3288, 0x22},
859 	{0x328A, 0x02},
860 	{0x328C, 0xA2},
861 	{0x328E, 0x22},
862 	{0x3415, 0x27},
863 	{0x3418, 0x27},
864 	{0x3428, 0xFE},
865 	{0x349E, 0x6A},
866 	{0x34A2, 0x9A},
867 	{0x34A4, 0x8A},
868 	{0x34A6, 0x8E},
869 	{0x34AA, 0xD8},
870 	{0x35BC, 0x00},
871 	{0x35BE, 0xFF},
872 	{0x35CC, 0x1B},
873 	{0x35CD, 0x00},
874 	{0x35CE, 0x2A},
875 	{0x35CF, 0x00},
876 	{0x35DC, 0x07},
877 	{0x35DE, 0x1A},
878 	{0x35DF, 0x00},
879 	{0x35E4, 0x2B},
880 	{0x35E5, 0x00},
881 	{0x35E6, 0x07},
882 	{0x35E7, 0x01},
883 	{0x3648, 0x01},
884 	{0x3678, 0x01},
885 	{0x367C, 0x69},
886 	{0x367E, 0x69},
887 	{0x3680, 0x69},
888 	{0x3682, 0x69},
889 	{0x3718, 0x1C},
890 	{0x371D, 0x05},
891 	{0x375D, 0x11},
892 	{0x375E, 0x43},
893 	{0x375F, 0x76},
894 	{0x3760, 0x07},
895 	{0x3768, 0x1B},
896 	{0x3769, 0x1B},
897 	{0x376A, 0x1A},
898 	{0x376B, 0x19},
899 	{0x376C, 0x17},
900 	{0x376D, 0x0F},
901 	{0x376E, 0x0B},
902 	{0x376F, 0x0B},
903 	{0x3770, 0x0B},
904 	{0x3776, 0x89},
905 	{0x3777, 0x00},
906 	{0x3778, 0xCA},
907 	{0x3779, 0x00},
908 	{0x377A, 0x45},
909 	{0x377B, 0x01},
910 	{0x377C, 0x56},
911 	{0x377D, 0x02},
912 	{0x377E, 0xFE},
913 	{0x377F, 0x03},
914 	{0x3780, 0xFE},
915 	{0x3781, 0x05},
916 	{0x3782, 0xFE},
917 	{0x3783, 0x06},
918 	{0x3784, 0x7F},
919 	{0x3788, 0x1F},
920 	{0x378A, 0xCA},
921 	{0x378B, 0x00},
922 	{0x378C, 0x45},
923 	{0x378D, 0x01},
924 	{0x378E, 0x56},
925 	{0x378F, 0x02},
926 	{0x3790, 0xFE},
927 	{0x3791, 0x03},
928 	{0x3792, 0xFE},
929 	{0x3793, 0x05},
930 	{0x3794, 0xFE},
931 	{0x3795, 0x06},
932 	{0x3796, 0x7F},
933 	{0x3798, 0xBF},
934 	{0x3A18, 0x7F},
935 	{0x3A1A, 0x37},
936 	{0x3A1C, 0x37},
937 	{0x3A1E, 0xF7},
938 	{0x3A1F, 0x00},
939 	{0x3A20, 0x3F},
940 	{0x3A22, 0x6F},
941 	{0x3A24, 0x3F},
942 	{0x3A26, 0x5F},
943 	{0x3A28, 0x2F},
944 	{REG_NULL, 0x00},
945 };
946 
947 static const struct regval IMX464_hdr_3x_10bit_2688x1520_regs[] = {
948 	{0x3000, 0x01},
949 	{0x3002, 0x01},
950 	{0x300C, 0x5B},
951 	{0x300D, 0x40},
952 #ifdef FRAME_15_FPS
953 	{0x3030, 0xA2},
954 	{0x3031, 0x09},
955 #else
956 	{0x3030, 0xD1},
957 	{0x3031, 0x04},
958 #endif
959 //add for default
960 	{0x3034, 0xF4},
961 	{0x3035, 0x01},
962 	{0x3048, 0x01},
963 	{0x3049, 0x02},
964 	{0x304A, 0x05},
965 	{0x304B, 0x04},
966 	{0x304C, 0x13},
967 	{0x3050, 0x00},
968 	{0x3058, 0x77},
969 	{0x3059, 0x0D},
970 	{0x305C, 0x0D},
971 	{0x3060, 0xB0},
972 	{0x3061, 0x00},
973 	{0x3068, 0xA3},
974 	{0x306C, 0xCE},
975 	{0x306D, 0x00},
976 	{0x30BE, 0x5E},
977 	{0x30E8, 0x14},
978 	{0x3110, 0x02},
979 	{0x314C, 0x80},
980 	{0x315A, 0x02},
981 	{0x316A, 0x7E},
982 	{0x319D, 0x00},
983 	{0x319E, 0x01},
984 	{0x31A1, 0x00},
985 	{0x31D7, 0x03},
986 	{0x3200, 0x10},
987 	{0x3288, 0x22},
988 	{0x328A, 0x02},
989 	{0x328C, 0xA2},
990 	{0x328E, 0x22},
991 	{0x3415, 0x27},
992 	{0x3418, 0x27},
993 	{0x3428, 0xFE},
994 	{0x349E, 0x6A},
995 	{0x34A2, 0x9A},
996 	{0x34A4, 0x8A},
997 	{0x34A6, 0x8E},
998 	{0x34AA, 0xD8},
999 	{0x35BC, 0x00},
1000 	{0x35BE, 0xFF},
1001 	{0x35CC, 0x1B},
1002 	{0x35CD, 0x00},
1003 	{0x35CE, 0x2A},
1004 	{0x35CF, 0x00},
1005 	{0x35DC, 0x07},
1006 	{0x35DE, 0x1A},
1007 	{0x35DF, 0x00},
1008 	{0x35E4, 0x2B},
1009 	{0x35E5, 0x00},
1010 	{0x35E6, 0x07},
1011 	{0x35E7, 0x01},
1012 	{0x3648, 0x01},
1013 	{0x3678, 0x01},
1014 	{0x367C, 0x69},
1015 	{0x367E, 0x69},
1016 	{0x3680, 0x69},
1017 	{0x3682, 0x69},
1018 	{0x3718, 0x1C},
1019 	{0x371D, 0x05},
1020 	{0x375D, 0x11},
1021 	{0x375E, 0x43},
1022 	{0x375F, 0x76},
1023 	{0x3760, 0x07},
1024 	{0x3768, 0x1B},
1025 	{0x3769, 0x1B},
1026 	{0x376A, 0x1A},
1027 	{0x376B, 0x19},
1028 	{0x376C, 0x17},
1029 	{0x376D, 0x0F},
1030 	{0x376E, 0x0B},
1031 	{0x376F, 0x0B},
1032 	{0x3770, 0x0B},
1033 	{0x3776, 0x89},
1034 	{0x3777, 0x00},
1035 	{0x3778, 0xCA},
1036 	{0x3779, 0x00},
1037 	{0x377A, 0x45},
1038 	{0x377B, 0x01},
1039 	{0x377C, 0x56},
1040 	{0x377D, 0x02},
1041 	{0x377E, 0xFE},
1042 	{0x377F, 0x03},
1043 	{0x3780, 0xFE},
1044 	{0x3781, 0x05},
1045 	{0x3782, 0xFE},
1046 	{0x3783, 0x06},
1047 	{0x3784, 0x7F},
1048 	{0x3788, 0x1F},
1049 	{0x378A, 0xCA},
1050 	{0x378B, 0x00},
1051 	{0x378C, 0x45},
1052 	{0x378D, 0x01},
1053 	{0x378E, 0x56},
1054 	{0x378F, 0x02},
1055 	{0x3790, 0xFE},
1056 	{0x3791, 0x03},
1057 	{0x3792, 0xFE},
1058 	{0x3793, 0x05},
1059 	{0x3794, 0xFE},
1060 	{0x3795, 0x06},
1061 	{0x3796, 0x7F},
1062 	{0x3798, 0xBF},
1063 	{0x3A18, 0x8F},
1064 	{0x3A1A, 0x4F},
1065 	{0x3A1C, 0x47},
1066 	{0x3A1E, 0xF7},
1067 	{0x3A1F, 0x01},
1068 	{0x3A20, 0x4F},
1069 	{0x3A22, 0x87},
1070 	{0x3A24, 0x4F},
1071 	{0x3A26, 0x5F},
1072 	{0x3A28, 0x3F},
1073 	{REG_NULL, 0x00},
1074 };
1075 
1076 static __maybe_unused const struct regval IMX464_linear_12bit_2688x1520_regs[] = {
1077 	{0x3000, 0x01},
1078 	{0x3002, 0x00},
1079 	{0x300C, 0x3B},
1080 	{0x300D, 0x2A},
1081 	{0x3018, 0x04},
1082 	{0x302C, 0x30},
1083 	{0x302E, 0x80},
1084 	{0x302F, 0x0A},
1085 	{0x3030, 0x6B},
1086 	{0x3031, 0x0A},
1087 	{0x3032, 0x00},
1088 	{0x3034, 0xee},
1089 	{0x3035, 0x02},
1090 	{0x3048, 0x00},
1091 	{0x3049, 0x00},
1092 	{0x304A, 0x03},
1093 	{0x304B, 0x02},
1094 	{0x304C, 0x14},
1095 	{0x3050, 0x01},
1096 	{0x3056, 0x02},
1097 	{0x3057, 0x06},
1098 	{0x3058, 0x03},
1099 	{0x3059, 0x00},
1100 	{0x3068, 0xc9},
1101 	{0x3069, 0x00},
1102 	{0x30BE, 0x5E},
1103 	{0x30C6, 0x00},
1104 	{0x30CE, 0x00},
1105 	{0x30D8, 0x4F},
1106 	{0x30D9, 0x64},
1107 	{0x3110, 0x02},
1108 	{0x314C, 0xF0},
1109 	{0x315A, 0x06},
1110 	{0x3168, 0x82},
1111 	{0x316A, 0x7E},
1112 	{0x319D, 0x01},
1113 	{0x319E, 0x02},
1114 	{0x31A1, 0x00},
1115 	{0x31D7, 0x00},
1116 	{0x3202, 0x02},
1117 	{0x3288, 0x22},
1118 	{0x328A, 0x02},
1119 	{0x328C, 0xA2},
1120 	{0x328E, 0x22},
1121 	{0x3415, 0x27},
1122 	{0x3418, 0x27},
1123 	{0x3428, 0xFE},
1124 	{0x349E, 0x6A},
1125 	{0x34A2, 0x9A},
1126 	{0x34A4, 0x8A},
1127 	{0x34A6, 0x8E},
1128 	{0x34AA, 0xD8},
1129 	{0x3648, 0x01},
1130 	{0x3678, 0x01},
1131 	{0x367C, 0x69},
1132 	{0x367E, 0x69},
1133 	{0x3680, 0x69},
1134 	{0x3682, 0x69},
1135 	{0x371D, 0x05},
1136 	{0x375D, 0x11},
1137 	{0x375E, 0x43},
1138 	{0x375F, 0x76},
1139 	{0x3760, 0x07},
1140 	{0x3768, 0x1B},
1141 	{0x3769, 0x1B},
1142 	{0x376A, 0x1A},
1143 	{0x376B, 0x19},
1144 	{0x376C, 0x17},
1145 	{0x376D, 0x0F},
1146 	{0x376E, 0x0B},
1147 	{0x376F, 0x0B},
1148 	{0x3770, 0x0B},
1149 	{0x3776, 0x89},
1150 	{0x3777, 0x00},
1151 	{0x3778, 0xCA},
1152 	{0x3779, 0x00},
1153 	{0x377A, 0x45},
1154 	{0x377B, 0x01},
1155 	{0x377C, 0x56},
1156 	{0x377D, 0x02},
1157 	{0x377E, 0xFE},
1158 	{0x377F, 0x03},
1159 	{0x3780, 0xFE},
1160 	{0x3781, 0x05},
1161 	{0x3782, 0xFE},
1162 	{0x3783, 0x06},
1163 	{0x3784, 0x7F},
1164 	{0x3788, 0x1F},
1165 	{0x378A, 0xCA},
1166 	{0x378B, 0x00},
1167 	{0x378C, 0x45},
1168 	{0x378D, 0x01},
1169 	{0x378E, 0x56},
1170 	{0x378F, 0x02},
1171 	{0x3790, 0xFE},
1172 	{0x3791, 0x03},
1173 	{0x3792, 0xFE},
1174 	{0x3793, 0x05},
1175 	{0x3794, 0xFE},
1176 	{0x3795, 0x06},
1177 	{0x3796, 0x7F},
1178 	{0x3200, 0x11},
1179 	{0x3798, 0xBF},
1180 	{0x3A01, 0x03},
1181 	{0x3A18, 0x6F},
1182 	{0x3A1A, 0x2F},
1183 	{0x3A1C, 0x2F},
1184 	{0x3A1E, 0xBF},
1185 	{0x3A1F, 0x00},
1186 	{0x3A20, 0x2F},
1187 	{0x3A22, 0x57},
1188 	{0x3A24, 0x2F},
1189 	{0x3A26, 0x4F},
1190 	{0x3A28, 0x27},
1191 	{REG_NULL, 0x00},
1192 };
1193 
1194 static __maybe_unused const struct regval IMX464_hdr_2x_12bit_2688x1520_regs[] = {
1195 	{0x3000, 0x01},
1196 	{0x3002, 0x00},
1197 	{0x300C, 0x3B},
1198 	{0x300D, 0x2A},
1199 	{0x3018, 0x04},
1200 	{0x302C, 0x30},
1201 	{0x302E, 0x80},
1202 	{0x302F, 0x0A},
1203 	{0x3030, 0x40},
1204 	{0x3031, 0x06},
1205 	{0x3032, 0x00},
1206 	{0x3034, 0xee},
1207 	{0x3035, 0x02},
1208 	{0x3048, 0x01},
1209 	{0x3049, 0x01},
1210 	{0x304A, 0x04},
1211 	{0x304B, 0x04},
1212 	{0x304C, 0x13},
1213 	{0x3050, 0x01},
1214 	{0x3056, 0x02},
1215 	{0x3057, 0x06},
1216 	{0x3058, 0x20},
1217 	{0x3059, 0x03},
1218 	{0x3068, 0xD9},
1219 	{0x3069, 0x02},
1220 	{0x30BE, 0x5E},
1221 	{0x30C6, 0x00},
1222 	{0x30CE, 0x00},
1223 	{0x30D8, 0x4F},
1224 	{0x30D9, 0x64},
1225 	{0x3110, 0x02},
1226 	{0x314C, 0xF0},
1227 	{0x315A, 0x06},
1228 	{0x3168, 0x82},
1229 	{0x316A, 0x7E},
1230 	{0x319D, 0x01},
1231 	{0x319E, 0x02},
1232 	{0x31A1, 0x00},
1233 	{0x31D7, 0x01},
1234 	{0x3202, 0x02},
1235 	{0x3288, 0x22},
1236 	{0x328A, 0x02},
1237 	{0x328C, 0xA2},
1238 	{0x328E, 0x22},
1239 	{0x3415, 0x27},
1240 	{0x3418, 0x27},
1241 	{0x3428, 0xFE},
1242 	{0x349E, 0x6A},
1243 	{0x34A2, 0x9A},
1244 	{0x34A4, 0x8A},
1245 	{0x34A6, 0x8E},
1246 	{0x34AA, 0xD8},
1247 	{0x3648, 0x01},
1248 	{0x3678, 0x01},
1249 	{0x367C, 0x69},
1250 	{0x367E, 0x69},
1251 	{0x3680, 0x69},
1252 	{0x3682, 0x69},
1253 	{0x371D, 0x05},
1254 	{0x375D, 0x11},
1255 	{0x375E, 0x43},
1256 	{0x375F, 0x76},
1257 	{0x3760, 0x07},
1258 	{0x3768, 0x1B},
1259 	{0x3769, 0x1B},
1260 	{0x376A, 0x1A},
1261 	{0x376B, 0x19},
1262 	{0x376C, 0x17},
1263 	{0x376D, 0x0F},
1264 	{0x376E, 0x0B},
1265 	{0x376F, 0x0B},
1266 	{0x3770, 0x0B},
1267 	{0x3776, 0x89},
1268 	{0x3777, 0x00},
1269 	{0x3778, 0xCA},
1270 	{0x3779, 0x00},
1271 	{0x377A, 0x45},
1272 	{0x377B, 0x01},
1273 	{0x377C, 0x56},
1274 	{0x377D, 0x02},
1275 	{0x377E, 0xFE},
1276 	{0x377F, 0x03},
1277 	{0x3780, 0xFE},
1278 	{0x3781, 0x05},
1279 	{0x3782, 0xFE},
1280 	{0x3783, 0x06},
1281 	{0x3784, 0x7F},
1282 	{0x3788, 0x1F},
1283 	{0x378A, 0xCA},
1284 	{0x378B, 0x00},
1285 	{0x378C, 0x45},
1286 	{0x378D, 0x01},
1287 	{0x378E, 0x56},
1288 	{0x378F, 0x02},
1289 	{0x3790, 0xFE},
1290 	{0x3791, 0x03},
1291 	{0x3792, 0xFE},
1292 	{0x3793, 0x05},
1293 	{0x3794, 0xFE},
1294 	{0x3795, 0x06},
1295 	{0x3796, 0x7F},
1296 	{0x3200, 0x10},
1297 	{0x3798, 0xBF},
1298 	{0x3A01, 0x03},
1299 	{0x3A18, 0x6F},
1300 	{0x3A1A, 0x2F},
1301 	{0x3A1C, 0x2F},
1302 	{0x3A1E, 0xBF},
1303 	{0x3A1F, 0x00},
1304 	{0x3A20, 0x2F},
1305 	{0x3A22, 0x57},
1306 	{0x3A24, 0x2F},
1307 	{0x3A26, 0x4F},
1308 	{0x3A28, 0x27},
1309 	{REG_NULL, 0x00},
1310 };
1311 
1312 static __maybe_unused const struct regval IMX464_interal_sync_master_start_regs[] = {
1313 	{0x3010, 0x07},
1314 	{0x31a1, 0x00},
1315 	{REG_NULL, 0x00},
1316 };
1317 static __maybe_unused const struct regval IMX464_interal_sync_master_stop_regs[] = {
1318 	{0x31a1, 0x0f},
1319 	{REG_NULL, 0x00},
1320 };
1321 
1322 static __maybe_unused const struct regval IMX464_external_sync_master_start_regs[] = {
1323 	{0x3010, 0x05},
1324 	{0x31a1, 0x03},
1325 	{0x31d9, 0x01},
1326 	{REG_NULL, 0x00},
1327 };
1328 static __maybe_unused const struct regval IMX464_external_sync_master_stop_regs[] = {
1329 	{0x31a1, 0x0f},
1330 	{REG_NULL, 0x00},
1331 };
1332 
1333 static __maybe_unused const struct regval IMX464_slave_start_regs[] = {
1334 	{0x3010, 0x05},
1335 	{0x31a1, 0x0f},
1336 	{REG_NULL, 0x00},
1337 };
1338 
1339 /*
1340  * The width and height must be configured to be
1341  * the same as the current output resolution of the sensor.
1342  * The input width of the isp needs to be 16 aligned.
1343  * The input height of the isp needs to be 8 aligned.
1344  * If the width or height does not meet the alignment rules,
1345  * you can configure the cropping parameters with the following function to
1346  * crop out the appropriate resolution.
1347  * struct v4l2_subdev_pad_ops {
1348  *	.get_selection
1349  * }
1350  */
1351 static const struct IMX464_mode supported_modes[] = {
1352 	{
1353 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1354 		.width = 2712,
1355 		.height = 1536,
1356 		.max_fps = {
1357 			.numerator = 10000,
1358 			.denominator = 300000,
1359 		},
1360 		.exp_def = 0x0906,
1361 		.hts_def = 0x05dc * 2,
1362 		.vts_def = 0x0ce4,
1363 		.mipi_freq_idx = 0,
1364 		.bpp = 10,
1365 		.mclk = 37125000,
1366 		.reg_list = IMX464_linear_10bit_2688x1520_regs,
1367 		.hdr_mode = NO_HDR,
1368 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1369 	},
1370 	{
1371 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1372 		.width = 2712,
1373 		.height = 1536,
1374 		.max_fps = {
1375 			.numerator = 10000,
1376 			.denominator = 300000,
1377 		},
1378 		.exp_def = 0x03de,
1379 		.hts_def = 0x02ee * 4,
1380 		.vts_def = 0x0672 * 2,
1381 		.mipi_freq_idx = 1,
1382 		.bpp = 10,
1383 		.mclk = 37125000,
1384 		.reg_list = IMX464_hdr_2x_10bit_2688x1520_regs,
1385 		.hdr_mode = HDR_X2,
1386 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1387 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1388 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1389 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1390 	},
1391 	{
1392 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1393 		.width = 2712,
1394 		.height = 1536,
1395 		.max_fps = {
1396 			.numerator = 10000,
1397 			#ifdef FRAME_15_FPS
1398 			.denominator = 150000,
1399 			#else
1400 			.denominator = 300000,
1401 			#endif
1402 		},
1403 		.exp_def = 0x05cd,
1404 		.hts_def = 0x01F4 * 8,
1405 		#ifdef FRAME_15_FPS
1406 		.vts_def = 0x09A2 * 4,
1407 		#else
1408 		.vts_def = 0x04D1 * 4,
1409 		#endif
1410 		.mipi_freq_idx = 1,
1411 		.bpp = 10,
1412 		.mclk = 37125000,
1413 		.reg_list = IMX464_hdr_3x_10bit_2688x1520_regs,
1414 		.hdr_mode = HDR_X3,
1415 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
1416 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
1417 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr1
1418 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1419 	},
1420 };
1421 
1422 static const struct IMX464_mode supported_modes_2lane[] = {
1423 	{
1424 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1425 		.width = 2712,
1426 		.height = 1538,
1427 		.max_fps = {
1428 			.numerator = 10000,
1429 			.denominator = 300000,
1430 		},
1431 		.exp_def = 0x0600,
1432 		.hts_def = 0x05dc * 2,
1433 		.vts_def = 0x672,
1434 		.mipi_freq_idx = 0,
1435 		.bpp = 10,
1436 		.mclk = 24000000,
1437 		.reg_list = IMX464_linear_10bit_2688x1520_2lane_regs,
1438 		.hdr_mode = NO_HDR,
1439 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1440 	},
1441 	{
1442 		.bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1443 		.width = 2712,
1444 		.height = 1538,
1445 		.max_fps = {
1446 			.numerator = 10000,
1447 			.denominator = 150000,
1448 		},
1449 		.exp_def = 0x0600,
1450 		.hts_def = 0x05dc * 4,
1451 		.vts_def = 0x0672 * 2,
1452 		.mipi_freq_idx = 0,
1453 		.bpp = 10,
1454 		.mclk = 24000000,
1455 		.reg_list = IMX464_hdr_2x_10bit_2688x1520_2lane_regs,
1456 		.hdr_mode = HDR_X2,
1457 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1458 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1459 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1460 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1461 	},
1462 };
1463 
1464 static const s64 link_freq_menu_items[] = {
1465 	MIPI_FREQ_445M,
1466 	MIPI_FREQ_594M,
1467 };
1468 
1469 /* Write registers up to 4 at a time */
imx464_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)1470 static int imx464_write_reg(struct i2c_client *client, u16 reg,
1471 			    u32 len, u32 val)
1472 {
1473 	u32 buf_i, val_i;
1474 	u8 buf[6];
1475 	u8 *val_p;
1476 	__be32 val_be;
1477 
1478 	if (len > 4)
1479 		return -EINVAL;
1480 
1481 	buf[0] = reg >> 8;
1482 	buf[1] = reg & 0xff;
1483 
1484 	val_be = cpu_to_be32(val);
1485 	val_p = (u8 *)&val_be;
1486 	buf_i = 2;
1487 	val_i = 4 - len;
1488 
1489 	while (val_i < 4)
1490 		buf[buf_i++] = val_p[val_i++];
1491 
1492 	if (i2c_master_send(client, buf, len + 2) != len + 2)
1493 		return -EIO;
1494 
1495 	return 0;
1496 }
1497 
IMX464_write_array(struct i2c_client * client,const struct regval * regs)1498 static int IMX464_write_array(struct i2c_client *client,
1499 			      const struct regval *regs)
1500 {
1501 	u32 i;
1502 	int ret = 0;
1503 
1504 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
1505 		ret = imx464_write_reg(client, regs[i].addr,
1506 				       IMX464_REG_VALUE_08BIT, regs[i].val);
1507 	}
1508 	return ret;
1509 }
1510 
1511 /* Read registers up to 4 at a time */
IMX464_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)1512 static int IMX464_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
1513 			   u32 *val)
1514 {
1515 	struct i2c_msg msgs[2];
1516 	u8 *data_be_p;
1517 	__be32 data_be = 0;
1518 	__be16 reg_addr_be = cpu_to_be16(reg);
1519 	int ret;
1520 
1521 	if (len > 4 || !len)
1522 		return -EINVAL;
1523 
1524 	data_be_p = (u8 *)&data_be;
1525 	/* Write register address */
1526 	msgs[0].addr = client->addr;
1527 	msgs[0].flags = 0;
1528 	msgs[0].len = 2;
1529 	msgs[0].buf = (u8 *)&reg_addr_be;
1530 
1531 	/* Read data from register */
1532 	msgs[1].addr = client->addr;
1533 	msgs[1].flags = I2C_M_RD;
1534 	msgs[1].len = len;
1535 	msgs[1].buf = &data_be_p[4 - len];
1536 
1537 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1538 	if (ret != ARRAY_SIZE(msgs))
1539 		return -EIO;
1540 
1541 	*val = be32_to_cpu(data_be);
1542 
1543 	return 0;
1544 }
1545 
IMX464_get_reso_dist(const struct IMX464_mode * mode,struct v4l2_mbus_framefmt * framefmt)1546 static int IMX464_get_reso_dist(const struct IMX464_mode *mode,
1547 				struct v4l2_mbus_framefmt *framefmt)
1548 {
1549 	return abs(mode->width - framefmt->width) +
1550 	       abs(mode->height - framefmt->height);
1551 }
1552 
1553 static const struct IMX464_mode *
IMX464_find_best_fit(struct IMX464 * IMX464,struct v4l2_subdev_format * fmt)1554 IMX464_find_best_fit(struct IMX464 *IMX464, struct v4l2_subdev_format *fmt)
1555 {
1556 	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
1557 	int dist;
1558 	int cur_best_fit = 0;
1559 	int cur_best_fit_dist = -1;
1560 	unsigned int i;
1561 
1562 	for (i = 0; i < IMX464->cfg_num; i++) {
1563 		dist = IMX464_get_reso_dist(&IMX464->support_modes[i], framefmt);
1564 		if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
1565 			IMX464->support_modes[i].bus_fmt == framefmt->code) {
1566 			cur_best_fit_dist = dist;
1567 			cur_best_fit = i;
1568 		}
1569 	}
1570 
1571 	return &IMX464->support_modes[cur_best_fit];
1572 }
1573 
IMX464_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1574 static int IMX464_set_fmt(struct v4l2_subdev *sd,
1575 			  struct v4l2_subdev_pad_config *cfg,
1576 			  struct v4l2_subdev_format *fmt)
1577 {
1578 	struct IMX464 *IMX464 = to_IMX464(sd);
1579 	const struct IMX464_mode *mode;
1580 	s64 h_blank, vblank_def;
1581 	u64 pixel_rate = 0;
1582 
1583 	mutex_lock(&IMX464->mutex);
1584 
1585 	mode = IMX464_find_best_fit(IMX464, fmt);
1586 	fmt->format.code = mode->bus_fmt;
1587 	fmt->format.width = mode->width;
1588 	fmt->format.height = mode->height;
1589 	fmt->format.field = V4L2_FIELD_NONE;
1590 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1591 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1592 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
1593 #else
1594 		mutex_unlock(&IMX464->mutex);
1595 		return -ENOTTY;
1596 #endif
1597 	} else {
1598 		IMX464->cur_mode = mode;
1599 		h_blank = mode->hts_def - mode->width;
1600 		__v4l2_ctrl_modify_range(IMX464->hblank, h_blank,
1601 					 h_blank, 1, h_blank);
1602 		vblank_def = mode->vts_def - mode->height;
1603 		__v4l2_ctrl_modify_range(IMX464->vblank, vblank_def,
1604 					 IMX464_VTS_MAX - mode->height,
1605 					 1, vblank_def);
1606 		IMX464->cur_vts = IMX464->cur_mode->vts_def;
1607 		pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
1608 			     IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
1609 		__v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
1610 					 pixel_rate);
1611 		__v4l2_ctrl_s_ctrl(IMX464->link_freq,
1612 				   mode->mipi_freq_idx);
1613 	}
1614 
1615 	mutex_unlock(&IMX464->mutex);
1616 
1617 	return 0;
1618 }
1619 
IMX464_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1620 static int IMX464_get_fmt(struct v4l2_subdev *sd,
1621 			  struct v4l2_subdev_pad_config *cfg,
1622 			  struct v4l2_subdev_format *fmt)
1623 {
1624 	struct IMX464 *IMX464 = to_IMX464(sd);
1625 	const struct IMX464_mode *mode = IMX464->cur_mode;
1626 
1627 	mutex_lock(&IMX464->mutex);
1628 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1629 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1630 		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1631 #else
1632 		mutex_unlock(&IMX464->mutex);
1633 		return -ENOTTY;
1634 #endif
1635 	} else {
1636 		fmt->format.width = mode->width;
1637 		fmt->format.height = mode->height;
1638 		fmt->format.code = mode->bus_fmt;
1639 		fmt->format.field = V4L2_FIELD_NONE;
1640 		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
1641 			fmt->reserved[0] = mode->vc[fmt->pad];
1642 		else
1643 			fmt->reserved[0] = mode->vc[PAD0];
1644 	}
1645 	mutex_unlock(&IMX464->mutex);
1646 
1647 	return 0;
1648 }
1649 
IMX464_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)1650 static int IMX464_enum_mbus_code(struct v4l2_subdev *sd,
1651 				 struct v4l2_subdev_pad_config *cfg,
1652 				 struct v4l2_subdev_mbus_code_enum *code)
1653 {
1654 	struct IMX464 *IMX464 = to_IMX464(sd);
1655 
1656 	if (code->index != 0)
1657 		return -EINVAL;
1658 	code->code = IMX464->cur_mode->bus_fmt;
1659 
1660 	return 0;
1661 }
1662 
IMX464_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)1663 static int IMX464_enum_frame_sizes(struct v4l2_subdev *sd,
1664 				   struct v4l2_subdev_pad_config *cfg,
1665 				   struct v4l2_subdev_frame_size_enum *fse)
1666 {
1667 	struct IMX464 *IMX464 = to_IMX464(sd);
1668 
1669 	if (fse->index >= IMX464->cfg_num)
1670 		return -EINVAL;
1671 
1672 	if (fse->code != IMX464->support_modes[fse->index].bus_fmt)
1673 		return -EINVAL;
1674 
1675 	fse->min_width  = IMX464->support_modes[fse->index].width;
1676 	fse->max_width  = IMX464->support_modes[fse->index].width;
1677 	fse->max_height = IMX464->support_modes[fse->index].height;
1678 	fse->min_height = IMX464->support_modes[fse->index].height;
1679 
1680 	return 0;
1681 }
1682 
IMX464_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)1683 static int IMX464_g_frame_interval(struct v4l2_subdev *sd,
1684 				   struct v4l2_subdev_frame_interval *fi)
1685 {
1686 	struct IMX464 *IMX464 = to_IMX464(sd);
1687 	const struct IMX464_mode *mode = IMX464->cur_mode;
1688 
1689 	fi->interval = mode->max_fps;
1690 
1691 	return 0;
1692 }
1693 
IMX464_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)1694 static int IMX464_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
1695 				struct v4l2_mbus_config *config)
1696 {
1697 	struct IMX464 *IMX464 = to_IMX464(sd);
1698 	const struct IMX464_mode *mode = IMX464->cur_mode;
1699 	u32 val = 0;
1700 	u32 lane_num = IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
1701 
1702 	if (mode->hdr_mode == NO_HDR) {
1703 		val = 1 << (lane_num - 1) |
1704 		V4L2_MBUS_CSI2_CHANNEL_0 |
1705 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
1706 	}
1707 	if (mode->hdr_mode == HDR_X2)
1708 		val = 1 << (lane_num - 1) |
1709 		V4L2_MBUS_CSI2_CHANNEL_0 |
1710 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
1711 		V4L2_MBUS_CSI2_CHANNEL_1;
1712 	if (mode->hdr_mode == HDR_X3)
1713 		val = 1 << (lane_num - 1) |
1714 		V4L2_MBUS_CSI2_CHANNEL_0 |
1715 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
1716 		V4L2_MBUS_CSI2_CHANNEL_1 |
1717 		V4L2_MBUS_CSI2_CHANNEL_2;
1718 
1719 	config->type = V4L2_MBUS_CSI2_DPHY;
1720 	config->flags = val;
1721 
1722 	return 0;
1723 }
1724 
IMX464_get_module_inf(struct IMX464 * IMX464,struct rkmodule_inf * inf)1725 static void IMX464_get_module_inf(struct IMX464 *IMX464,
1726 				  struct rkmodule_inf *inf)
1727 {
1728 	memset(inf, 0, sizeof(*inf));
1729 	strscpy(inf->base.sensor, IMX464_NAME, sizeof(inf->base.sensor));
1730 	strscpy(inf->base.module, IMX464->module_name,
1731 		sizeof(inf->base.module));
1732 	strscpy(inf->base.lens, IMX464->len_name, sizeof(inf->base.lens));
1733 }
1734 
IMX464_set_hdrae(struct IMX464 * IMX464,struct preisp_hdrae_exp_s * ae)1735 static int IMX464_set_hdrae(struct IMX464 *IMX464,
1736 			    struct preisp_hdrae_exp_s *ae)
1737 {
1738 	struct i2c_client *client = IMX464->client;
1739 	u32 l_exp_time, m_exp_time, s_exp_time;
1740 	u32 l_a_gain, m_a_gain, s_a_gain;
1741 	u32 gain_switch = 0;
1742 	u32 shr1 = 0;
1743 	u32 shr0 = 0;
1744 	u32 rhs1 = 0;
1745 	u32 rhs1_max = 0;
1746 	static int rhs1_old = IMX464_RHS1_DEFAULT;
1747 	int rhs1_change_limit;
1748 	int ret = 0;
1749 	u32 fsc = IMX464->cur_vts;
1750 	u8 cg_mode = 0;
1751 
1752 	if (!IMX464->has_init_exp && !IMX464->streaming) {
1753 		IMX464->init_hdrae_exp = *ae;
1754 		IMX464->has_init_exp = true;
1755 		dev_dbg(&IMX464->client->dev, "IMX464 don't stream, record exp for hdr!\n");
1756 		return ret;
1757 	}
1758 	l_exp_time = ae->long_exp_reg;
1759 	m_exp_time = ae->middle_exp_reg;
1760 	s_exp_time = ae->short_exp_reg;
1761 	l_a_gain = ae->long_gain_reg;
1762 	m_a_gain = ae->middle_gain_reg;
1763 	s_a_gain = ae->short_gain_reg;
1764 	dev_dbg(&client->dev,
1765 		"rev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
1766 		l_exp_time, m_exp_time, s_exp_time,
1767 		l_a_gain, m_a_gain, s_a_gain);
1768 
1769 	if (IMX464->cur_mode->hdr_mode == HDR_X2) {
1770 		//2 stagger
1771 		l_a_gain = m_a_gain;
1772 		l_exp_time = m_exp_time;
1773 		cg_mode = ae->middle_cg_mode;
1774 	}
1775 	if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
1776 		gain_switch = 0x01 | 0x100;
1777 		IMX464->isHCG = true;
1778 	} else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
1779 		gain_switch = 0x00 | 0x100;
1780 		IMX464->isHCG = false;
1781 	}
1782 	ret = imx464_write_reg(client,
1783 		IMX464_GROUP_HOLD_REG,
1784 		IMX464_REG_VALUE_08BIT,
1785 		IMX464_GROUP_HOLD_START);
1786 	//gain effect n+1
1787 	ret |= imx464_write_reg(client,
1788 		IMX464_LF_GAIN_REG_H,
1789 		IMX464_REG_VALUE_08BIT,
1790 		IMX464_FETCH_GAIN_H(l_a_gain));
1791 	ret |= imx464_write_reg(client,
1792 		IMX464_LF_GAIN_REG_L,
1793 		IMX464_REG_VALUE_08BIT,
1794 		IMX464_FETCH_GAIN_L(l_a_gain));
1795 	ret |= imx464_write_reg(client,
1796 		IMX464_SF1_GAIN_REG_H,
1797 		IMX464_REG_VALUE_08BIT,
1798 		IMX464_FETCH_GAIN_H(s_a_gain));
1799 	ret |= imx464_write_reg(client,
1800 		IMX464_SF1_GAIN_REG_L,
1801 		IMX464_REG_VALUE_08BIT,
1802 		IMX464_FETCH_GAIN_L(s_a_gain));
1803 	if (gain_switch & 0x100)
1804 		ret |= imx464_write_reg(client,
1805 			IMX464_GAIN_SWITCH_REG,
1806 			IMX464_REG_VALUE_08BIT,
1807 			gain_switch & 0xff);
1808 	/* Restrictions
1809 	 *     FSC = 2 * VMAX = 4n                   (4n, align with 4)
1810 	 *   SHR1 + 9 <= SHR0 <= (FSC - 2)
1811 	 *
1812 	 *   exp_l = FSC - SHR0
1813 	 *    SHR0 = FSC - exp_l                     (2n, align with 2)
1814 	 *
1815 	 *   exp_s = RHS1 - SHR1
1816 	 *    SHR1 + 2 <= RHS1 < BRL * 2             (4n + 1)
1817 	 *    SHR1 + 2 <= RHS1 <= SHR0 - 9
1818 	 *          9 <= SHR1 <= RHS1 - 2           (2n + 1)
1819 	 *
1820 	 *    RHS1(n+1) >= (RHS1(n) + BRL * 2) - FSC + 2
1821 	 *
1822 	 *    RHS1 and SHR1 shall be even value.
1823 	 *
1824 	 *    T(l_exp) = FSC - SHR0,  unit: H
1825 	 *    T(s_exp) = RHS1 - SHR1, unit: H
1826 	 *    Exposure ratio: T(l_exp) / T(s_exp) >= 1
1827 	 */
1828 
1829 	/* The HDR mode vts is already double by default to workaround T-line */
1830 
1831 	//long exposure and short exposure
1832 	shr0 = fsc - l_exp_time;
1833 	rhs1_max = (RHS1_MAX > (shr0 - 9)) ? (shr0 - 9) : RHS1_MAX;
1834 	rhs1 = SHR1_MIN + s_exp_time;
1835 	dev_err(&client->dev, "line(%d) rhs1 %d\n", __LINE__, rhs1);
1836 	if (rhs1 < 11)
1837 		rhs1 = 11;
1838 	else if (rhs1 > rhs1_max)
1839 		rhs1 = rhs1_max;
1840 	dev_dbg(&client->dev, "line(%d) rhs1 %d\n", __LINE__, rhs1);
1841 
1842 	//Dynamic adjustment rhs1 must meet the following conditions
1843 	rhs1_change_limit = rhs1_old + 2 * BRL - fsc + 2;
1844 	rhs1_change_limit = (rhs1_change_limit < 11) ?  11 : rhs1_change_limit;
1845 	if (rhs1_max < rhs1_change_limit)
1846 		dev_err(&client->dev,
1847 			"The total exposure limit makes rhs1 max is %d,but old rhs1 limit makes rhs1 min is %d\n",
1848 			rhs1_max, rhs1_change_limit);
1849 	if (rhs1 < rhs1_change_limit)
1850 		rhs1 = rhs1_change_limit;
1851 
1852 	dev_dbg(&client->dev,
1853 		"line(%d) rhs1 %d,short time %d rhs1_old %d test %d\n",
1854 		__LINE__, rhs1, s_exp_time, rhs1_old,
1855 		(rhs1_old + 2 * BRL - fsc + 2));
1856 
1857 	rhs1 = (rhs1 >> 2) * 4 + 1;
1858 	rhs1_old = rhs1;
1859 
1860 	if (rhs1 - s_exp_time <= SHR1_MIN) {
1861 		shr1 = SHR1_MIN;
1862 		s_exp_time = rhs1 - shr1;
1863 	} else {
1864 		shr1 = rhs1 - s_exp_time;
1865 	}
1866 
1867 	if (shr1 < 9)
1868 		shr1 = 9;
1869 	else if (shr1 > (rhs1 - 2))
1870 		shr1 = rhs1 - 2;
1871 
1872 	if (shr0 < (rhs1 + 9))
1873 		shr0 = rhs1 + 9;
1874 	else if (shr0 > (fsc - 2))
1875 		shr0 = fsc - 2;
1876 
1877 	dev_dbg(&client->dev,
1878 		"fsc=%d,RHS1_MAX=%d,SHR1_MIN=%d,rhs1_max=%d\n",
1879 		fsc, RHS1_MAX, SHR1_MIN, rhs1_max);
1880 	dev_dbg(&client->dev,
1881 		"l_exp_time=%d,s_exp_time=%d,shr0=%d,shr1=%d,rhs1=%d,l_a_gain=%d,s_a_gain=%d\n",
1882 		l_exp_time, s_exp_time, shr0, shr1, rhs1, l_a_gain, s_a_gain);
1883 	//time effect n+2
1884 	ret |= imx464_write_reg(client,
1885 		IMX464_RHS1_REG_L,
1886 		IMX464_REG_VALUE_08BIT,
1887 		IMX464_FETCH_RHS1_L(rhs1));
1888 	ret |= imx464_write_reg(client,
1889 		IMX464_RHS1_REG_M,
1890 		IMX464_REG_VALUE_08BIT,
1891 		IMX464_FETCH_RHS1_M(rhs1));
1892 	ret |= imx464_write_reg(client,
1893 		IMX464_RHS1_REG_H,
1894 		IMX464_REG_VALUE_08BIT,
1895 		IMX464_FETCH_RHS1_H(rhs1));
1896 
1897 	ret |= imx464_write_reg(client,
1898 		IMX464_SF1_EXPO_REG_L,
1899 		IMX464_REG_VALUE_08BIT,
1900 		IMX464_FETCH_EXP_L(shr1));
1901 	ret |= imx464_write_reg(client,
1902 		IMX464_SF1_EXPO_REG_M,
1903 		IMX464_REG_VALUE_08BIT,
1904 		IMX464_FETCH_EXP_M(shr1));
1905 	ret |= imx464_write_reg(client,
1906 		IMX464_SF1_EXPO_REG_H,
1907 		IMX464_REG_VALUE_08BIT,
1908 		IMX464_FETCH_EXP_H(shr1));
1909 	ret |= imx464_write_reg(client,
1910 		IMX464_LF_EXPO_REG_L,
1911 		IMX464_REG_VALUE_08BIT,
1912 		IMX464_FETCH_EXP_L(shr0));
1913 	ret |= imx464_write_reg(client,
1914 		IMX464_LF_EXPO_REG_M,
1915 		IMX464_REG_VALUE_08BIT,
1916 		IMX464_FETCH_EXP_M(shr0));
1917 	ret |= imx464_write_reg(client,
1918 		IMX464_LF_EXPO_REG_H,
1919 		IMX464_REG_VALUE_08BIT,
1920 		IMX464_FETCH_EXP_H(shr0));
1921 	ret |= imx464_write_reg(client,
1922 		IMX464_GROUP_HOLD_REG,
1923 		IMX464_REG_VALUE_08BIT,
1924 		IMX464_GROUP_HOLD_END);
1925 	return ret;
1926 }
1927 
IMX464_set_hdrae_3frame(struct IMX464 * IMX464,struct preisp_hdrae_exp_s * ae)1928 static int IMX464_set_hdrae_3frame(struct IMX464 *IMX464,
1929 				   struct preisp_hdrae_exp_s *ae)
1930 {
1931 	struct i2c_client *client = IMX464->client;
1932 	u32 l_exp_time, m_exp_time, s_exp_time;
1933 	u32 l_a_gain, m_a_gain, s_a_gain;
1934 	int shr2, shr1, shr0, rhs2, rhs1 = 0;
1935 	int rhs1_change_limit, rhs2_change_limit = 0;
1936 	static int rhs1_old = IMX464_RHS1_X3_DEFAULT;
1937 	static int rhs2_old = IMX464_RHS2_X3_DEFAULT;
1938 	int ret = 0;
1939 	u32 gain_switch = 0;
1940 	u8 cg_mode = 0;
1941 	u32 fsc;
1942 	int rhs1_max = 0;
1943 	int shr2_min = 0;
1944 
1945 	if (!IMX464->has_init_exp && !IMX464->streaming) {
1946 		IMX464->init_hdrae_exp = *ae;
1947 		IMX464->has_init_exp = true;
1948 		dev_dbg(&IMX464->client->dev, "IMX464 is not streaming, save hdr ae!\n");
1949 		return ret;
1950 	}
1951 	l_exp_time = ae->long_exp_reg;
1952 	m_exp_time = ae->middle_exp_reg;
1953 	s_exp_time = ae->short_exp_reg;
1954 	l_a_gain = ae->long_gain_reg;
1955 	m_a_gain = ae->middle_gain_reg;
1956 	s_a_gain = ae->short_gain_reg;
1957 
1958 	if (IMX464->cur_mode->hdr_mode == HDR_X3) {
1959 		//3 stagger
1960 		cg_mode = ae->long_cg_mode;
1961 	}
1962 	if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
1963 		gain_switch = 0x01 | 0x100;
1964 		IMX464->isHCG = true;
1965 	} else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
1966 		gain_switch = 0x00 | 0x100;
1967 		IMX464->isHCG = false;
1968 	}
1969 
1970 	dev_dbg(&client->dev,
1971 		"rev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
1972 		l_exp_time, l_a_gain, m_exp_time, m_a_gain, s_exp_time, s_a_gain);
1973 
1974 	ret = imx464_write_reg(client, IMX464_GROUP_HOLD_REG,
1975 		IMX464_REG_VALUE_08BIT, IMX464_GROUP_HOLD_START);
1976 	/* gain effect n+1 */
1977 	ret |= imx464_write_reg(client, IMX464_LF_GAIN_REG_H,
1978 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_H(l_a_gain));
1979 	ret |= imx464_write_reg(client, IMX464_LF_GAIN_REG_L,
1980 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_L(l_a_gain));
1981 	ret |= imx464_write_reg(client, IMX464_SF1_GAIN_REG_H,
1982 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_H(m_a_gain));
1983 	ret |= imx464_write_reg(client, IMX464_SF1_GAIN_REG_L,
1984 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_L(m_a_gain));
1985 	ret |= imx464_write_reg(client, IMX464_SF2_GAIN_REG_H,
1986 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_H(s_a_gain));
1987 	ret |= imx464_write_reg(client, IMX464_SF2_GAIN_REG_L,
1988 		IMX464_REG_VALUE_08BIT, IMX464_FETCH_GAIN_L(s_a_gain));
1989 	if (gain_switch & 0x100)
1990 		ret |= imx464_write_reg(client,
1991 			IMX464_GAIN_SWITCH_REG,
1992 			IMX464_REG_VALUE_08BIT,
1993 			gain_switch & 0xff);
1994 
1995 	/* Restrictions
1996 	 *   FSC = 4 * VMAX and FSC should be 6n;
1997 	 *   exp_l = FSC - SHR0 + Toffset;
1998 	 *
1999 	 *   SHR0 = FSC - exp_l + Toffset;
2000 	 *   SHR0 <= (FSC -3);
2001 	 *   SHR0 >= RHS2 + 13;
2002 	 *   SHR0 should be 3n;
2003 	 *
2004 	 *   exp_m = RHS1 - SHR1 + Toffset;
2005 	 *
2006 	 *   RHS1 < BRL * 3;
2007 	 *   RHS1 <= SHR2 - 13;
2008 	 *   RHS1 >= SHR1 + 3;
2009 	 *   SHR1 >= 13;
2010 	 *   SHR1 <= RHS1 - 3;
2011 	 *   RHS1(n+1) >= RHS1(n) + BRL * 3 -FSC + 3;
2012 	 *
2013 	 *   SHR1 should be 3n+1 and RHS1 should be 6n+1;
2014 	 *
2015 	 *   exp_s = RHS2 - SHR2 + Toffset;
2016 	 *
2017 	 *   RHS2 < BRL * 3 + RHS1;
2018 	 *   RHS2 <= SHR0 - 13;
2019 	 *   RHS2 >= SHR2 + 3;
2020 	 *   SHR2 >= RHS1 + 13;
2021 	 *   SHR2 <= RHS2 - 3;
2022 	 *   RHS1(n+1) >= RHS1(n) + BRL * 3 -FSC + 3;
2023 	 *
2024 	 *   SHR2 should be 3n+2 and RHS2 should be 6n+2;
2025 	 */
2026 
2027 	/* The HDR mode vts is double by default to workaround T-line */
2028 	fsc = IMX464->cur_vts;
2029 	shr0 = fsc - l_exp_time;
2030 	dev_dbg(&client->dev,
2031 		"line(%d) shr0 %d, l_exp_time %d, fsc %d\n",
2032 		__LINE__, shr0, l_exp_time, fsc);
2033 
2034 	rhs1 = (SHR1_MIN_X3 + m_exp_time + 5) / 6 * 6 + 1;
2035 	rhs1_max = RHS1_MAX_X3;
2036 	if (rhs1 < SHR1_MIN_X3 + 3)
2037 		rhs1 = SHR1_MIN_X3 + 3;
2038 	else if (rhs1 > rhs1_max)
2039 		rhs1 = rhs1_max;
2040 
2041 	dev_dbg(&client->dev,
2042 		"line(%d) rhs1 %d, m_exp_time %d rhs1_old %d\n",
2043 		__LINE__, rhs1, m_exp_time, rhs1_old);
2044 
2045 	//Dynamic adjustment rhs2 must meet the following conditions
2046 
2047 	rhs1_change_limit = rhs1_old + 3 * BRL - fsc + 3;
2048 	rhs1_change_limit = (rhs1_change_limit < 16) ? 16 : rhs1_change_limit;
2049 	rhs1_change_limit = (rhs1_change_limit + 5) / 6 * 6 + 1;
2050 	if (rhs1_max < rhs1_change_limit) {
2051 		dev_err(&client->dev,
2052 			"The total exposure limit makes rhs1 max is %d,but old rhs1 limit makes rhs1 min is %d\n",
2053 			rhs1_max, rhs1_change_limit);
2054 		return -EINVAL;
2055 	}
2056 	if (rhs1 < rhs1_change_limit)
2057 		rhs1 = rhs1_change_limit;
2058 
2059 	dev_dbg(&client->dev,
2060 		"line(%d) m_exp_time %d rhs1_old %d, rhs1_new %d\n",
2061 		__LINE__, m_exp_time, rhs1_old, rhs1);
2062 
2063 	rhs1_old = rhs1;
2064 
2065 	/* shr1 = rhs1 - s_exp_time */
2066 	if (rhs1 - m_exp_time <= SHR1_MIN_X3) {
2067 		shr1 = SHR1_MIN_X3;
2068 		m_exp_time = rhs1 - shr1;
2069 	} else {
2070 		shr1 = rhs1 - m_exp_time;
2071 	}
2072 
2073 	shr2_min = rhs1 + 13;
2074 	rhs2 =  (shr2_min + s_exp_time + 5) / 6 * 6 + 2;
2075 	if (rhs2 > (shr0 - 13))
2076 		rhs2 = shr0 - 13;
2077 	else if (rhs2 < 32)//16+13 +3
2078 		rhs2 = 32;
2079 
2080 	dev_err(&client->dev,
2081 		"line(%d) rhs2 %d, s_exp_time %d, rhs2_old %d\n",
2082 		__LINE__, rhs2, s_exp_time, rhs2_old);
2083 
2084 	//Dynamic adjustment rhs2 must meet the following conditions
2085 	//RHS2(N+1) > (RHS2(N) + BRL �� 3) �C VMAX �� 4) + 3
2086 	rhs2_change_limit = rhs2_old + 3 * BRL - fsc + 3;
2087 	rhs2_change_limit = (rhs2_change_limit < 32) ?  32 : rhs2_change_limit;
2088 	rhs2_change_limit = (rhs2_change_limit + 5) / 6 * 6 + 2;
2089 	if ((shr0 - 13) < rhs2_change_limit) {
2090 		dev_err(&client->dev,
2091 			"The total exposure limit makes rhs2 max is %d,but old rhs1 limit makes rhs2 min is %d\n",
2092 			shr0 - 13, rhs2_change_limit);
2093 		return -EINVAL;
2094 	}
2095 	if (rhs2 < rhs2_change_limit)
2096 		rhs2 = rhs2_change_limit;
2097 
2098 	rhs2_old = rhs2;
2099 
2100 	/* shr2 = rhs2 - s_exp_time */
2101 	if (rhs2 - s_exp_time <= shr2_min) {
2102 		shr2 = shr2_min;
2103 		s_exp_time = rhs2 - shr2;
2104 	} else {
2105 		shr2 = rhs2 - s_exp_time;
2106 	}
2107 	dev_dbg(&client->dev,
2108 		"line(%d) rhs2_new %d, s_exp_time %d shr2 %d, rhs2_change_limit %d\n",
2109 		__LINE__, rhs2, s_exp_time, shr2, rhs2_change_limit);
2110 
2111 	if (shr0 < rhs2 + 13)
2112 		shr0 = rhs2 + 13;
2113 	else if (shr0 > fsc - 3)
2114 		shr0 = fsc - 3;
2115 
2116 	dev_dbg(&client->dev,
2117 		"long exposure: l_exp_time=%d, fsc=%d, shr0=%d, l_a_gain=%d\n",
2118 		l_exp_time, fsc, shr0, l_a_gain);
2119 	dev_dbg(&client->dev,
2120 		"middle exposure(SEF1): m_exp_time=%d, rhs1=%d, shr1=%d, m_a_gain=%d\n",
2121 		m_exp_time, rhs1, shr1, m_a_gain);
2122 	dev_dbg(&client->dev,
2123 		"short exposure(SEF2): s_exp_time=%d, rhs2=%d, shr2=%d, s_a_gain=%d\n",
2124 		s_exp_time, rhs2, shr2, s_a_gain);
2125 	/* time effect n+1 */
2126 	/* write SEF2 exposure RHS2 regs*/
2127 	ret |= imx464_write_reg(client,
2128 		IMX464_RHS2_REG_L,
2129 		IMX464_REG_VALUE_08BIT,
2130 		IMX464_FETCH_RHS1_L(rhs2));
2131 	ret |= imx464_write_reg(client,
2132 		IMX464_RHS2_REG_M,
2133 		IMX464_REG_VALUE_08BIT,
2134 		IMX464_FETCH_RHS1_M(rhs2));
2135 	ret |= imx464_write_reg(client,
2136 		IMX464_RHS2_REG_H,
2137 		IMX464_REG_VALUE_08BIT,
2138 		IMX464_FETCH_RHS1_H(rhs2));
2139 	/* write SEF2 exposure SHR2 regs*/
2140 	ret |= imx464_write_reg(client,
2141 		IMX464_SF2_EXPO_REG_L,
2142 		IMX464_REG_VALUE_08BIT,
2143 		IMX464_FETCH_EXP_L(shr2));
2144 	ret |= imx464_write_reg(client,
2145 		IMX464_SF2_EXPO_REG_M,
2146 		IMX464_REG_VALUE_08BIT,
2147 		IMX464_FETCH_EXP_M(shr2));
2148 	ret |= imx464_write_reg(client,
2149 		IMX464_SF2_EXPO_REG_H,
2150 		IMX464_REG_VALUE_08BIT,
2151 		IMX464_FETCH_EXP_H(shr2));
2152 	/* write SEF1 exposure RHS1 regs*/
2153 	ret |= imx464_write_reg(client,
2154 		IMX464_RHS1_REG_L,
2155 		IMX464_REG_VALUE_08BIT,
2156 		IMX464_FETCH_RHS1_L(rhs1));
2157 	ret |= imx464_write_reg(client,
2158 		IMX464_RHS1_REG_M,
2159 		IMX464_REG_VALUE_08BIT,
2160 		IMX464_FETCH_RHS1_M(rhs1));
2161 	ret |= imx464_write_reg(client,
2162 		IMX464_RHS1_REG_H,
2163 		IMX464_REG_VALUE_08BIT,
2164 		IMX464_FETCH_RHS1_H(rhs1));
2165 	/* write SEF1 exposure SHR1 regs*/
2166 	ret |= imx464_write_reg(client,
2167 		IMX464_SF1_EXPO_REG_L,
2168 		IMX464_REG_VALUE_08BIT,
2169 		IMX464_FETCH_EXP_L(shr1));
2170 	ret |= imx464_write_reg(client,
2171 		IMX464_SF1_EXPO_REG_M,
2172 		IMX464_REG_VALUE_08BIT,
2173 		IMX464_FETCH_EXP_M(shr1));
2174 	ret |= imx464_write_reg(client,
2175 		IMX464_SF1_EXPO_REG_H,
2176 		IMX464_REG_VALUE_08BIT,
2177 		IMX464_FETCH_EXP_H(shr1));
2178 	/* write LF exposure SHR0 regs*/
2179 	ret |= imx464_write_reg(client,
2180 		IMX464_LF_EXPO_REG_L,
2181 		IMX464_REG_VALUE_08BIT,
2182 		IMX464_FETCH_EXP_L(shr0));
2183 	ret |= imx464_write_reg(client,
2184 		IMX464_LF_EXPO_REG_M,
2185 		IMX464_REG_VALUE_08BIT,
2186 		IMX464_FETCH_EXP_M(shr0));
2187 	ret |= imx464_write_reg(client,
2188 		IMX464_LF_EXPO_REG_H,
2189 		IMX464_REG_VALUE_08BIT,
2190 		IMX464_FETCH_EXP_H(shr0));
2191 
2192 	ret |= imx464_write_reg(client, IMX464_GROUP_HOLD_REG,
2193 		IMX464_REG_VALUE_08BIT, IMX464_GROUP_HOLD_END);
2194 	return ret;
2195 }
2196 
IMX464_set_conversion_gain(struct IMX464 * IMX464,u32 * cg)2197 static int IMX464_set_conversion_gain(struct IMX464 *IMX464, u32 *cg)
2198 {
2199 	int ret = 0;
2200 	struct i2c_client *client = IMX464->client;
2201 	int cur_cg = *cg;
2202 	u32 gain_switch = 0;
2203 
2204 	if (IMX464->isHCG && cur_cg == GAIN_MODE_LCG) {
2205 		gain_switch = 0x00 | 0x100;
2206 		IMX464->isHCG = false;
2207 	} else if (!IMX464->isHCG && cur_cg == GAIN_MODE_HCG) {
2208 		gain_switch = 0x01 | 0x100;
2209 		IMX464->isHCG = true;
2210 	}
2211 	ret = imx464_write_reg(client,
2212 			IMX464_GROUP_HOLD_REG,
2213 			IMX464_REG_VALUE_08BIT,
2214 			IMX464_GROUP_HOLD_START);
2215 	if (gain_switch & 0x100)
2216 		ret |= imx464_write_reg(client,
2217 			IMX464_GAIN_SWITCH_REG,
2218 			IMX464_REG_VALUE_08BIT,
2219 			gain_switch & 0xff);
2220 	ret |= imx464_write_reg(client,
2221 			IMX464_GROUP_HOLD_REG,
2222 			IMX464_REG_VALUE_08BIT,
2223 			IMX464_GROUP_HOLD_END);
2224 	return ret;
2225 }
2226 
2227 #ifdef USED_SYS_DEBUG
2228 //ag: echo 0 >  /sys/devices/platform/ff510000.i2c/i2c-1/1-0037/cam_s_cg
set_conversion_gain_status(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)2229 static ssize_t set_conversion_gain_status(struct device *dev,
2230 	struct device_attribute *attr,
2231 	const char *buf,
2232 	size_t count)
2233 {
2234 	struct i2c_client *client = to_i2c_client(dev);
2235 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2236 	struct IMX464 *IMX464 = to_IMX464(sd);
2237 	int status = 0;
2238 	int ret = 0;
2239 
2240 	ret = kstrtoint(buf, 0, &status);
2241 	if (!ret && status >= 0 && status < 2)
2242 		IMX464_set_conversion_gain(IMX464, &status);
2243 	else
2244 		dev_err(dev, "input 0 for LCG, 1 for HCG, cur %d\n", status);
2245 	return count;
2246 }
2247 
2248 static struct device_attribute attributes[] = {
2249 	__ATTR(cam_s_cg, S_IWUSR, NULL, set_conversion_gain_status),
2250 };
2251 
add_sysfs_interfaces(struct device * dev)2252 static int add_sysfs_interfaces(struct device *dev)
2253 {
2254 	int i;
2255 
2256 	for (i = 0; i < ARRAY_SIZE(attributes); i++)
2257 		if (device_create_file(dev, attributes + i))
2258 			goto undo;
2259 	return 0;
2260 undo:
2261 	for (i--; i >= 0 ; i--)
2262 		device_remove_file(dev, attributes + i);
2263 	dev_err(dev, "%s: failed to create sysfs interface\n", __func__);
2264 	return -ENODEV;
2265 }
2266 
remove_sysfs_interfaces(struct device * dev)2267 static int remove_sysfs_interfaces(struct device *dev)
2268 {
2269 	int i;
2270 
2271 	for (i = 0; i < ARRAY_SIZE(attributes); i++)
2272 		device_remove_file(dev, attributes + i);
2273 	return 0;
2274 }
2275 #endif
2276 
IMX464_get_channel_info(struct IMX464 * IMX464,struct rkmodule_channel_info * ch_info)2277 static int IMX464_get_channel_info(struct IMX464 *IMX464, struct rkmodule_channel_info *ch_info)
2278 {
2279 	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
2280 		return -EINVAL;
2281 	ch_info->vc = IMX464->cur_mode->vc[ch_info->index];
2282 	ch_info->width = IMX464->cur_mode->width;
2283 	ch_info->height = IMX464->cur_mode->height;
2284 	ch_info->bus_fmt = IMX464->cur_mode->bus_fmt;
2285 	return 0;
2286 }
2287 
IMX464_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)2288 static long IMX464_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
2289 {
2290 	struct IMX464 *IMX464 = to_IMX464(sd);
2291 	struct rkmodule_hdr_cfg *hdr;
2292 	struct rkmodule_channel_info *ch_info;
2293 	u32 i, h, w, stream;
2294 	long ret = 0;
2295 	u64 pixel_rate = 0;
2296 	u32 *sync_mode = NULL;
2297 
2298 	switch (cmd) {
2299 	case PREISP_CMD_SET_HDRAE_EXP:
2300 		if (IMX464->cur_mode->hdr_mode == HDR_X2)
2301 			ret = IMX464_set_hdrae(IMX464, arg);
2302 		else if (IMX464->cur_mode->hdr_mode == HDR_X3)
2303 			ret = IMX464_set_hdrae_3frame(IMX464, arg);
2304 		break;
2305 	case RKMODULE_GET_MODULE_INFO:
2306 		IMX464_get_module_inf(IMX464, (struct rkmodule_inf *)arg);
2307 		break;
2308 	case RKMODULE_GET_HDR_CFG:
2309 		hdr = (struct rkmodule_hdr_cfg *)arg;
2310 		hdr->esp.mode = HDR_NORMAL_VC;
2311 		hdr->hdr_mode = IMX464->cur_mode->hdr_mode;
2312 		break;
2313 	case RKMODULE_SET_HDR_CFG:
2314 		hdr = (struct rkmodule_hdr_cfg *)arg;
2315 		w = IMX464->cur_mode->width;
2316 		h = IMX464->cur_mode->height;
2317 		for (i = 0; i < IMX464->cfg_num; i++) {
2318 			if (w == IMX464->support_modes[i].width &&
2319 			    h == IMX464->support_modes[i].height &&
2320 			    IMX464->support_modes[i].hdr_mode == hdr->hdr_mode) {
2321 				IMX464->cur_mode = &IMX464->support_modes[i];
2322 				break;
2323 			}
2324 		}
2325 		if (i == IMX464->cfg_num) {
2326 			dev_err(&IMX464->client->dev,
2327 				"not find hdr mode:%d %dx%d config\n",
2328 				hdr->hdr_mode, w, h);
2329 			ret = -EINVAL;
2330 		} else {
2331 			w = IMX464->cur_mode->hts_def - IMX464->cur_mode->width;
2332 			h = IMX464->cur_mode->vts_def - IMX464->cur_mode->height;
2333 			__v4l2_ctrl_modify_range(IMX464->hblank, w, w, 1, w);
2334 			__v4l2_ctrl_modify_range(IMX464->vblank, h,
2335 				IMX464_VTS_MAX - IMX464->cur_mode->height,
2336 				1, h);
2337 			IMX464->cur_vts = IMX464->cur_mode->vts_def;
2338 			pixel_rate = (u32)link_freq_menu_items[IMX464->cur_mode->mipi_freq_idx] / IMX464->cur_mode->bpp * 2 *
2339 				     IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
2340 			__v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
2341 						 pixel_rate);
2342 			__v4l2_ctrl_s_ctrl(IMX464->link_freq,
2343 					   IMX464->cur_mode->mipi_freq_idx);
2344 		}
2345 		break;
2346 	case RKMODULE_SET_CONVERSION_GAIN:
2347 		ret = IMX464_set_conversion_gain(IMX464, (u32 *)arg);
2348 		break;
2349 	case RKMODULE_SET_QUICK_STREAM:
2350 
2351 		stream = *((u32 *)arg);
2352 
2353 		if (stream)
2354 			ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2355 				IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
2356 		else
2357 			ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2358 				IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
2359 
2360 		break;
2361 	case RKMODULE_GET_CHANNEL_INFO:
2362 		ch_info = (struct rkmodule_channel_info *)arg;
2363 		ret = IMX464_get_channel_info(IMX464, ch_info);
2364 		break;
2365 	case RKMODULE_GET_SYNC_MODE:
2366 		sync_mode = (u32 *)arg;
2367 		*sync_mode = IMX464->sync_mode;
2368 		break;
2369 	case RKMODULE_SET_SYNC_MODE:
2370 		sync_mode = (u32 *)arg;
2371 		IMX464->sync_mode = *sync_mode;
2372 		break;
2373 	default:
2374 		ret = -ENOIOCTLCMD;
2375 		break;
2376 	}
2377 
2378 	return ret;
2379 }
2380 
2381 #ifdef CONFIG_COMPAT
IMX464_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)2382 static long IMX464_compat_ioctl32(struct v4l2_subdev *sd,
2383 				  unsigned int cmd, unsigned long arg)
2384 {
2385 	void __user *up = compat_ptr(arg);
2386 	struct rkmodule_inf *inf;
2387 	struct rkmodule_awb_cfg *cfg;
2388 	struct rkmodule_hdr_cfg *hdr;
2389 	struct preisp_hdrae_exp_s *hdrae;
2390 	struct rkmodule_channel_info *ch_info;
2391 	long ret;
2392 	u32 cg = 0;
2393 	u32  stream;
2394 	u32 sync_mode;
2395 
2396 	switch (cmd) {
2397 	case RKMODULE_GET_MODULE_INFO:
2398 		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
2399 		if (!inf) {
2400 			ret = -ENOMEM;
2401 			return ret;
2402 		}
2403 
2404 		ret = IMX464_ioctl(sd, cmd, inf);
2405 		if (!ret) {
2406 			ret = copy_to_user(up, inf, sizeof(*inf));
2407 			if (ret)
2408 				ret = -EFAULT;
2409 		}
2410 		kfree(inf);
2411 		break;
2412 	case RKMODULE_AWB_CFG:
2413 		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
2414 		if (!cfg) {
2415 			ret = -ENOMEM;
2416 			return ret;
2417 		}
2418 
2419 		ret = copy_from_user(cfg, up, sizeof(*cfg));
2420 		if (!ret)
2421 			ret = IMX464_ioctl(sd, cmd, cfg);
2422 		else
2423 			ret = -EFAULT;
2424 		kfree(cfg);
2425 		break;
2426 	case RKMODULE_GET_HDR_CFG:
2427 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2428 		if (!hdr) {
2429 			ret = -ENOMEM;
2430 			return ret;
2431 		}
2432 
2433 		ret = IMX464_ioctl(sd, cmd, hdr);
2434 		if (!ret) {
2435 			ret = copy_to_user(up, hdr, sizeof(*hdr));
2436 			if (ret)
2437 				ret = -EFAULT;
2438 		}
2439 		kfree(hdr);
2440 		break;
2441 	case RKMODULE_SET_HDR_CFG:
2442 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2443 		if (!hdr) {
2444 			ret = -ENOMEM;
2445 			return ret;
2446 		}
2447 
2448 		ret = copy_from_user(hdr, up, sizeof(*hdr));
2449 		if (!ret)
2450 			ret = IMX464_ioctl(sd, cmd, hdr);
2451 		else
2452 			ret = -EFAULT;
2453 		kfree(hdr);
2454 		break;
2455 	case PREISP_CMD_SET_HDRAE_EXP:
2456 		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
2457 		if (!hdrae) {
2458 			ret = -ENOMEM;
2459 			return ret;
2460 		}
2461 
2462 		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
2463 		if (!ret)
2464 			ret = IMX464_ioctl(sd, cmd, hdrae);
2465 		else
2466 			ret = -EFAULT;
2467 		kfree(hdrae);
2468 		break;
2469 	case RKMODULE_SET_CONVERSION_GAIN:
2470 		ret = copy_from_user(&cg, up, sizeof(cg));
2471 		if (!ret)
2472 			ret = IMX464_ioctl(sd, cmd, &cg);
2473 		else
2474 			ret = -EFAULT;
2475 		break;
2476 	case RKMODULE_SET_QUICK_STREAM:
2477 		ret = copy_from_user(&stream, up, sizeof(u32));
2478 		if (!ret)
2479 			ret = IMX464_ioctl(sd, cmd, &stream);
2480 		else
2481 			ret = -EFAULT;
2482 
2483 		break;
2484 	case RKMODULE_GET_CHANNEL_INFO:
2485 		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2486 		if (!ch_info) {
2487 			ret = -ENOMEM;
2488 			return ret;
2489 		}
2490 
2491 		ret = IMX464_ioctl(sd, cmd, ch_info);
2492 		if (!ret) {
2493 			ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2494 			if (ret)
2495 				ret = -EFAULT;
2496 		}
2497 		kfree(ch_info);
2498 		break;
2499 	case RKMODULE_GET_SYNC_MODE:
2500 		ret = IMX464_ioctl(sd, cmd, &sync_mode);
2501 		if (!ret) {
2502 			ret = copy_to_user(up, &sync_mode, sizeof(u32));
2503 			if (ret)
2504 				ret = -EFAULT;
2505 		}
2506 		break;
2507 	case RKMODULE_SET_SYNC_MODE:
2508 		ret = copy_from_user(&sync_mode, up, sizeof(u32));
2509 		if (!ret)
2510 			ret = IMX464_ioctl(sd, cmd, &sync_mode);
2511 		else
2512 			ret = -EFAULT;
2513 		break;
2514 	default:
2515 		ret = -ENOIOCTLCMD;
2516 		break;
2517 	}
2518 
2519 	return ret;
2520 }
2521 #endif
2522 
IMX464_init_conversion_gain(struct IMX464 * IMX464,bool isHCG)2523 static int IMX464_init_conversion_gain(struct IMX464 *IMX464, bool isHCG)
2524 {
2525 	struct i2c_client *client = IMX464->client;
2526 	int ret = 0;
2527 	u32 val = 0;
2528 
2529 	if (isHCG)
2530 		val = 0x01;
2531 	else
2532 		val = 0;
2533 	ret = imx464_write_reg(client,
2534 		IMX464_GAIN_SWITCH_REG,
2535 		IMX464_REG_VALUE_08BIT,
2536 		val);
2537 	return ret;
2538 }
2539 
__IMX464_start_stream(struct IMX464 * IMX464)2540 static int __IMX464_start_stream(struct IMX464 *IMX464)
2541 {
2542 	int ret;
2543 
2544 	ret = IMX464_write_array(IMX464->client, IMX464->cur_mode->reg_list);
2545 	if (ret)
2546 		return ret;
2547 	ret = IMX464_init_conversion_gain(IMX464, IMX464->isHCG);
2548 	if (ret)
2549 		return ret;
2550 	/* In case these controls are set before streaming */
2551 	ret = __v4l2_ctrl_handler_setup(&IMX464->ctrl_handler);
2552 	if (ret)
2553 		return ret;
2554 	if (IMX464->has_init_exp && IMX464->cur_mode->hdr_mode != NO_HDR) {
2555 		ret = IMX464_ioctl(&IMX464->subdev, PREISP_CMD_SET_HDRAE_EXP,
2556 			&IMX464->init_hdrae_exp);
2557 		if (ret) {
2558 			dev_err(&IMX464->client->dev,
2559 				"init exp fail in hdr mode\n");
2560 			return ret;
2561 		}
2562 	}
2563 
2564 	if (IMX464->sync_mode == EXTERNAL_MASTER_MODE) {
2565 		ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_start_regs);
2566 		v4l2_err(&IMX464->subdev, "cur externam master mode\n");
2567 	} else if (IMX464->sync_mode == INTERNAL_MASTER_MODE) {
2568 		ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_start_regs);
2569 		v4l2_err(&IMX464->subdev, "cur intertal master\n");
2570 	} else if (IMX464->sync_mode == SLAVE_MODE) {
2571 		ret |= IMX464_write_array(IMX464->client, IMX464_slave_start_regs);
2572 		v4l2_err(&IMX464->subdev, "cur slave mode\n");
2573 	}
2574 	if (IMX464->sync_mode == NO_SYNC_MODE) {
2575 		ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2576 					IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
2577 		usleep_range(30000, 40000);
2578 		ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2579 					IMX464_REG_VALUE_08BIT, 0);
2580 	} else {
2581 		ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2582 					IMX464_REG_VALUE_08BIT, 0);
2583 	}
2584 	return ret;
2585 }
2586 
__IMX464_stop_stream(struct IMX464 * IMX464)2587 static int __IMX464_stop_stream(struct IMX464 *IMX464)
2588 {
2589 	int ret = 0;
2590 
2591 	IMX464->has_init_exp = false;
2592 	ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2593 			IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
2594 
2595 	if (IMX464->sync_mode == EXTERNAL_MASTER_MODE)
2596 		ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_stop_regs);
2597 	else if (IMX464->sync_mode == INTERNAL_MASTER_MODE)
2598 		ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_stop_regs);
2599 	return ret;
2600 }
2601 
IMX464_s_stream(struct v4l2_subdev * sd,int on)2602 static int IMX464_s_stream(struct v4l2_subdev *sd, int on)
2603 {
2604 	struct IMX464 *IMX464 = to_IMX464(sd);
2605 	struct i2c_client *client = IMX464->client;
2606 	int ret = 0;
2607 
2608 	mutex_lock(&IMX464->mutex);
2609 	on = !!on;
2610 	if (on == IMX464->streaming)
2611 		goto unlock_and_return;
2612 
2613 	if (on) {
2614 		ret = pm_runtime_get_sync(&client->dev);
2615 		if (ret < 0) {
2616 			pm_runtime_put_noidle(&client->dev);
2617 			goto unlock_and_return;
2618 		}
2619 
2620 		ret = __IMX464_start_stream(IMX464);
2621 		if (ret) {
2622 			v4l2_err(sd, "start stream failed while write regs\n");
2623 			pm_runtime_put(&client->dev);
2624 			goto unlock_and_return;
2625 		}
2626 	} else {
2627 		__IMX464_stop_stream(IMX464);
2628 		pm_runtime_put(&client->dev);
2629 	}
2630 
2631 	IMX464->streaming = on;
2632 
2633 unlock_and_return:
2634 	mutex_unlock(&IMX464->mutex);
2635 
2636 	return ret;
2637 }
2638 
IMX464_s_power(struct v4l2_subdev * sd,int on)2639 static int IMX464_s_power(struct v4l2_subdev *sd, int on)
2640 {
2641 	struct IMX464 *IMX464 = to_IMX464(sd);
2642 	struct i2c_client *client = IMX464->client;
2643 	int ret = 0;
2644 
2645 	mutex_lock(&IMX464->mutex);
2646 
2647 	/* If the power state is not modified - no work to do. */
2648 	if (IMX464->power_on == !!on)
2649 		goto unlock_and_return;
2650 
2651 	if (on) {
2652 		ret = pm_runtime_get_sync(&client->dev);
2653 		if (ret < 0) {
2654 			pm_runtime_put_noidle(&client->dev);
2655 			goto unlock_and_return;
2656 		}
2657 
2658 		ret = IMX464_write_array(IMX464->client, IMX464_global_regs);
2659 		if (ret) {
2660 			v4l2_err(sd, "could not set init registers\n");
2661 			pm_runtime_put_noidle(&client->dev);
2662 			goto unlock_and_return;
2663 		}
2664 
2665 		IMX464->power_on = true;
2666 	} else {
2667 		pm_runtime_put(&client->dev);
2668 		IMX464->power_on = false;
2669 	}
2670 
2671 unlock_and_return:
2672 	mutex_unlock(&IMX464->mutex);
2673 
2674 	return ret;
2675 }
2676 
2677 /* Calculate the delay in us by clock rate and clock cycles */
IMX464_cal_delay(u32 cycles)2678 static inline u32 IMX464_cal_delay(u32 cycles)
2679 {
2680 	return DIV_ROUND_UP(cycles, IMX464_XVCLK_FREQ_37M / 1000 / 1000);
2681 }
2682 
__IMX464_power_on(struct IMX464 * IMX464)2683 static int __IMX464_power_on(struct IMX464 *IMX464)
2684 {
2685 	int ret;
2686 	u32 delay_us;
2687 	struct device *dev = &IMX464->client->dev;
2688 
2689 	if (!IS_ERR_OR_NULL(IMX464->pins_default)) {
2690 		ret = pinctrl_select_state(IMX464->pinctrl,
2691 					   IMX464->pins_default);
2692 		if (ret < 0)
2693 			dev_err(dev, "could not set pins\n");
2694 	}
2695 
2696 	ret = clk_set_rate(IMX464->xvclk, IMX464->cur_mode->mclk);
2697 	if (ret < 0)
2698 		dev_warn(dev, "Failed to set xvclk rate\n");
2699 	if (clk_get_rate(IMX464->xvclk) != IMX464->cur_mode->mclk)
2700 		dev_warn(dev, "xvclk mismatched, %lu\n", clk_get_rate(IMX464->xvclk));
2701 	else
2702 		IMX464->cur_mclk = IMX464->cur_mode->mclk;
2703 	ret = clk_prepare_enable(IMX464->xvclk);
2704 	if (ret < 0) {
2705 		dev_err(dev, "Failed to enable xvclk\n");
2706 		return ret;
2707 	}
2708 	if (!IS_ERR(IMX464->reset_gpio))
2709 		gpiod_set_value_cansleep(IMX464->reset_gpio, 0);
2710 
2711 	ret = regulator_bulk_enable(IMX464_NUM_SUPPLIES, IMX464->supplies);
2712 	if (ret < 0) {
2713 		dev_err(dev, "Failed to enable regulators\n");
2714 		goto disable_clk;
2715 	}
2716 	usleep_range(15000, 16000);
2717 	if (!IS_ERR(IMX464->reset_gpio))
2718 		gpiod_set_value_cansleep(IMX464->reset_gpio, 1);
2719 
2720 	usleep_range(500, 1000);
2721 	if (!IS_ERR(IMX464->pwdn_gpio))
2722 		gpiod_set_value_cansleep(IMX464->pwdn_gpio, 1);
2723 
2724 	/* 8192 cycles prior to first SCCB transaction */
2725 	delay_us = IMX464_cal_delay(8192);
2726 	usleep_range(delay_us, delay_us * 2);
2727 
2728 	return 0;
2729 
2730 disable_clk:
2731 	clk_disable_unprepare(IMX464->xvclk);
2732 
2733 	return ret;
2734 }
2735 
__IMX464_power_off(struct IMX464 * IMX464)2736 static void __IMX464_power_off(struct IMX464 *IMX464)
2737 {
2738 	int ret;
2739 	struct device *dev = &IMX464->client->dev;
2740 
2741 	if (!IS_ERR(IMX464->pwdn_gpio))
2742 		gpiod_set_value_cansleep(IMX464->pwdn_gpio, 0);
2743 	clk_disable_unprepare(IMX464->xvclk);
2744 	if (!IS_ERR(IMX464->reset_gpio))
2745 		gpiod_set_value_cansleep(IMX464->reset_gpio, 0);
2746 	if (!IS_ERR_OR_NULL(IMX464->pins_sleep)) {
2747 		ret = pinctrl_select_state(IMX464->pinctrl,
2748 					   IMX464->pins_sleep);
2749 		if (ret < 0)
2750 			dev_err(dev, "could not set pins\n");
2751 	}
2752 	regulator_bulk_disable(IMX464_NUM_SUPPLIES, IMX464->supplies);
2753 	usleep_range(15000, 16000);
2754 }
2755 
IMX464_runtime_resume(struct device * dev)2756 static int IMX464_runtime_resume(struct device *dev)
2757 {
2758 	struct i2c_client *client = to_i2c_client(dev);
2759 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2760 	struct IMX464 *IMX464 = to_IMX464(sd);
2761 
2762 	return __IMX464_power_on(IMX464);
2763 }
2764 
IMX464_runtime_suspend(struct device * dev)2765 static int IMX464_runtime_suspend(struct device *dev)
2766 {
2767 	struct i2c_client *client = to_i2c_client(dev);
2768 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2769 	struct IMX464 *IMX464 = to_IMX464(sd);
2770 
2771 	__IMX464_power_off(IMX464);
2772 
2773 	return 0;
2774 }
2775 
2776 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
IMX464_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2777 static int IMX464_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2778 {
2779 	struct IMX464 *IMX464 = to_IMX464(sd);
2780 	struct v4l2_mbus_framefmt *try_fmt =
2781 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
2782 	const struct IMX464_mode *def_mode = &IMX464->support_modes[0];
2783 
2784 	mutex_lock(&IMX464->mutex);
2785 	/* Initialize try_fmt */
2786 	try_fmt->width = def_mode->width;
2787 	try_fmt->height = def_mode->height;
2788 	try_fmt->code = def_mode->bus_fmt;
2789 	try_fmt->field = V4L2_FIELD_NONE;
2790 
2791 	mutex_unlock(&IMX464->mutex);
2792 	/* No crop or compose */
2793 
2794 	return 0;
2795 }
2796 #endif
2797 
IMX464_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2798 static int IMX464_enum_frame_interval(struct v4l2_subdev *sd,
2799 	struct v4l2_subdev_pad_config *cfg,
2800 	struct v4l2_subdev_frame_interval_enum *fie)
2801 {
2802 	struct IMX464 *IMX464 = to_IMX464(sd);
2803 
2804 	if (fie->index >= IMX464->cfg_num)
2805 		return -EINVAL;
2806 
2807 	fie->code = IMX464->support_modes[fie->index].bus_fmt;
2808 	fie->width = IMX464->support_modes[fie->index].width;
2809 	fie->height = IMX464->support_modes[fie->index].height;
2810 	fie->interval = IMX464->support_modes[fie->index].max_fps;
2811 	fie->reserved[0] = IMX464->support_modes[fie->index].hdr_mode;
2812 	return 0;
2813 }
2814 
2815 #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
2816 #define DST_WIDTH 2560
2817 #define DST_HEIGHT 1520
2818 
2819 /*
2820  * The resolution of the driver configuration needs to be exactly
2821  * the same as the current output resolution of the sensor,
2822  * the input width of the isp needs to be 16 aligned,
2823  * the input height of the isp needs to be 8 aligned.
2824  * Can be cropped to standard resolution by this function,
2825  * otherwise it will crop out strange resolution according
2826  * to the alignment rules.
2827  */
IMX464_get_selection(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_selection * sel)2828 static int IMX464_get_selection(struct v4l2_subdev *sd,
2829 				struct v4l2_subdev_pad_config *cfg,
2830 				struct v4l2_subdev_selection *sel)
2831 {
2832 	struct IMX464 *IMX464 = to_IMX464(sd);
2833 
2834 	if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
2835 		sel->r.left = CROP_START(IMX464->cur_mode->width, DST_WIDTH);
2836 		sel->r.width = DST_WIDTH;
2837 		sel->r.top = CROP_START(IMX464->cur_mode->height, DST_HEIGHT);
2838 		sel->r.height = DST_HEIGHT;
2839 		return 0;
2840 	}
2841 	return -EINVAL;
2842 }
2843 
2844 static const struct dev_pm_ops IMX464_pm_ops = {
2845 	SET_RUNTIME_PM_OPS(IMX464_runtime_suspend,
2846 			   IMX464_runtime_resume, NULL)
2847 };
2848 
2849 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2850 static const struct v4l2_subdev_internal_ops IMX464_internal_ops = {
2851 	.open = IMX464_open,
2852 };
2853 #endif
2854 
2855 static const struct v4l2_subdev_core_ops IMX464_core_ops = {
2856 	.s_power = IMX464_s_power,
2857 	.ioctl = IMX464_ioctl,
2858 #ifdef CONFIG_COMPAT
2859 	.compat_ioctl32 = IMX464_compat_ioctl32,
2860 #endif
2861 };
2862 
2863 static const struct v4l2_subdev_video_ops IMX464_video_ops = {
2864 	.s_stream = IMX464_s_stream,
2865 	.g_frame_interval = IMX464_g_frame_interval,
2866 };
2867 
2868 static const struct v4l2_subdev_pad_ops IMX464_pad_ops = {
2869 	.enum_mbus_code = IMX464_enum_mbus_code,
2870 	.enum_frame_size = IMX464_enum_frame_sizes,
2871 	.enum_frame_interval = IMX464_enum_frame_interval,
2872 	.get_fmt = IMX464_get_fmt,
2873 	.set_fmt = IMX464_set_fmt,
2874 	.get_selection = IMX464_get_selection,
2875 	.get_mbus_config = IMX464_g_mbus_config,
2876 };
2877 
2878 static const struct v4l2_subdev_ops IMX464_subdev_ops = {
2879 	.core	= &IMX464_core_ops,
2880 	.video	= &IMX464_video_ops,
2881 	.pad	= &IMX464_pad_ops,
2882 };
2883 
IMX464_set_ctrl(struct v4l2_ctrl * ctrl)2884 static int IMX464_set_ctrl(struct v4l2_ctrl *ctrl)
2885 {
2886 	struct IMX464 *IMX464 = container_of(ctrl->handler,
2887 					     struct IMX464, ctrl_handler);
2888 	struct i2c_client *client = IMX464->client;
2889 	const struct IMX464_mode *mode = IMX464->cur_mode;
2890 	s64 max;
2891 	u32 vts = 0;
2892 	int ret = 0;
2893 	u32 shr0 = 0;
2894 	u32 flip = 0;
2895 
2896 	/* Propagate change of current control to all related controls */
2897 	switch (ctrl->id) {
2898 	case V4L2_CID_VBLANK:
2899 		/* Update max exposure while meeting expected vblanking */
2900 		if (mode->hdr_mode == NO_HDR) {
2901 			max = IMX464->cur_mode->height + ctrl->val - 3;
2902 			__v4l2_ctrl_modify_range(IMX464->exposure,
2903 						 IMX464->exposure->minimum, max,
2904 						 IMX464->exposure->step,
2905 						 IMX464->exposure->default_value);
2906 		}
2907 		break;
2908 	}
2909 
2910 	if (!pm_runtime_get_if_in_use(&client->dev))
2911 		return 0;
2912 
2913 	switch (ctrl->id) {
2914 	case V4L2_CID_EXPOSURE:
2915 		if (mode->hdr_mode == NO_HDR) {
2916 			shr0 = IMX464->cur_vts - ctrl->val;
2917 			ret = imx464_write_reg(IMX464->client, IMX464_LF_EXPO_REG_L,
2918 					IMX464_REG_VALUE_08BIT,
2919 					IMX464_FETCH_EXP_L(shr0));
2920 			ret |= imx464_write_reg(IMX464->client, IMX464_LF_EXPO_REG_M,
2921 					IMX464_REG_VALUE_08BIT,
2922 					IMX464_FETCH_EXP_M(shr0));
2923 			ret |= imx464_write_reg(IMX464->client, IMX464_LF_EXPO_REG_H,
2924 					IMX464_REG_VALUE_08BIT,
2925 					IMX464_FETCH_EXP_H(shr0));
2926 			dev_err(&client->dev, "set exposure 0x%x\n",
2927 				ctrl->val);
2928 		}
2929 		break;
2930 	case V4L2_CID_ANALOGUE_GAIN:
2931 		if (mode->hdr_mode == NO_HDR) {
2932 			ret = imx464_write_reg(IMX464->client, IMX464_LF_GAIN_REG_H,
2933 					IMX464_REG_VALUE_08BIT,
2934 					IMX464_FETCH_GAIN_H(ctrl->val));
2935 			ret |= imx464_write_reg(IMX464->client, IMX464_LF_GAIN_REG_L,
2936 					IMX464_REG_VALUE_08BIT,
2937 					IMX464_FETCH_GAIN_L(ctrl->val));
2938 			dev_err(&client->dev, "set analog gain 0x%x\n",
2939 				ctrl->val);
2940 		}
2941 		break;
2942 	case V4L2_CID_VBLANK:
2943 		vts = ctrl->val + IMX464->cur_mode->height;
2944 
2945 		if (mode->hdr_mode == HDR_X2) {
2946 			vts = (vts + 3) / 4 * 4;
2947 			IMX464->cur_vts = vts;
2948 			vts /= 2;
2949 		} else if (mode->hdr_mode == HDR_X3) {
2950 			vts = (vts + 5) / 6 * 6;
2951 			IMX464->cur_vts = vts;
2952 			vts /= 4;
2953 		} else {
2954 			IMX464->cur_vts = vts;
2955 		}
2956 		ret = imx464_write_reg(IMX464->client, IMX464_VTS_REG_L,
2957 				       IMX464_REG_VALUE_08BIT,
2958 				       IMX464_FETCH_VTS_L(vts));
2959 		ret |= imx464_write_reg(IMX464->client, IMX464_VTS_REG_M,
2960 				       IMX464_REG_VALUE_08BIT,
2961 				       IMX464_FETCH_VTS_M(vts));
2962 		ret |= imx464_write_reg(IMX464->client, IMX464_VTS_REG_H,
2963 				       IMX464_REG_VALUE_08BIT,
2964 				       IMX464_FETCH_VTS_H(vts));
2965 
2966 		dev_err(&client->dev, "set vts 0x%x\n",
2967 			vts);
2968 		break;
2969 	case V4L2_CID_HFLIP:
2970 		ret = imx464_write_reg(client,
2971 				       IMX464_GROUP_HOLD_REG,
2972 				       IMX464_REG_VALUE_08BIT,
2973 				       IMX464_GROUP_HOLD_START);
2974 		ret |= imx464_write_reg(IMX464->client, IMX464_HREVERSE_REG,
2975 				       IMX464_REG_VALUE_08BIT, !!ctrl->val);
2976 		ret |= imx464_write_reg(client,
2977 					IMX464_GROUP_HOLD_REG,
2978 					IMX464_REG_VALUE_08BIT,
2979 					IMX464_GROUP_HOLD_END);
2980 		break;
2981 	case V4L2_CID_VFLIP:
2982 		flip = ctrl->val;
2983 		ret = imx464_write_reg(client,
2984 				       IMX464_GROUP_HOLD_REG,
2985 				       IMX464_REG_VALUE_08BIT,
2986 				       IMX464_GROUP_HOLD_START);
2987 		ret |= imx464_write_reg(IMX464->client, IMX464_VREVERSE_REG,
2988 				IMX464_REG_VALUE_08BIT, !!flip);
2989 		if (flip) {
2990 			ret |= imx464_write_reg(IMX464->client, 0x3074,
2991 				IMX464_REG_VALUE_08BIT, 0x40);
2992 			ret |= imx464_write_reg(IMX464->client, 0x3075,
2993 				IMX464_REG_VALUE_08BIT, 0x06);
2994 			ret |= imx464_write_reg(IMX464->client, 0x3080,
2995 				IMX464_REG_VALUE_08BIT, 0xff);
2996 			ret |= imx464_write_reg(IMX464->client, 0x30ad,
2997 				IMX464_REG_VALUE_08BIT, 0x7e);
2998 			ret |= imx464_write_reg(IMX464->client, 0x30b6,
2999 				IMX464_REG_VALUE_08BIT, 0xff);
3000 			ret |= imx464_write_reg(IMX464->client, 0x30b7,
3001 				IMX464_REG_VALUE_08BIT, 0x01);
3002 			ret |= imx464_write_reg(IMX464->client, 0x30d8,
3003 				IMX464_REG_VALUE_08BIT, 0x45);
3004 			ret |= imx464_write_reg(IMX464->client, 0x3114,
3005 				IMX464_REG_VALUE_08BIT, 0x01);
3006 		} else {
3007 			ret |= imx464_write_reg(IMX464->client, 0x3074,
3008 				IMX464_REG_VALUE_08BIT, 0x3c);
3009 			ret |= imx464_write_reg(IMX464->client, 0x3075,
3010 				IMX464_REG_VALUE_08BIT, 0x00);
3011 			ret |= imx464_write_reg(IMX464->client, 0x3080,
3012 				IMX464_REG_VALUE_08BIT, 0x01);
3013 			ret |= imx464_write_reg(IMX464->client, 0x30ad,
3014 				IMX464_REG_VALUE_08BIT, 0x02);
3015 			ret |= imx464_write_reg(IMX464->client, 0x30b6,
3016 				IMX464_REG_VALUE_08BIT, 0x00);
3017 			ret |= imx464_write_reg(IMX464->client, 0x30b7,
3018 				IMX464_REG_VALUE_08BIT, 0x00);
3019 			ret |= imx464_write_reg(IMX464->client, 0x30d8,
3020 				IMX464_REG_VALUE_08BIT, 0x44);
3021 			ret |= imx464_write_reg(IMX464->client, 0x3114,
3022 				IMX464_REG_VALUE_08BIT, 0x02);
3023 		}
3024 		ret |= imx464_write_reg(client,
3025 					IMX464_GROUP_HOLD_REG,
3026 					IMX464_REG_VALUE_08BIT,
3027 					IMX464_GROUP_HOLD_END);
3028 		break;
3029 	default:
3030 		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
3031 			 __func__, ctrl->id, ctrl->val);
3032 		break;
3033 	}
3034 
3035 	pm_runtime_put(&client->dev);
3036 
3037 	return ret;
3038 }
3039 
3040 static const struct v4l2_ctrl_ops IMX464_ctrl_ops = {
3041 	.s_ctrl = IMX464_set_ctrl,
3042 };
3043 
IMX464_initialize_controls(struct IMX464 * IMX464)3044 static int IMX464_initialize_controls(struct IMX464 *IMX464)
3045 {
3046 	const struct IMX464_mode *mode;
3047 	struct v4l2_ctrl_handler *handler;
3048 	s64 exposure_max, vblank_def;
3049 	u32 h_blank;
3050 	u64 pixel_rate = 0;
3051 	int ret;
3052 
3053 	handler = &IMX464->ctrl_handler;
3054 	mode = IMX464->cur_mode;
3055 	ret = v4l2_ctrl_handler_init(handler, 8);
3056 	if (ret)
3057 		return ret;
3058 	handler->lock = &IMX464->mutex;
3059 
3060 	IMX464->link_freq = v4l2_ctrl_new_int_menu(handler,
3061 				NULL, V4L2_CID_LINK_FREQ,
3062 				1, 0, link_freq_menu_items);
3063 	__v4l2_ctrl_s_ctrl(IMX464->link_freq,
3064 			 IMX464->cur_mode->mipi_freq_idx);
3065 	pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
3066 		     IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
3067 	IMX464->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
3068 		V4L2_CID_PIXEL_RATE, 0, IMX464_10BIT_HDR2_PIXEL_RATE,
3069 		1, pixel_rate);
3070 
3071 	h_blank = mode->hts_def - mode->width;
3072 	IMX464->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
3073 				h_blank, h_blank, 1, h_blank);
3074 	if (IMX464->hblank)
3075 		IMX464->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
3076 
3077 	vblank_def = mode->vts_def - mode->height;
3078 	IMX464->vblank = v4l2_ctrl_new_std(handler, &IMX464_ctrl_ops,
3079 				V4L2_CID_VBLANK, vblank_def,
3080 				IMX464_VTS_MAX - mode->height,
3081 				1, vblank_def);
3082 	IMX464->cur_vts = mode->vts_def;
3083 
3084 	exposure_max = mode->vts_def - 3;
3085 	IMX464->exposure = v4l2_ctrl_new_std(handler, &IMX464_ctrl_ops,
3086 				V4L2_CID_EXPOSURE, IMX464_EXPOSURE_MIN,
3087 				exposure_max, IMX464_EXPOSURE_STEP,
3088 				mode->exp_def);
3089 
3090 	IMX464->anal_a_gain = v4l2_ctrl_new_std(handler, &IMX464_ctrl_ops,
3091 				V4L2_CID_ANALOGUE_GAIN, IMX464_GAIN_MIN,
3092 				IMX464_GAIN_MAX, IMX464_GAIN_STEP,
3093 				IMX464_GAIN_DEFAULT);
3094 	v4l2_ctrl_new_std(handler, &IMX464_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
3095 	v4l2_ctrl_new_std(handler, &IMX464_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
3096 
3097 	if (handler->error) {
3098 		ret = handler->error;
3099 		dev_err(&IMX464->client->dev,
3100 			"Failed to init controls(%d)\n", ret);
3101 		goto err_free_handler;
3102 	}
3103 
3104 	IMX464->subdev.ctrl_handler = handler;
3105 	IMX464->has_init_exp = false;
3106 	IMX464->isHCG = false;
3107 
3108 	return 0;
3109 
3110 err_free_handler:
3111 	v4l2_ctrl_handler_free(handler);
3112 
3113 	return ret;
3114 }
3115 
IMX464_check_sensor_id(struct IMX464 * IMX464,struct i2c_client * client)3116 static int IMX464_check_sensor_id(struct IMX464 *IMX464,
3117 				  struct i2c_client *client)
3118 {
3119 	struct device *dev = &IMX464->client->dev;
3120 	u32 id = 0;
3121 	int ret;
3122 
3123 	ret = IMX464_read_reg(client, IMX464_REG_CHIP_ID,
3124 			      IMX464_REG_VALUE_08BIT, &id);
3125 	if (id != CHIP_ID) {
3126 		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
3127 		return -ENODEV;
3128 	}
3129 
3130 	dev_info(dev, "Detected IMX464 id %06x\n", CHIP_ID);
3131 
3132 	return 0;
3133 }
3134 
IMX464_configure_regulators(struct IMX464 * IMX464)3135 static int IMX464_configure_regulators(struct IMX464 *IMX464)
3136 {
3137 	unsigned int i;
3138 
3139 	for (i = 0; i < IMX464_NUM_SUPPLIES; i++)
3140 		IMX464->supplies[i].supply = IMX464_supply_names[i];
3141 
3142 	return devm_regulator_bulk_get(&IMX464->client->dev,
3143 				       IMX464_NUM_SUPPLIES,
3144 				       IMX464->supplies);
3145 }
3146 
IMX464_probe(struct i2c_client * client,const struct i2c_device_id * id)3147 static int IMX464_probe(struct i2c_client *client,
3148 			const struct i2c_device_id *id)
3149 {
3150 	struct device *dev = &client->dev;
3151 	struct device_node *node = dev->of_node;
3152 	struct IMX464 *IMX464;
3153 	struct v4l2_subdev *sd;
3154 	struct device_node *endpoint;
3155 	char facing[2];
3156 	int ret;
3157 	u32 i, hdr_mode = 0;
3158 	const char *sync_mode_name = NULL;
3159 
3160 
3161 	dev_info(dev, "driver version: %02x.%02x.%02x",
3162 		DRIVER_VERSION >> 16,
3163 		(DRIVER_VERSION & 0xff00) >> 8,
3164 		DRIVER_VERSION & 0x00ff);
3165 
3166 	IMX464 = devm_kzalloc(dev, sizeof(*IMX464), GFP_KERNEL);
3167 	if (!IMX464)
3168 		return -ENOMEM;
3169 
3170 	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
3171 				   &IMX464->module_index);
3172 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
3173 				       &IMX464->module_facing);
3174 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
3175 				       &IMX464->module_name);
3176 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
3177 				       &IMX464->len_name);
3178 	if (ret) {
3179 		dev_err(dev, "could not get module information!\n");
3180 		return -EINVAL;
3181 	}
3182 
3183 	ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
3184 				      &sync_mode_name);
3185 	if (ret) {
3186 		IMX464->sync_mode = NO_SYNC_MODE;
3187 		dev_err(dev, "could not get sync mode!\n");
3188 	} else {
3189 		if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0)
3190 			IMX464->sync_mode = EXTERNAL_MASTER_MODE;
3191 		else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0)
3192 			IMX464->sync_mode = INTERNAL_MASTER_MODE;
3193 		else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0)
3194 			IMX464->sync_mode = SLAVE_MODE;
3195 	}
3196 
3197 	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
3198 			&hdr_mode);
3199 	if (ret) {
3200 		hdr_mode = NO_HDR;
3201 		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
3202 	}
3203 	IMX464->client = client;
3204 	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
3205 	if (!endpoint) {
3206 		dev_err(dev, "Failed to get endpoint\n");
3207 		return -EINVAL;
3208 	}
3209 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
3210 		&IMX464->bus_cfg);
3211 	if (ret) {
3212 		dev_err(dev, "Failed to get bus cfg\n");
3213 		return ret;
3214 	}
3215 	if (IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
3216 		IMX464->support_modes = supported_modes;
3217 		IMX464->cfg_num = ARRAY_SIZE(supported_modes);
3218 	} else {
3219 		IMX464->support_modes = supported_modes_2lane;
3220 		IMX464->cfg_num = ARRAY_SIZE(supported_modes_2lane);
3221 	}
3222 
3223 	for (i = 0; i < IMX464->cfg_num; i++) {
3224 		if (hdr_mode == IMX464->support_modes[i].hdr_mode) {
3225 			IMX464->cur_mode = &IMX464->support_modes[i];
3226 			break;
3227 		}
3228 	}
3229 	IMX464->cur_mode = &IMX464->support_modes[0];
3230 	IMX464->xvclk = devm_clk_get(dev, "xvclk");
3231 	if (IS_ERR(IMX464->xvclk)) {
3232 		dev_err(dev, "Failed to get xvclk\n");
3233 		return -EINVAL;
3234 	}
3235 
3236 	IMX464->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
3237 	if (IS_ERR(IMX464->reset_gpio))
3238 		dev_warn(dev, "Failed to get reset-gpios\n");
3239 
3240 	IMX464->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
3241 	if (IS_ERR(IMX464->pwdn_gpio))
3242 		dev_warn(dev, "Failed to get pwdn-gpios\n");
3243 
3244 	IMX464->pinctrl = devm_pinctrl_get(dev);
3245 	if (!IS_ERR(IMX464->pinctrl)) {
3246 		IMX464->pins_default =
3247 			pinctrl_lookup_state(IMX464->pinctrl,
3248 					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
3249 		if (IS_ERR(IMX464->pins_default))
3250 			dev_err(dev, "could not get default pinstate\n");
3251 
3252 		IMX464->pins_sleep =
3253 			pinctrl_lookup_state(IMX464->pinctrl,
3254 					     OF_CAMERA_PINCTRL_STATE_SLEEP);
3255 		if (IS_ERR(IMX464->pins_sleep))
3256 			dev_err(dev, "could not get sleep pinstate\n");
3257 	} else {
3258 		dev_err(dev, "no pinctrl\n");
3259 	}
3260 
3261 	ret = IMX464_configure_regulators(IMX464);
3262 	if (ret) {
3263 		dev_err(dev, "Failed to get power regulators\n");
3264 		return ret;
3265 	}
3266 
3267 	mutex_init(&IMX464->mutex);
3268 
3269 	sd = &IMX464->subdev;
3270 	v4l2_i2c_subdev_init(sd, client, &IMX464_subdev_ops);
3271 	ret = IMX464_initialize_controls(IMX464);
3272 	if (ret)
3273 		goto err_destroy_mutex;
3274 
3275 	ret = __IMX464_power_on(IMX464);
3276 	if (ret)
3277 		goto err_free_handler;
3278 
3279 	ret = IMX464_check_sensor_id(IMX464, client);
3280 	if (ret)
3281 		goto err_power_off;
3282 
3283 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
3284 	sd->internal_ops = &IMX464_internal_ops;
3285 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
3286 		     V4L2_SUBDEV_FL_HAS_EVENTS;
3287 #endif
3288 #if defined(CONFIG_MEDIA_CONTROLLER)
3289 	IMX464->pad.flags = MEDIA_PAD_FL_SOURCE;
3290 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
3291 	ret = media_entity_pads_init(&sd->entity, 1, &IMX464->pad);
3292 	if (ret < 0)
3293 		goto err_power_off;
3294 #endif
3295 
3296 	memset(facing, 0, sizeof(facing));
3297 	if (strcmp(IMX464->module_facing, "back") == 0)
3298 		facing[0] = 'b';
3299 	else
3300 		facing[0] = 'f';
3301 
3302 	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
3303 		 IMX464->module_index, facing,
3304 		 IMX464_NAME, dev_name(sd->dev));
3305 	ret = v4l2_async_register_subdev_sensor_common(sd);
3306 	if (ret) {
3307 		dev_err(dev, "v4l2 async register subdev failed\n");
3308 		goto err_clean_entity;
3309 	}
3310 
3311 	pm_runtime_set_active(dev);
3312 	pm_runtime_enable(dev);
3313 	pm_runtime_idle(dev);
3314 
3315 #ifdef USED_SYS_DEBUG
3316 	add_sysfs_interfaces(dev);
3317 #endif
3318 	return 0;
3319 
3320 err_clean_entity:
3321 #if defined(CONFIG_MEDIA_CONTROLLER)
3322 	media_entity_cleanup(&sd->entity);
3323 #endif
3324 err_power_off:
3325 	__IMX464_power_off(IMX464);
3326 err_free_handler:
3327 	v4l2_ctrl_handler_free(&IMX464->ctrl_handler);
3328 err_destroy_mutex:
3329 	mutex_destroy(&IMX464->mutex);
3330 
3331 	return ret;
3332 }
3333 
IMX464_remove(struct i2c_client * client)3334 static int IMX464_remove(struct i2c_client *client)
3335 {
3336 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
3337 	struct IMX464 *IMX464 = to_IMX464(sd);
3338 
3339 	v4l2_async_unregister_subdev(sd);
3340 #if defined(CONFIG_MEDIA_CONTROLLER)
3341 	media_entity_cleanup(&sd->entity);
3342 #endif
3343 	v4l2_ctrl_handler_free(&IMX464->ctrl_handler);
3344 	mutex_destroy(&IMX464->mutex);
3345 
3346 	pm_runtime_disable(&client->dev);
3347 	if (!pm_runtime_status_suspended(&client->dev))
3348 		__IMX464_power_off(IMX464);
3349 	pm_runtime_set_suspended(&client->dev);
3350 #ifdef USED_SYS_DEBUG
3351 	remove_sysfs_interfaces(&client->dev);
3352 #endif
3353 	return 0;
3354 }
3355 
3356 #if IS_ENABLED(CONFIG_OF)
3357 static const struct of_device_id IMX464_of_match[] = {
3358 	{ .compatible = "sony,imx464" },
3359 	{},
3360 };
3361 MODULE_DEVICE_TABLE(of, IMX464_of_match);
3362 #endif
3363 
3364 static const struct i2c_device_id IMX464_match_id[] = {
3365 	{ "sony,imx464", 0 },
3366 	{ },
3367 };
3368 
3369 static struct i2c_driver IMX464_i2c_driver = {
3370 	.driver = {
3371 		.name = IMX464_NAME,
3372 		.pm = &IMX464_pm_ops,
3373 		.of_match_table = of_match_ptr(IMX464_of_match),
3374 	},
3375 	.probe		= &IMX464_probe,
3376 	.remove		= &IMX464_remove,
3377 	.id_table	= IMX464_match_id,
3378 };
3379 
sensor_mod_init(void)3380 static int __init sensor_mod_init(void)
3381 {
3382 	return i2c_add_driver(&IMX464_i2c_driver);
3383 }
3384 
sensor_mod_exit(void)3385 static void __exit sensor_mod_exit(void)
3386 {
3387 	i2c_del_driver(&IMX464_i2c_driver);
3388 }
3389 
3390 device_initcall_sync(sensor_mod_init);
3391 module_exit(sensor_mod_exit);
3392 
3393 MODULE_DESCRIPTION("Sony IMX464 sensor driver");
3394 MODULE_LICENSE("GPL v2");
3395