xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/sc4210.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sc4210 driver
4  *
5  * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
6  *
7  * V0.0X01.0X00 first version.
8  */
9 
10 //#define DEBUG
11 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/delay.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/i2c.h>
16 #include <linux/module.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/of.h>
19 #include <linux/of_graph.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/sysfs.h>
22 #include <linux/pinctrl/consumer.h>
23 #include <linux/slab.h>
24 #include <linux/version.h>
25 #include <linux/rk-camera-module.h>
26 #include <linux/rk-preisp.h>
27 #include <media/media-entity.h>
28 #include <media/v4l2-common.h>
29 #include <media/v4l2-async.h>
30 #include <media/v4l2-device.h>
31 #include <media/v4l2-event.h>
32 #include <media/v4l2-fwnode.h>
33 #include <media/v4l2-ctrls.h>
34 #include <media/v4l2-subdev.h>
35 #include <media/v4l2-image-sizes.h>
36 #include <media/v4l2-mediabus.h>
37 #include <media/v4l2-subdev.h>
38 #include <linux/pinctrl/consumer.h>
39 #include <stdarg.h>
40 #include <linux/linkage.h>
41 #include <linux/types.h>
42 #include <linux/printk.h>
43 
44 #include <linux/rk-camera-module.h>
45 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x00)
46 
47 #ifndef V4L2_CID_DIGITAL_GAIN
48 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
49 #endif
50 
51 #define SC4210_LINK_FREQ_2LANE_LINEAR	303000000 // 607.5Mbps
52 #define SC4210_LINK_FREQ_2LANE_HDR2		540000000 // 1080Mbps
53 #define SC4210_LINK_FREQ_4LANE_LINEAR	202500000 // 405Mbps
54 #define SC4210_LINK_FREQ_4LANE_HDR2		364500000 // 729Mbps
55 
56 #define SC4210_PIXEL_RATES_2LANE_LINEAR	(SC4210_LINK_FREQ_2LANE_LINEAR / 10 * 2 * 2)
57 #define SC4210_PIXEL_RATES_2LANE_HDR2	(SC4210_LINK_FREQ_2LANE_HDR2 / 10 * 2 * 2)
58 #define SC4210_PIXEL_RATES_4LANE_LINEAR	(SC4210_LINK_FREQ_4LANE_LINEAR / 10 * 4 * 2)
59 #define SC4210_PIXEL_RATES_4LANE_HDR2	(SC4210_LINK_FREQ_4LANE_HDR2 / 10 * 4 * 2)
60 #define SC4210_MAX_PIXEL_RATE			(SC4210_LINK_FREQ_4LANE_HDR2 / 10 * 4 * 2)
61 
62 #define SC4210_XVCLK_FREQ			27000000
63 
64 #define SC4210_CHIP_ID				0x4210
65 #define SC4210_REG_CHIP_ID			0x3107
66 
67 #define SC4210_REG_CTRL_MODE		0x0100
68 #define SC4210_MODE_SW_STANDBY		0x0
69 #define SC4210_MODE_STREAMING		BIT(0)
70 
71 #define SC4210_REG_EXPOSURE_H		0x3e00
72 #define SC4210_REG_EXPOSURE_M		0x3e01
73 #define SC4210_REG_EXPOSURE_L		0x3e02
74 #define	SC4210_EXPOSURE_MIN			2
75 #define	SC4210_EXPOSURE_STEP		1
76 
77 #define SC4210_REG_DIG_GAIN			0x3e06
78 #define SC4210_REG_DIG_FINE_GAIN	0x3e07
79 #define SC4210_REG_ANA_GAIN			0x3e08
80 #define SC4210_REG_ANA_FINE_GAIN	0x3e09
81 #define SC4210_GAIN_MIN				1000
82 #define SC4210_GAIN_MAX				(43.65 * 32 * 1000)
83 #define SC4210_GAIN_STEP			1
84 #define SC4210_GAIN_DEFAULT			1000
85 
86 #define SC4210_REG_VTS_H			0x320e
87 #define SC4210_REG_VTS_L			0x320f
88 #define SC4210_VTS_MAX				0x7fff
89 
90 #define SC4210_SOFTWARE_RESET_REG	0x0103
91 
92 // short frame exposure
93 #define SC4210_REG_SHORT_EXPOSURE_H	0x3e22
94 #define SC4210_REG_SHORT_EXPOSURE_M	0x3e04
95 #define SC4210_REG_SHORT_EXPOSURE_L	0x3e05
96 #define SC4210_REG_MAX_SHORT_EXP_H	0x3e23
97 #define SC4210_REG_MAX_SHORT_EXP_L	0x3e24
98 #define SC4210_HDR_EXPOSURE_MIN		5
99 #define SC4210_HDR_EXPOSURE_STEP	4
100 #define SC4210_MAX_SHORT_EXPOSURE	608
101 
102 // short frame gain
103 #define SC4210_REG_SDIG_GAIN		0x3e10
104 #define SC4210_REG_SDIG_FINE_GAIN	0x3e11
105 #define SC4210_REG_SANA_GAIN		0x3e12
106 #define SC4210_REG_SANA_FINE_GAIN	0x3e13
107 
108 //group hold
109 #define SC4210_GROUP_UPDATE_ADDRESS	0x3800
110 #define SC4210_GROUP_UPDATE_START_DATA	0x00
111 #define SC4210_GROUP_UPDATE_END_DATA	0x10
112 #define SC4210_GROUP_UPDATE_LAUNCH	0x40
113 
114 #define SC4210_FLIP_MIRROR_REG		0x3221
115 #define SC4210_FLIP_MASK			0x60
116 #define SC4210_MIRROR_MASK			0x06
117 
118 #define REG_NULL			0xFFFF
119 
120 #define SC4210_REG_VALUE_08BIT		1
121 #define SC4210_REG_VALUE_16BIT		2
122 #define SC4210_REG_VALUE_24BIT		3
123 
124 #define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
125 #define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
126 #define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
127 
128 #define SC4210_NAME			"sc4210"
129 
130 #define SC4210_FETCH_EXP_H(VAL)		(((VAL) >> 12) & 0xF)
131 #define SC4210_FETCH_EXP_M(VAL)		(((VAL) >> 4) & 0xFF)
132 #define SC4210_FETCH_EXP_L(VAL)		(((VAL) & 0xF) << 4)
133 
134 static const char * const sc4210_supply_names[] = {
135 	"avdd",		/* Analog power */
136 	"dovdd",	/* Digital I/O power */
137 	"dvdd",		/* Digital core power */
138 };
139 
140 #define sc4210_NUM_SUPPLIES ARRAY_SIZE(sc4210_supply_names)
141 struct regval {
142 	u16 addr;
143 	u8 val;
144 };
145 
146 struct sc4210_mode {
147 	u32 bus_fmt;
148 	u32 width;
149 	u32 height;
150 	struct v4l2_fract max_fps;
151 	u32 hts_def;
152 	u32 vts_def;
153 	u32 exp_def;
154 	u32 mipi_freq_idx;
155 	u32 bpp;
156 	const struct regval *reg_list;
157 	u32 hdr_mode;
158 	u32 vc[PAD_MAX];
159 };
160 
161 struct sc4210 {
162 		struct i2c_client	*client;
163 	struct clk		*xvclk;
164 	struct gpio_desc	*reset_gpio;
165 	struct gpio_desc	*pwdn_gpio;
166 	struct regulator_bulk_data supplies[sc4210_NUM_SUPPLIES];
167 	struct pinctrl		*pinctrl;
168 	struct pinctrl_state	*pins_default;
169 	struct pinctrl_state	*pins_sleep;
170 
171 	struct v4l2_subdev	subdev;
172 	struct media_pad	pad;
173 	struct v4l2_ctrl_handler ctrl_handler;
174 	struct v4l2_ctrl	*exposure;
175 	struct v4l2_ctrl	*anal_gain;
176 	struct v4l2_ctrl	*digi_gain;
177 	struct v4l2_ctrl	*hblank;
178 	struct v4l2_ctrl	*vblank;
179 	struct v4l2_ctrl	*pixel_rate;
180 	struct v4l2_ctrl	*link_freq;
181 	struct mutex		mutex;
182 	bool			streaming;
183 	bool			power_on;
184 	const struct sc4210_mode *support_modes;
185 	const struct sc4210_mode *cur_mode;
186 	struct v4l2_fract	cur_fps;
187 	u32			support_modes_num;
188 	unsigned int		lane_num;
189 	u32			module_index;
190 	const char		*module_facing;
191 	const char		*module_name;
192 	const char		*len_name;
193 	bool			has_init_exp;
194 	struct preisp_hdrae_exp_s init_hdrae_exp;
195 	u32			cur_vts;
196 };
197 
198 #define to_sc4210(sd) container_of(sd, struct sc4210, subdev)
199 
200 /*
201  * sc4210 27Mhz
202  * max_framerate 30fps
203  * mipi_datarate per lane 405Mbps, 4lane
204  */
205 static const struct regval sc4210_linear_10_30fps_2560x1440_4lane_regs[] = {
206 	{0x0103, 0x01},
207 	{0x0100, 0x00},
208 	{0x36e9, 0x80},
209 	{0x36f9, 0x80},
210 	{0x3001, 0x07},
211 	{0x3002, 0xc0},
212 	{0x300a, 0x2c},
213 	{0x300f, 0x00},
214 	{0x3018, 0x73},
215 	{0x301f, 0x3b},
216 	{0x3031, 0x0a},
217 	{0x3038, 0x22},
218 	{0x320c, 0x05},
219 	{0x320d, 0x46},
220 	{0x3220, 0x10},
221 	{0x3225, 0x01},
222 	{0x3227, 0x03},
223 	{0x3229, 0x08},
224 	{0x3231, 0x01},
225 	{0x3241, 0x02},
226 	{0x3243, 0x03},
227 	{0x3249, 0x17},
228 	{0x3251, 0x08},
229 	{0x3253, 0x08},
230 	{0x325e, 0x00},
231 	{0x325f, 0x00},
232 	{0x3273, 0x01},
233 	{0x3301, 0x28},
234 	{0x3302, 0x18},
235 	{0x3000, 0x00},
236 	{0x3304, 0x20},
237 	{0x3305, 0x00},
238 	{0x3306, 0x74},
239 	{0x3308, 0x10},
240 	{0x3309, 0x40},
241 	{0x330a, 0x00},
242 	{0x330b, 0xe8},
243 	{0x330e, 0x18},
244 	{0x3312, 0x02},
245 	{0x3314, 0x84},
246 	{0x331e, 0x19},
247 	{0x331f, 0x39},
248 	{0x3320, 0x05},
249 	{0x3338, 0x10},
250 	{0x334c, 0x10},
251 	{0x335d, 0x20},
252 	{0x3366, 0x92},
253 	{0x3367, 0x08},
254 	{0x3368, 0x05},
255 	{0x3369, 0xdc},
256 	{0x336a, 0x0b},
257 	{0x336b, 0xb8},
258 	{0x336c, 0xc2},
259 	{0x337a, 0x08},
260 	{0x337b, 0x10},
261 	{0x337e, 0x40},
262 	{0x33a3, 0x0c},
263 	{0x33e0, 0xa0},
264 	{0x33e1, 0x08},
265 	{0x33e2, 0x00},
266 	{0x33e3, 0x10},
267 	{0x33e4, 0x10},
268 	{0x33e5, 0x00},
269 	{0x33e6, 0x10},
270 	{0x33e7, 0x10},
271 	{0x33e8, 0x00},
272 	{0x33e9, 0x10},
273 	{0x33ea, 0x16},
274 	{0x33eb, 0x00},
275 	{0x33ec, 0x10},
276 	{0x33ed, 0x18},
277 	{0x33ee, 0xa0},
278 	{0x33ef, 0x08},
279 	{0x33f4, 0x00},
280 	{0x33f5, 0x10},
281 	{0x33f6, 0x10},
282 	{0x33f7, 0x00},
283 	{0x33f8, 0x10},
284 	{0x33f9, 0x10},
285 	{0x33fa, 0x00},
286 	{0x33fb, 0x10},
287 	{0x33fc, 0x16},
288 	{0x33fd, 0x00},
289 	{0x33fe, 0x10},
290 	{0x33ff, 0x18},
291 	{0x360f, 0x05},
292 	{0x3622, 0xff},
293 	{0x3624, 0x07},
294 	{0x3625, 0x02},
295 	{0x3630, 0xc4},
296 	{0x3631, 0x80},
297 	{0x3632, 0x88},
298 	{0x3633, 0x22},
299 	{0x3634, 0x64},
300 	{0x3635, 0x40},
301 	{0x3636, 0x20},
302 	{0x3638, 0x28},
303 	{0x363b, 0x03},
304 	{0x363c, 0x08},
305 	{0x363d, 0x08},
306 	{0x366e, 0x04},
307 	{0x3670, 0x48},
308 	{0x3671, 0xff},
309 	{0x3672, 0x1f},
310 	{0x3673, 0x1f},
311 	{0x367a, 0x40},
312 	{0x367b, 0x40},
313 	{0x3690, 0x42},
314 	{0x3691, 0x44},
315 	{0x3692, 0x44},
316 	{0x3699, 0x80},
317 	{0x369a, 0x9f},
318 	{0x369b, 0x9f},
319 	{0x369c, 0x40},
320 	{0x369d, 0x40},
321 	{0x36a2, 0x40},
322 	{0x36a3, 0x40},
323 	{0x36cc, 0x2c},
324 	{0x36cd, 0x30},
325 	{0x36ce, 0x30},
326 	{0x36d0, 0x20},
327 	{0x36d1, 0x40},
328 	{0x36d2, 0x40},
329 	{0x36ea, 0x36},
330 	{0x36eb, 0x16},
331 	{0x36ec, 0x03},
332 	{0x36ed, 0x0c},
333 	{0x36fa, 0x37},
334 	{0x36fb, 0x14},
335 	{0x36fc, 0x00},
336 	{0x36fd, 0x2c},
337 	{0x3817, 0x20},
338 	{0x3905, 0xd8},
339 	{0x3908, 0x11},
340 	{0x391b, 0x80},
341 	{0x391c, 0x0f},
342 	{0x391d, 0x21},
343 	{0x3933, 0x27},
344 	{0x3934, 0xf5},
345 	{0x3935, 0x80},
346 	{0x3936, 0x1f},
347 	{0x3940, 0x6e},
348 	{0x3942, 0x07},
349 	{0x3943, 0xf6},
350 	{0x3980, 0x00},
351 	{0x3981, 0x12},
352 	{0x3982, 0x00},
353 	{0x3983, 0x07},
354 	{0x3984, 0x00},
355 	{0x3985, 0x03},
356 	{0x3986, 0x00},
357 	{0x3987, 0x04},
358 	{0x3988, 0x00},
359 	{0x3989, 0x01},
360 	{0x398a, 0x00},
361 	{0x398b, 0x03},
362 	{0x398c, 0x00},
363 	{0x398d, 0x06},
364 	{0x398e, 0x00},
365 	{0x398f, 0x0d},
366 	{0x3990, 0x00},
367 	{0x3991, 0x12},
368 	{0x3992, 0x00},
369 	{0x3993, 0x09},
370 	{0x3994, 0x00},
371 	{0x3995, 0x02},
372 	{0x3996, 0x00},
373 	{0x3997, 0x04},
374 	{0x3998, 0x00},
375 	{0x3999, 0x0a},
376 	{0x399a, 0x00},
377 	{0x399b, 0x10},
378 	{0x399c, 0x00},
379 	{0x399d, 0x16},
380 	{0x399e, 0x00},
381 	{0x399f, 0x1f},
382 	{0x39a0, 0x02},
383 	{0x39a1, 0x04},
384 	{0x39a2, 0x10},
385 	{0x39a3, 0x13},
386 	{0x39a4, 0x97},
387 	{0x39a5, 0x43},
388 	{0x39a6, 0x20},
389 	{0x39a7, 0x05},
390 	{0x39a8, 0x23},
391 	{0x39a9, 0x43},
392 	{0x39aa, 0x85},
393 	{0x39ab, 0x95},
394 	{0x39ac, 0x24},
395 	{0x39ad, 0x18},
396 	{0x39ae, 0x11},
397 	{0x39af, 0x04},
398 	{0x39b9, 0x00},
399 	{0x39ba, 0x19},
400 	{0x39bb, 0xba},
401 	{0x39bc, 0x00},
402 	{0x39bd, 0x05},
403 	{0x39be, 0x99},
404 	{0x39bf, 0x00},
405 	{0x39c0, 0x00},
406 	{0x39c5, 0x71},
407 	{0x3e00, 0x00},
408 	{0x3e01, 0xbb},
409 	{0x3e02, 0x40},
410 	{0x3e03, 0x0b},
411 	{0x3e06, 0x00},
412 	{0x3e07, 0x80},
413 	{0x3e08, 0x03},
414 	{0x3e09, 0x40},
415 	{0x3e0e, 0x6a},
416 	{0x3e26, 0x40},
417 	{0x4407, 0xb0},
418 	{0x4418, 0x0b},
419 	{0x4501, 0xb4},
420 	{0x4509, 0x20},
421 	{0x4603, 0x00},
422 	{0x4800, 0x24},
423 	{0x4837, 0x28},
424 	{0x5000, 0x0e},
425 	{0x550f, 0x20},
426 	{0x5784, 0x10},
427 	{0x5785, 0x08},
428 	{0x5787, 0x06},
429 	{0x5788, 0x06},
430 	{0x5789, 0x00},
431 	{0x578a, 0x06},
432 	{0x578b, 0x06},
433 	{0x578c, 0x00},
434 	{0x5790, 0x10},
435 	{0x5791, 0x10},
436 	{0x5792, 0x00},
437 	{0x5793, 0x10},
438 	{0x5794, 0x10},
439 	{0x5795, 0x00},
440 	{0x57c4, 0x10},
441 	{0x57c5, 0x08},
442 	{0x57c7, 0x06},
443 	{0x57c8, 0x06},
444 	{0x57c9, 0x00},
445 	{0x57ca, 0x06},
446 	{0x57cb, 0x06},
447 	{0x57cc, 0x00},
448 	{0x57d0, 0x10},
449 	{0x57d1, 0x10},
450 	{0x57d2, 0x00},
451 	{0x57d3, 0x10},
452 	{0x57d4, 0x10},
453 	{0x57d5, 0x00},
454 	{0x36e9, 0x27},
455 	{0x36f9, 0x20},
456 	//{0x0100, 0x01},
457 	{REG_NULL, 0x0},
458 };
459 
460 /*
461  * sc4210 27Mhz
462  * max_framerate 30fps
463  * mipi_datarate per lane 729Mbps, 4lane
464  */
465 static const struct regval sc4210_hdr_10_30fps_2560x1440_4lane_regs[] = {
466 	{0x0103, 0x01},
467 	{0x0100, 0x00},
468 	{0x36e9, 0x80},
469 	{0x36f9, 0x80},
470 	{0x3001, 0x07},
471 	{0x3002, 0xc0},
472 	{0x300a, 0x2c},
473 	{0x300f, 0x00},
474 	{0x3018, 0x73},
475 	{0x301f, 0x3e},
476 	{0x3031, 0x0a},
477 	{0x3038, 0x22},
478 	{0x3207, 0xa7},
479 	{0x320c, 0x05},
480 	{0x320d, 0x58},
481 	{0x320e, 0x0b},
482 	{0x320f, 0x90},
483 	{0x3213, 0x04},
484 	{0x3220, 0x50},
485 	{0x3225, 0x01},
486 	{0x3227, 0x03},
487 	{0x3229, 0x08},
488 	{0x3231, 0x01},
489 	{0x3241, 0x02},
490 	{0x3243, 0x03},
491 	{0x3249, 0x17},
492 	{0x3250, 0x3f},
493 	{0x3251, 0x08},
494 	{0x3253, 0x10},
495 	{0x325e, 0x00},
496 	{0x3000, 0x00},
497 	{0x325f, 0x00},
498 	{0x3273, 0x01},
499 	{0x3301, 0x15},
500 	{0x3302, 0x18},
501 	{0x3304, 0x20},
502 	{0x3305, 0x00},
503 	{0x3306, 0x78},
504 	{0x3308, 0x10},
505 	{0x3309, 0x50},
506 	{0x330a, 0x00},
507 	{0x330b, 0xe8},
508 	{0x330e, 0x20},
509 	{0x3312, 0x02},
510 	{0x3314, 0x84},
511 	{0x331e, 0x19},
512 	{0x331f, 0x49},
513 	{0x3320, 0x05},
514 	{0x3338, 0x10},
515 	{0x334c, 0x10},
516 	{0x335d, 0x20},
517 	{0x335e, 0x02},
518 	{0x335f, 0x04},
519 	{0x3360, 0x20},
520 	{0x3362, 0x72},
521 	{0x3364, 0x1e},
522 	{0x3366, 0x92},
523 	{0x3367, 0x08},
524 	{0x3368, 0x0a},
525 	{0x3369, 0xd4},
526 	{0x336a, 0x15},
527 	{0x336b, 0xa8},
528 	{0x336c, 0xc2},
529 	{0x337a, 0x08},
530 	{0x337b, 0x10},
531 	{0x337c, 0x06},
532 	{0x337d, 0x0a},
533 	{0x337e, 0x40},
534 	{0x3390, 0x08},
535 	{0x3391, 0x18},
536 	{0x3392, 0x38},
537 	{0x3393, 0x13},
538 	{0x3394, 0x24},
539 	{0x3395, 0x24},
540 	{0x3396, 0x08},
541 	{0x3397, 0x18},
542 	{0x3398, 0x38},
543 	{0x3399, 0x11},
544 	{0x339a, 0x14},
545 	{0x339b, 0x24},
546 	{0x339c, 0x24},
547 	{0x33a2, 0x08},
548 	{0x33a3, 0x0c},
549 	{0x33e0, 0xa0},
550 	{0x33e1, 0x08},
551 	{0x33e2, 0x00},
552 	{0x33e3, 0x10},
553 	{0x33e4, 0x10},
554 	{0x33e5, 0x00},
555 	{0x33e6, 0x10},
556 	{0x33e7, 0x10},
557 	{0x33e8, 0x00},
558 	{0x33e9, 0x10},
559 	{0x33ea, 0x16},
560 	{0x33eb, 0x00},
561 	{0x33ec, 0x10},
562 	{0x33ed, 0x18},
563 	{0x33ee, 0xa0},
564 	{0x33ef, 0x08},
565 	{0x33f4, 0x00},
566 	{0x33f5, 0x10},
567 	{0x33f6, 0x10},
568 	{0x33f7, 0x00},
569 	{0x33f8, 0x10},
570 	{0x33f9, 0x10},
571 	{0x33fa, 0x00},
572 	{0x33fb, 0x10},
573 	{0x33fc, 0x16},
574 	{0x33fd, 0x00},
575 	{0x33fe, 0x10},
576 	{0x33ff, 0x18},
577 	{0x360f, 0x05},
578 	{0x3622, 0xff},
579 	{0x3624, 0x07},
580 	{0x3625, 0x0a},
581 	{0x3630, 0xc4},
582 	{0x3631, 0x80},
583 	{0x3632, 0x88},
584 	{0x3633, 0x42},
585 	{0x3634, 0x64},
586 	{0x3635, 0x20},
587 	{0x3636, 0x20},
588 	{0x3638, 0x28},
589 	{0x363b, 0x03},
590 	{0x363c, 0x06},
591 	{0x363d, 0x06},
592 	{0x366e, 0x04},
593 	{0x3670, 0x4a},
594 	{0x3671, 0xff},
595 	{0x3672, 0x9f},
596 	{0x3673, 0x9f},
597 	{0x3674, 0xc4},
598 	{0x3675, 0xc4},
599 	{0x3676, 0xb8},
600 	{0x367a, 0x40},
601 	{0x367b, 0x48},
602 	{0x367c, 0x40},
603 	{0x367d, 0x48},
604 	{0x3690, 0x43},
605 	{0x3691, 0x55},
606 	{0x3692, 0x66},
607 	{0x3699, 0x8c},
608 	{0x369a, 0x96},
609 	{0x369b, 0x9f},
610 	{0x369c, 0x40},
611 	{0x369d, 0x48},
612 	{0x36a2, 0x40},
613 	{0x36a3, 0x48},
614 	{0x36cc, 0x2c},
615 	{0x36cd, 0x30},
616 	{0x36ce, 0x30},
617 	{0x36d0, 0x20},
618 	{0x36d1, 0x40},
619 	{0x36d2, 0x40},
620 	{0x36ea, 0x37},
621 	{0x36eb, 0x06},
622 	{0x36ec, 0x03},
623 	{0x36ed, 0x0c},
624 	{0x36fa, 0x37},
625 	{0x36fb, 0x04},
626 	{0x36fc, 0x00},
627 	{0x36fd, 0x2c},
628 	{0x3817, 0x20},
629 	{0x3905, 0x98},
630 	{0x3908, 0x11},
631 	{0x391b, 0x80},
632 	{0x391c, 0x0f},
633 	{0x391d, 0x21},
634 	{0x3933, 0x1f},
635 	{0x3934, 0xff},
636 	{0x3935, 0x80},
637 	{0x3936, 0x1f},
638 	{0x393e, 0x01},
639 	{0x3940, 0x60},
640 	{0x3942, 0x04},
641 	{0x3943, 0xd0},
642 	{0x3980, 0x00},
643 	{0x3981, 0x30},
644 	{0x3982, 0x00},
645 	{0x3983, 0x2c},
646 	{0x3984, 0x00},
647 	{0x3985, 0x15},
648 	{0x3986, 0x00},
649 	{0x3987, 0x10},
650 	{0x3988, 0x00},
651 	{0x3989, 0x30},
652 	{0x398a, 0x00},
653 	{0x398b, 0x28},
654 	{0x398c, 0x00},
655 	{0x398d, 0x30},
656 	{0x398e, 0x00},
657 	{0x398f, 0x70},
658 	{0x3990, 0x0a},
659 	{0x3991, 0x00},
660 	{0x3992, 0x00},
661 	{0x3993, 0x60},
662 	{0x3994, 0x00},
663 	{0x3995, 0x30},
664 	{0x3996, 0x00},
665 	{0x3997, 0x10},
666 	{0x3998, 0x00},
667 	{0x3999, 0x1c},
668 	{0x399a, 0x00},
669 	{0x399b, 0x48},
670 	{0x399c, 0x00},
671 	{0x399d, 0x90},
672 	{0x399e, 0x00},
673 	{0x399f, 0xc0},
674 	{0x39a0, 0x14},
675 	{0x39a1, 0x28},
676 	{0x39a2, 0x48},
677 	{0x39a3, 0x70},
678 	{0x39a4, 0x18},
679 	{0x39a5, 0x04},
680 	{0x39a6, 0x08},
681 	{0x39a7, 0x04},
682 	{0x39a8, 0x01},
683 	{0x39a9, 0x14},
684 	{0x39aa, 0x28},
685 	{0x39ab, 0x50},
686 	{0x39ac, 0x30},
687 	{0x39ad, 0x20},
688 	{0x39ae, 0x10},
689 	{0x39af, 0x08},
690 	{0x39b9, 0x00},
691 	{0x39ba, 0x00},
692 	{0x39bb, 0x00},
693 	{0x39bc, 0x00},
694 	{0x39bd, 0x58},
695 	{0x39be, 0xc0},
696 	{0x39bf, 0x00},
697 	{0x39c0, 0x00},
698 	{0x39c5, 0x41},
699 	{0x3c09, 0x4a},
700 	{0x3c10, 0x04},
701 	{0x3c11, 0x20},
702 	{0x3c12, 0x04},
703 	{0x3c13, 0x20},
704 	{0x3c14, 0x0f},
705 	{0x3e00, 0x01},
706 	{0x3e01, 0x5a},
707 	{0x3e02, 0x00},
708 	{0x3e03, 0x0b},
709 	{0x3e04, 0x15},
710 	{0x3e05, 0xa0},
711 	{0x3e06, 0x00},
712 	{0x3e07, 0x80},
713 	{0x3e08, 0x03},
714 	{0x3e09, 0x40},
715 	{0x3e0e, 0x6a},
716 	{0x3e10, 0x00},
717 	{0x3e11, 0x80},
718 	{0x3e12, 0x03},
719 	{0x3e13, 0x40},
720 	{0x3e23, 0x00},
721 	{0x3e24, 0xbc},
722 	{0x3e26, 0x40},
723 	{0x4401, 0x0b},
724 	{0x4407, 0xb0},
725 	{0x4418, 0x16},
726 	{0x4501, 0xa4},
727 	{0x4509, 0x08},
728 	{0x4603, 0x00},
729 	{0x4800, 0x24},
730 	{0x4816, 0x11},
731 	{0x4819, 0x40},
732 	{0x4829, 0x01},
733 	{0x4837, 0x16},
734 	{0x5000, 0x0e},
735 	{0x550f, 0x20},
736 	{0x5784, 0x10},
737 	{0x5785, 0x08},
738 	{0x5787, 0x06},
739 	{0x5788, 0x06},
740 	{0x5789, 0x00},
741 	{0x578a, 0x06},
742 	{0x578b, 0x06},
743 	{0x578c, 0x00},
744 	{0x5790, 0x10},
745 	{0x5791, 0x10},
746 	{0x5792, 0x00},
747 	{0x5793, 0x10},
748 	{0x5794, 0x10},
749 	{0x5795, 0x00},
750 	{0x57c4, 0x10},
751 	{0x57c5, 0x08},
752 	{0x57c7, 0x06},
753 	{0x57c8, 0x06},
754 	{0x57c9, 0x00},
755 	{0x57ca, 0x06},
756 	{0x57cb, 0x06},
757 	{0x57cc, 0x00},
758 	{0x57d0, 0x10},
759 	{0x57d1, 0x10},
760 	{0x57d2, 0x00},
761 	{0x57d3, 0x10},
762 	{0x57d4, 0x10},
763 	{0x57d5, 0x00},
764 	{0x36e9, 0x27},
765 	{0x36f9, 0x20},
766 	//{0x0100, 0x01},
767 	{REG_NULL, 0x00},
768 };
769 
770 /*
771  * Xclk 27Mhz
772  * max_framerate 30fps
773  * mipi_datarate per lane 607.5Mbps, 2lane
774  */
775 static const struct regval sc4210_liner_10_30fps_2560x1440_2lane_regs[] = {
776 	{0x0103, 0x01},
777 	{0x0100, 0x00},
778 	{0x36e9, 0xd1},
779 	{0x36f9, 0xd1},
780 	{0x3001, 0x07},
781 	{0x3002, 0xc0},
782 	{0x300a, 0x2c},
783 	{0x300f, 0x00},
784 	{0x3018, 0x33},
785 	{0x301f, 0x21},
786 	{0x3031, 0x0a},
787 	{0x3038, 0x22},
788 	{0x320c, 0x05},
789 	{0x320d, 0x46},
790 	{0x3220, 0x10},
791 	{0x3225, 0x01},
792 	{0x3227, 0x03},
793 	{0x3229, 0x08},
794 	{0x3231, 0x01},
795 	{0x3241, 0x02},
796 	{0x3243, 0x03},
797 	{0x3249, 0x17},
798 	{0x3251, 0x08},
799 	{0x3253, 0x08},
800 	{0x325e, 0x00},
801 	{0x325f, 0x00},
802 	{0x3273, 0x01},
803 	{0x3301, 0x28},
804 	{0x3302, 0x18},
805 	{0x3304, 0x20},
806 	{0x3000, 0x00},
807 	{0x3305, 0x00},
808 	{0x3306, 0x74},
809 	{0x3308, 0x10},
810 	{0x3309, 0x40},
811 	{0x330a, 0x00},
812 	{0x330b, 0xe8},
813 	{0x330e, 0x18},
814 	{0x3312, 0x02},
815 	{0x3314, 0x84},
816 	{0x331e, 0x19},
817 	{0x331f, 0x39},
818 	{0x3320, 0x05},
819 	{0x3338, 0x10},
820 	{0x334c, 0x10},
821 	{0x335d, 0x20},
822 	{0x3366, 0x92},
823 	{0x3367, 0x08},
824 	{0x3368, 0x05},
825 	{0x3369, 0xdc},
826 	{0x336a, 0x0b},
827 	{0x336b, 0xb8},
828 	{0x336c, 0xc2},
829 	{0x337a, 0x08},
830 	{0x337b, 0x10},
831 	{0x337e, 0x40},
832 	{0x33a3, 0x0c},
833 	{0x33e0, 0xa0},
834 	{0x33e1, 0x08},
835 	{0x33e2, 0x00},
836 	{0x33e3, 0x10},
837 	{0x33e4, 0x10},
838 	{0x33e5, 0x00},
839 	{0x33e6, 0x10},
840 	{0x33e7, 0x10},
841 	{0x33e8, 0x00},
842 	{0x33e9, 0x10},
843 	{0x33ea, 0x16},
844 	{0x33eb, 0x00},
845 	{0x33ec, 0x10},
846 	{0x33ed, 0x18},
847 	{0x33ee, 0xa0},
848 	{0x33ef, 0x08},
849 	{0x33f4, 0x00},
850 	{0x33f5, 0x10},
851 	{0x33f6, 0x10},
852 	{0x33f7, 0x00},
853 	{0x33f8, 0x10},
854 	{0x33f9, 0x10},
855 	{0x33fa, 0x00},
856 	{0x33fb, 0x10},
857 	{0x33fc, 0x16},
858 	{0x33fd, 0x00},
859 	{0x33fe, 0x10},
860 	{0x33ff, 0x18},
861 	{0x360f, 0x05},
862 	{0x3622, 0xff},
863 	{0x3624, 0x07},
864 	{0x3625, 0x02},
865 	{0x3630, 0xc4},
866 	{0x3631, 0x80},
867 	{0x3632, 0x88},
868 	{0x3633, 0x22},
869 	{0x3634, 0x64},
870 	{0x3635, 0x20},
871 	{0x3636, 0x20},
872 	{0x3638, 0x28},
873 	{0x363b, 0x03},
874 	{0x363c, 0x06},
875 	{0x363d, 0x06},
876 	{0x366e, 0x04},
877 	{0x3670, 0x48},
878 	{0x3671, 0xff},
879 	{0x3672, 0x1f},
880 	{0x3673, 0x1f},
881 	{0x367a, 0x40},
882 	{0x367b, 0x40},
883 	{0x3690, 0x42},
884 	{0x3691, 0x44},
885 	{0x3692, 0x44},
886 	{0x3699, 0x80},
887 	{0x369a, 0x9f},
888 	{0x369b, 0x9f},
889 	{0x369c, 0x40},
890 	{0x369d, 0x40},
891 	{0x36a2, 0x40},
892 	{0x36a3, 0x40},
893 	{0x36cc, 0x2c},
894 	{0x36cd, 0x30},
895 	{0x36ce, 0x30},
896 	{0x36d0, 0x20},
897 	{0x36d1, 0x40},
898 	{0x36d2, 0x40},
899 	{0x36ea, 0xa8},
900 	{0x36eb, 0x04},
901 	{0x36ec, 0x03},
902 	{0x36ed, 0x0c},
903 	{0x36fa, 0x78},
904 	{0x36fb, 0x14},
905 	{0x36fc, 0x00},
906 	{0x36fd, 0x2c},
907 	{0x3817, 0x20},
908 	{0x3905, 0xd8},
909 	{0x3908, 0x11},
910 	{0x391b, 0x80},
911 	{0x391c, 0x0f},
912 	{0x391d, 0x21},
913 	{0x3933, 0x24},
914 	{0x3934, 0xb0},
915 	{0x3935, 0x80},
916 	{0x3936, 0x1f},
917 	{0x3940, 0x68},
918 	{0x3942, 0x04},
919 	{0x3943, 0xc0},
920 	{0x3980, 0x00},
921 	{0x3981, 0x50},
922 	{0x3982, 0x00},
923 	{0x3983, 0x40},
924 	{0x3984, 0x00},
925 	{0x3985, 0x20},
926 	{0x3986, 0x00},
927 	{0x3987, 0x10},
928 	{0x3988, 0x00},
929 	{0x3989, 0x20},
930 	{0x398a, 0x00},
931 	{0x398b, 0x30},
932 	{0x398c, 0x00},
933 	{0x398d, 0x50},
934 	{0x398e, 0x00},
935 	{0x398f, 0x60},
936 	{0x3990, 0x00},
937 	{0x3991, 0x70},
938 	{0x3992, 0x00},
939 	{0x3993, 0x36},
940 	{0x3994, 0x00},
941 	{0x3995, 0x20},
942 	{0x3996, 0x00},
943 	{0x3997, 0x14},
944 	{0x3998, 0x00},
945 	{0x3999, 0x20},
946 	{0x399a, 0x00},
947 	{0x399b, 0x50},
948 	{0x399c, 0x00},
949 	{0x399d, 0x90},
950 	{0x399e, 0x00},
951 	{0x399f, 0xf0},
952 	{0x39a0, 0x08},
953 	{0x39a1, 0x10},
954 	{0x39a2, 0x20},
955 	{0x39a3, 0x40},
956 	{0x39a4, 0x20},
957 	{0x39a5, 0x10},
958 	{0x39a6, 0x08},
959 	{0x39a7, 0x04},
960 	{0x39a8, 0x18},
961 	{0x39a9, 0x30},
962 	{0x39aa, 0x40},
963 	{0x39ab, 0x60},
964 	{0x39ac, 0x38},
965 	{0x39ad, 0x20},
966 	{0x39ae, 0x10},
967 	{0x39af, 0x08},
968 	{0x39b9, 0x00},
969 	{0x39ba, 0xa0},
970 	{0x39bb, 0x80},
971 	{0x39bc, 0x00},
972 	{0x39bd, 0x44},
973 	{0x39be, 0x00},
974 	{0x39bf, 0x00},
975 	{0x39c0, 0x00},
976 	{0x39c5, 0x41},
977 	{0x3e00, 0x00},
978 	{0x3e01, 0xbb},
979 	{0x3e02, 0x40},
980 	{0x3e03, 0x0b},
981 	{0x3e06, 0x00},
982 	{0x3e07, 0x80},
983 	{0x3e08, 0x03},
984 	{0x3e09, 0x40},
985 	{0x3e0e, 0x6a},
986 	{0x3e26, 0x40},
987 	{0x4401, 0x0b},
988 	{0x4407, 0xb0},
989 	{0x4418, 0x0b},
990 	{0x4501, 0xb4},
991 	{0x4509, 0x10},
992 	{0x4603, 0x00},
993 	{0x4837, 0x15},
994 	{0x5000, 0x0e},
995 	{0x550f, 0x20},
996 	{0x5784, 0x10},
997 	{0x5785, 0x08},
998 	{0x5787, 0x06},
999 	{0x5788, 0x06},
1000 	{0x5789, 0x00},
1001 	{0x578a, 0x06},
1002 	{0x578b, 0x06},
1003 	{0x578c, 0x00},
1004 	{0x5790, 0x10},
1005 	{0x5791, 0x10},
1006 	{0x5792, 0x00},
1007 	{0x5793, 0x10},
1008 	{0x5794, 0x10},
1009 	{0x5795, 0x00},
1010 	{0x57c4, 0x10},
1011 	{0x57c5, 0x08},
1012 	{0x57c7, 0x06},
1013 	{0x57c8, 0x06},
1014 	{0x57c9, 0x00},
1015 	{0x57ca, 0x06},
1016 	{0x57cb, 0x06},
1017 	{0x57cc, 0x00},
1018 	{0x57d0, 0x10},
1019 	{0x57d1, 0x10},
1020 	{0x57d2, 0x00},
1021 	{0x57d3, 0x10},
1022 	{0x57d4, 0x10},
1023 	{0x57d5, 0x00},
1024 	{0x36e9, 0x51},
1025 	{0x36f9, 0x51},
1026 	//{0x0100, 0x01},
1027 	{REG_NULL, 0x00},
1028 };
1029 
1030 
1031 /*
1032  * Xclk 27Mhz
1033  * max_framerate 25fps
1034  * mipi_datarate per lane 1080Mbps, 2lane
1035  */
1036 static const struct regval sc4210_hdr_10_25fps_2560x1440_2lane_regs[] = {
1037 	{0x0103, 0x01},
1038 	{0x0100, 0x00},
1039 	{0x36e9, 0x80},
1040 	{0x36f9, 0x80},
1041 	{0x3001, 0x07},
1042 	{0x3002, 0xc0},
1043 	{0x300a, 0x2c},
1044 	{0x300f, 0x00},
1045 	{0x3018, 0x33},
1046 	{0x3019, 0x0c},
1047 	{0x301f, 0x45},
1048 	{0x3031, 0x0a},
1049 	{0x3038, 0x22},
1050 	{0x3207, 0xa7},
1051 	{0x320c, 0x06},
1052 	{0x320d, 0x68},
1053 	{0x320e, 0x0b},
1054 	{0x320f, 0x90},
1055 	{0x3213, 0x04},
1056 	{0x3220, 0x50},
1057 	{0x3225, 0x01},
1058 	{0x3227, 0x03},
1059 	{0x3229, 0x08},
1060 	{0x3231, 0x01},
1061 	{0x3241, 0x02},
1062 	{0x3243, 0x03},
1063 	{0x3249, 0x17},
1064 	{0x3250, 0x3f},
1065 	{0x3251, 0x08},
1066 	{0x3000, 0x00},
1067 	{0x3253, 0x10},
1068 	{0x325e, 0x00},
1069 	{0x325f, 0x00},
1070 	{0x3273, 0x01},
1071 	{0x3301, 0x15},
1072 	{0x3302, 0x18},
1073 	{0x3304, 0x20},
1074 	{0x3305, 0x00},
1075 	{0x3306, 0x78},
1076 	{0x3308, 0x10},
1077 	{0x3309, 0x50},
1078 	{0x330a, 0x00},
1079 	{0x330b, 0xe8},
1080 	{0x330e, 0x20},
1081 	{0x3312, 0x02},
1082 	{0x3314, 0x84},
1083 	{0x331e, 0x19},
1084 	{0x331f, 0x49},
1085 	{0x3320, 0x05},
1086 	{0x3338, 0x10},
1087 	{0x334c, 0x10},
1088 	{0x335d, 0x20},
1089 	{0x335e, 0x02},
1090 	{0x335f, 0x04},
1091 	{0x3360, 0x20},
1092 	{0x3362, 0x72},
1093 	{0x3364, 0x1e},
1094 	{0x3366, 0x92},
1095 	{0x3367, 0x08},
1096 	{0x3368, 0x0a},
1097 	{0x3369, 0xd4},
1098 	{0x336a, 0x15},
1099 	{0x336b, 0xa8},
1100 	{0x336c, 0xc2},
1101 	{0x337a, 0x08},
1102 	{0x337b, 0x10},
1103 	{0x337c, 0x06},
1104 	{0x337d, 0x0a},
1105 	{0x337e, 0x40},
1106 	{0x3390, 0x08},
1107 	{0x3391, 0x18},
1108 	{0x3392, 0x38},
1109 	{0x3393, 0x13},
1110 	{0x3394, 0x24},
1111 	{0x3395, 0x24},
1112 	{0x3396, 0x08},
1113 	{0x3397, 0x18},
1114 	{0x3398, 0x38},
1115 	{0x3399, 0x11},
1116 	{0x339a, 0x14},
1117 	{0x339b, 0x24},
1118 	{0x339c, 0x24},
1119 	{0x33a2, 0x08},
1120 	{0x33a3, 0x0c},
1121 	{0x33e0, 0xa0},
1122 	{0x33e1, 0x08},
1123 	{0x33e2, 0x00},
1124 	{0x33e3, 0x10},
1125 	{0x33e4, 0x10},
1126 	{0x33e5, 0x00},
1127 	{0x33e6, 0x10},
1128 	{0x33e7, 0x10},
1129 	{0x33e8, 0x00},
1130 	{0x33e9, 0x10},
1131 	{0x33ea, 0x16},
1132 	{0x33eb, 0x00},
1133 	{0x33ec, 0x10},
1134 	{0x33ed, 0x18},
1135 	{0x33ee, 0xa0},
1136 	{0x33ef, 0x08},
1137 	{0x33f4, 0x00},
1138 	{0x33f5, 0x10},
1139 	{0x33f6, 0x10},
1140 	{0x33f7, 0x00},
1141 	{0x33f8, 0x10},
1142 	{0x33f9, 0x10},
1143 	{0x33fa, 0x00},
1144 	{0x33fb, 0x10},
1145 	{0x33fc, 0x16},
1146 	{0x33fd, 0x00},
1147 	{0x33fe, 0x10},
1148 	{0x33ff, 0x18},
1149 	{0x360f, 0x05},
1150 	{0x3622, 0xff},
1151 	{0x3624, 0x07},
1152 	{0x3625, 0x0a},
1153 	{0x3630, 0xc4},
1154 	{0x3631, 0x80},
1155 	{0x3632, 0x88},
1156 	{0x3633, 0x42},
1157 	{0x3634, 0x64},
1158 	{0x3635, 0x20},
1159 	{0x3636, 0x20},
1160 	{0x3638, 0x28},
1161 	{0x363b, 0x03},
1162 	{0x363c, 0x06},
1163 	{0x363d, 0x06},
1164 	{0x366e, 0x04},
1165 	{0x3670, 0x4a},
1166 	{0x3671, 0xff},
1167 	{0x3672, 0x9f},
1168 	{0x3673, 0x9f},
1169 	{0x3674, 0xc4},
1170 	{0x3675, 0xc4},
1171 	{0x3676, 0xb8},
1172 	{0x367a, 0x40},
1173 	{0x367b, 0x48},
1174 	{0x367c, 0x40},
1175 	{0x367d, 0x48},
1176 	{0x3690, 0x43},
1177 	{0x3691, 0x55},
1178 	{0x3692, 0x66},
1179 	{0x3699, 0x8c},
1180 	{0x369a, 0x96},
1181 	{0x369b, 0x9f},
1182 	{0x369c, 0x40},
1183 	{0x369d, 0x48},
1184 	{0x36a2, 0x40},
1185 	{0x36a3, 0x48},
1186 	{0x36cc, 0x2c},
1187 	{0x36cd, 0x30},
1188 	{0x36ce, 0x30},
1189 	{0x36d0, 0x20},
1190 	{0x36d1, 0x40},
1191 	{0x36d2, 0x40},
1192 	{0x36ea, 0x34},
1193 	{0x36eb, 0x06},
1194 	{0x36ec, 0x03},
1195 	{0x36ed, 0x2c},
1196 	{0x36fa, 0x37},
1197 	{0x36fb, 0x04},
1198 	{0x36fc, 0x00},
1199 	{0x36fd, 0x2c},
1200 	{0x3817, 0x20},
1201 	{0x3905, 0x98},
1202 	{0x3908, 0x11},
1203 	{0x391b, 0x80},
1204 	{0x391c, 0x0f},
1205 	{0x391d, 0x21},
1206 	{0x3933, 0x1f},
1207 	{0x3934, 0xff},
1208 	{0x3935, 0x80},
1209 	{0x3936, 0x1f},
1210 	{0x393e, 0x01},
1211 	{0x3940, 0x60},
1212 	{0x3942, 0x04},
1213 	{0x3943, 0xd0},
1214 	{0x3980, 0x00},
1215 	{0x3981, 0x30},
1216 	{0x3982, 0x00},
1217 	{0x3983, 0x2c},
1218 	{0x3984, 0x00},
1219 	{0x3985, 0x15},
1220 	{0x3986, 0x00},
1221 	{0x3987, 0x10},
1222 	{0x3988, 0x00},
1223 	{0x3989, 0x30},
1224 	{0x398a, 0x00},
1225 	{0x398b, 0x28},
1226 	{0x398c, 0x00},
1227 	{0x398d, 0x30},
1228 	{0x398e, 0x00},
1229 	{0x398f, 0x70},
1230 	{0x3990, 0x0a},
1231 	{0x3991, 0x00},
1232 	{0x3992, 0x00},
1233 	{0x3993, 0x60},
1234 	{0x3994, 0x00},
1235 	{0x3995, 0x30},
1236 	{0x3996, 0x00},
1237 	{0x3997, 0x10},
1238 	{0x3998, 0x00},
1239 	{0x3999, 0x1c},
1240 	{0x399a, 0x00},
1241 	{0x399b, 0x48},
1242 	{0x399c, 0x00},
1243 	{0x399d, 0x90},
1244 	{0x399e, 0x00},
1245 	{0x399f, 0xc0},
1246 	{0x39a0, 0x14},
1247 	{0x39a1, 0x28},
1248 	{0x39a2, 0x48},
1249 	{0x39a3, 0x70},
1250 	{0x39a4, 0x18},
1251 	{0x39a5, 0x04},
1252 	{0x39a6, 0x08},
1253 	{0x39a7, 0x04},
1254 	{0x39a8, 0x01},
1255 	{0x39a9, 0x14},
1256 	{0x39aa, 0x28},
1257 	{0x39ab, 0x50},
1258 	{0x39ac, 0x30},
1259 	{0x39ad, 0x20},
1260 	{0x39ae, 0x10},
1261 	{0x39af, 0x08},
1262 	{0x39b9, 0x00},
1263 	{0x39ba, 0x00},
1264 	{0x39bb, 0x00},
1265 	{0x39bc, 0x00},
1266 	{0x39bd, 0x58},
1267 	{0x39be, 0xc0},
1268 	{0x39bf, 0x00},
1269 	{0x39c0, 0x00},
1270 	{0x39c5, 0x41},
1271 	{0x3c09, 0x4a},
1272 	{0x3c10, 0x07},
1273 	{0x3c11, 0x20},
1274 	{0x3c12, 0x07},
1275 	{0x3c13, 0x20},
1276 	{0x3c14, 0x0f},
1277 	{0x3e00, 0x01},
1278 	{0x3e01, 0x5a},
1279 	{0x3e02, 0x00},
1280 	{0x3e03, 0x0b},
1281 	{0x3e04, 0x15},
1282 	{0x3e05, 0xa0},
1283 	{0x3e06, 0x00},
1284 	{0x3e07, 0x80},
1285 	{0x3e08, 0x03},
1286 	{0x3e09, 0x40},
1287 	{0x3e0e, 0x6a},
1288 	{0x3e10, 0x00},
1289 	{0x3e11, 0x80},
1290 	{0x3e12, 0x03},
1291 	{0x3e13, 0x40},
1292 	{0x3e23, 0x00},
1293 	{0x3e24, 0xbc},
1294 	{0x3e26, 0x40},
1295 	{0x4401, 0x0b},
1296 	{0x4407, 0xb0},
1297 	{0x4418, 0x16},
1298 	{0x4501, 0xa4},
1299 	{0x4509, 0x08},
1300 	{0x4603, 0x00},
1301 	{0x4800, 0x24},
1302 	{0x4816, 0x11},
1303 	{0x4819, 0x40},
1304 	{0x4829, 0x01},
1305 	{0x4837, 0x0f},
1306 	{0x5000, 0x0e},
1307 	{0x550f, 0x20},
1308 	{0x5784, 0x10},
1309 	{0x5785, 0x08},
1310 	{0x5787, 0x06},
1311 	{0x5788, 0x06},
1312 	{0x5789, 0x00},
1313 	{0x578a, 0x06},
1314 	{0x578b, 0x06},
1315 	{0x578c, 0x00},
1316 	{0x5790, 0x10},
1317 	{0x5791, 0x10},
1318 	{0x5792, 0x00},
1319 	{0x5793, 0x10},
1320 	{0x5794, 0x10},
1321 	{0x5795, 0x00},
1322 	{0x57c4, 0x10},
1323 	{0x57c5, 0x08},
1324 	{0x57c7, 0x06},
1325 	{0x57c8, 0x06},
1326 	{0x57c9, 0x00},
1327 	{0x57ca, 0x06},
1328 	{0x57cb, 0x06},
1329 	{0x57cc, 0x00},
1330 	{0x57d0, 0x10},
1331 	{0x57d1, 0x10},
1332 	{0x57d2, 0x00},
1333 	{0x57d3, 0x10},
1334 	{0x57d4, 0x10},
1335 	{0x57d5, 0x00},
1336 	{0x36e9, 0x44},
1337 	{0x36f9, 0x20},
1338 	//{0x0100, 0x01},
1339 	{REG_NULL, 0x00},
1340 };
1341 
1342 static const struct sc4210_mode supported_modes_2lane[] = {
1343 	{
1344 		.width = 2560,
1345 		.height = 1440,
1346 		.max_fps = {
1347 			.numerator = 10000,
1348 			.denominator = 300000,
1349 		},
1350 		.exp_def = 0x0100,
1351 		.hts_def = 0x0546,
1352 		.vts_def = 0x05dc,
1353 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1354 		.reg_list = sc4210_liner_10_30fps_2560x1440_2lane_regs,
1355 		.mipi_freq_idx = 0,
1356 		.bpp = 10,
1357 		.hdr_mode = NO_HDR,
1358 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1359 	},
1360 	{
1361 		.width = 2560,
1362 		.height = 1440,
1363 		.max_fps = {
1364 			.numerator = 10000,
1365 			.denominator = 250000,
1366 		},
1367 		.exp_def = 0x015a,
1368 		.hts_def = 0x0668,
1369 		.vts_def = 0x0b90,
1370 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1371 		.reg_list = sc4210_hdr_10_25fps_2560x1440_2lane_regs,
1372 		.mipi_freq_idx = 1,
1373 		.bpp = 10,
1374 		.hdr_mode = HDR_X2,
1375 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1376 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1377 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1378 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1379 	},
1380 };
1381 
1382 static const struct sc4210_mode supported_modes_4lane[] = {
1383 	{
1384 		.width = 2560,
1385 		.height = 1440,
1386 		.max_fps = {
1387 			.numerator = 10000,
1388 			.denominator = 300000,
1389 		},
1390 		.exp_def = 0x0100,
1391 		.hts_def = 0x0546,
1392 		.vts_def = 0x05dc,
1393 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1394 		.reg_list = sc4210_linear_10_30fps_2560x1440_4lane_regs,
1395 		.mipi_freq_idx = 2,
1396 		.bpp = 10,
1397 		.hdr_mode = NO_HDR,
1398 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1399 	},
1400 	{
1401 		.width = 2560,
1402 		.height = 1440,
1403 		.max_fps = {
1404 			.numerator = 10000,
1405 			.denominator = 300000,
1406 		},
1407 		.exp_def = 0x05a1,
1408 		.hts_def = 0x0558,
1409 		.vts_def = 0x0b90,
1410 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1411 		.reg_list = sc4210_hdr_10_30fps_2560x1440_4lane_regs,
1412 		.mipi_freq_idx = 3,
1413 		.bpp = 10,
1414 		.hdr_mode = HDR_X2,
1415 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1416 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1417 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1418 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
1419 	},
1420 };
1421 
1422 static const s64 link_freq_items[] = {
1423 	SC4210_LINK_FREQ_2LANE_LINEAR,
1424 	SC4210_LINK_FREQ_2LANE_HDR2,
1425 	SC4210_LINK_FREQ_4LANE_LINEAR,
1426 	SC4210_LINK_FREQ_4LANE_HDR2,
1427 };
1428 
1429 /* Write registers up to 4 at a time */
sc4210_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)1430 static int sc4210_write_reg(struct i2c_client *client, u16 reg,
1431 			     u32 len, u32 val)
1432 {
1433 	u32 buf_i, val_i;
1434 	u8 buf[6];
1435 	u8 *val_p;
1436 	__be32 val_be;
1437 
1438 	if (len > 4)
1439 		return -EINVAL;
1440 
1441 	buf[0] = reg >> 8;
1442 	buf[1] = reg & 0xff;
1443 
1444 	val_be = cpu_to_be32(val);
1445 	val_p = (u8 *)&val_be;
1446 	buf_i = 2;
1447 	val_i = 4 - len;
1448 
1449 	while (val_i < 4)
1450 		buf[buf_i++] = val_p[val_i++];
1451 
1452 	if (i2c_master_send(client, buf, len + 2) != len + 2)
1453 		return -EIO;
1454 
1455 	return 0;
1456 }
1457 
sc4210_write_array(struct i2c_client * client,const struct regval * regs)1458 static int sc4210_write_array(struct i2c_client *client,
1459 			       const struct regval *regs)
1460 {
1461 	u32 i;
1462 	int ret = 0;
1463 
1464 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
1465 		ret = sc4210_write_reg(client, regs[i].addr,
1466 					SC4210_REG_VALUE_08BIT, regs[i].val);
1467 
1468 	return ret;
1469 }
1470 
1471 /* Read registers up to 4 at a time */
sc4210_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)1472 static int sc4210_read_reg(struct i2c_client *client,
1473 			    u16 reg, unsigned int len, u32 *val)
1474 {
1475 	struct i2c_msg msgs[2];
1476 	u8 *data_be_p;
1477 	__be32 data_be = 0;
1478 	__be16 reg_addr_be = cpu_to_be16(reg);
1479 	int ret;
1480 
1481 	if (len > 4 || !len)
1482 		return -EINVAL;
1483 
1484 	data_be_p = (u8 *)&data_be;
1485 	/* Write register address */
1486 	msgs[0].addr = client->addr;
1487 	msgs[0].flags = 0;
1488 	msgs[0].len = 2;
1489 	msgs[0].buf = (u8 *)&reg_addr_be;
1490 
1491 	/* Read data from register */
1492 	msgs[1].addr = client->addr;
1493 	msgs[1].flags = I2C_M_RD;
1494 	msgs[1].len = len;
1495 	msgs[1].buf = &data_be_p[4 - len];
1496 
1497 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1498 	if (ret != ARRAY_SIZE(msgs))
1499 		return -EIO;
1500 
1501 	*val = be32_to_cpu(data_be);
1502 
1503 	return 0;
1504 }
1505 
sc4210_get_reso_dist(const struct sc4210_mode * mode,struct v4l2_mbus_framefmt * framefmt)1506 static int sc4210_get_reso_dist(const struct sc4210_mode *mode,
1507 		struct v4l2_mbus_framefmt *framefmt)
1508 {
1509 	return abs(mode->width - framefmt->width) +
1510 	       abs(mode->height - framefmt->height);
1511 }
1512 
1513 static const struct sc4210_mode *
sc4210_find_best_fit(struct sc4210 * sc4210,struct v4l2_subdev_format * fmt)1514 sc4210_find_best_fit(struct sc4210 *sc4210, struct v4l2_subdev_format *fmt)
1515 {
1516 	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
1517 	int dist;
1518 	int cur_best_fit = 0;
1519 	int cur_best_fit_dist = -1;
1520 	unsigned int i;
1521 
1522 	for (i = 0; i < sc4210->support_modes_num; i++) {
1523 		dist = sc4210_get_reso_dist(&sc4210->support_modes[i], framefmt);
1524 		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
1525 			cur_best_fit_dist = dist;
1526 			cur_best_fit = i;
1527 		}
1528 	}
1529 
1530 	return &sc4210->support_modes[cur_best_fit];
1531 }
1532 
sc4210_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1533 static int sc4210_set_fmt(struct v4l2_subdev *sd,
1534 			   struct v4l2_subdev_pad_config *cfg,
1535 			   struct v4l2_subdev_format *fmt)
1536 {
1537 	struct sc4210 *sc4210 = to_sc4210(sd);
1538 	const struct sc4210_mode *mode;
1539 	s64 h_blank, vblank_def;
1540 	u64 pixel_rate = 0;
1541 
1542 	mutex_lock(&sc4210->mutex);
1543 
1544 	mode = sc4210_find_best_fit(sc4210, fmt);
1545 	fmt->format.code = mode->bus_fmt;
1546 	fmt->format.width = mode->width;
1547 	fmt->format.height = mode->height;
1548 	fmt->format.field = V4L2_FIELD_NONE;
1549 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1550 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1551 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
1552 #else
1553 		mutex_unlock(&sc4210->mutex);
1554 		return -ENOTTY;
1555 #endif
1556 	} else {
1557 		sc4210->cur_mode = mode;
1558 
1559 		h_blank = mode->hts_def - mode->width;
1560 		__v4l2_ctrl_modify_range(sc4210->hblank, h_blank,
1561 					 h_blank, 1, h_blank);
1562 		vblank_def = mode->vts_def - mode->height;
1563 		__v4l2_ctrl_modify_range(sc4210->vblank, vblank_def,
1564 					 SC4210_VTS_MAX - mode->height,
1565 					 1, vblank_def);
1566 
1567 		__v4l2_ctrl_s_ctrl(sc4210->link_freq, mode->mipi_freq_idx);
1568 		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
1569 			     mode->bpp * 2 * sc4210->lane_num;
1570 		__v4l2_ctrl_s_ctrl_int64(sc4210->pixel_rate, pixel_rate);
1571 		sc4210->cur_fps = mode->max_fps;
1572 	}
1573 
1574 	mutex_unlock(&sc4210->mutex);
1575 
1576 	return 0;
1577 }
1578 
sc4210_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1579 static int sc4210_get_fmt(struct v4l2_subdev *sd,
1580 			   struct v4l2_subdev_pad_config *cfg,
1581 			   struct v4l2_subdev_format *fmt)
1582 {
1583 	struct sc4210 *sc4210 = to_sc4210(sd);
1584 	const struct sc4210_mode *mode = sc4210->cur_mode;
1585 
1586 	mutex_lock(&sc4210->mutex);
1587 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1588 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1589 		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1590 #else
1591 		mutex_unlock(&sc4210->mutex);
1592 		return -ENOTTY;
1593 #endif
1594 	} else {
1595 		fmt->format.width = mode->width;
1596 		fmt->format.height = mode->height;
1597 		fmt->format.code = mode->bus_fmt;
1598 		fmt->format.field = V4L2_FIELD_NONE;
1599 		/* format info: width/height/data type/virctual channel */
1600 		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
1601 			fmt->reserved[0] = mode->vc[fmt->pad];
1602 		else
1603 			fmt->reserved[0] = mode->vc[PAD0];
1604 	}
1605 	mutex_unlock(&sc4210->mutex);
1606 
1607 	return 0;
1608 }
1609 
sc4210_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)1610 static int sc4210_enum_mbus_code(struct v4l2_subdev *sd,
1611 				  struct v4l2_subdev_pad_config *cfg,
1612 				  struct v4l2_subdev_mbus_code_enum *code)
1613 {
1614 	struct sc4210 *sc4210 = to_sc4210(sd);
1615 
1616 	if (code->index != 0)
1617 		return -EINVAL;
1618 	code->code = sc4210->cur_mode->bus_fmt;
1619 
1620 	return 0;
1621 }
1622 
sc4210_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)1623 static int sc4210_enum_frame_sizes(struct v4l2_subdev *sd,
1624 				    struct v4l2_subdev_pad_config *cfg,
1625 				    struct v4l2_subdev_frame_size_enum *fse)
1626 {
1627 	struct sc4210 *sc4210 = to_sc4210(sd);
1628 
1629 	if (fse->index >= sc4210->support_modes_num)
1630 		return -EINVAL;
1631 
1632 	if (fse->code != sc4210->support_modes[fse->index].bus_fmt)
1633 		return -EINVAL;
1634 
1635 	fse->min_width  = sc4210->support_modes[fse->index].width;
1636 	fse->max_width  = sc4210->support_modes[fse->index].width;
1637 	fse->max_height = sc4210->support_modes[fse->index].height;
1638 	fse->min_height = sc4210->support_modes[fse->index].height;
1639 
1640 	return 0;
1641 }
1642 
sc4210_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)1643 static int sc4210_g_frame_interval(struct v4l2_subdev *sd,
1644 				    struct v4l2_subdev_frame_interval *fi)
1645 {
1646 	struct sc4210 *sc4210 = to_sc4210(sd);
1647 	const struct sc4210_mode *mode = sc4210->cur_mode;
1648 
1649 	if (sc4210->streaming)
1650 		fi->interval = sc4210->cur_fps;
1651 	else
1652 		fi->interval = mode->max_fps;
1653 
1654 	return 0;
1655 }
1656 
sc4210_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)1657 static int sc4210_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
1658 				 struct v4l2_mbus_config *config)
1659 {
1660 	struct sc4210 *sc4210 = to_sc4210(sd);
1661 	const struct sc4210_mode *mode = sc4210->cur_mode;
1662 	u32 val = 1 << (sc4210->lane_num - 1) |
1663 		  V4L2_MBUS_CSI2_CHANNEL_0 |
1664 		  V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
1665 
1666 	if (mode->hdr_mode != NO_HDR)
1667 		val |= V4L2_MBUS_CSI2_CHANNEL_1;
1668 	if (mode->hdr_mode == HDR_X3)
1669 		val |= V4L2_MBUS_CSI2_CHANNEL_2;
1670 
1671 	config->type = V4L2_MBUS_CSI2_DPHY;
1672 	config->flags = val;
1673 
1674 	return 0;
1675 }
1676 
sc4210_get_module_inf(struct sc4210 * sc4210,struct rkmodule_inf * inf)1677 static void sc4210_get_module_inf(struct sc4210 *sc4210,
1678 				   struct rkmodule_inf *inf)
1679 {
1680 	memset(inf, 0, sizeof(*inf));
1681 	strscpy(inf->base.sensor, SC4210_NAME, sizeof(inf->base.sensor));
1682 	strscpy(inf->base.module, sc4210->module_name,
1683 		sizeof(inf->base.module));
1684 	strscpy(inf->base.lens, sc4210->len_name, sizeof(inf->base.lens));
1685 }
1686 
sc4210_get_gain_reg(u32 total_gain,u32 * again,u32 * again_fine,u32 * dgain,u32 * dgain_fine)1687 static void sc4210_get_gain_reg(u32 total_gain, u32 *again, u32 *again_fine,
1688 					u32 *dgain, u32 *dgain_fine)
1689 {
1690 	u32 dgain_total = 0;
1691 
1692 	if (total_gain < SC4210_GAIN_MIN)
1693 		total_gain = SC4210_GAIN_MIN;
1694 	else if (total_gain > SC4210_GAIN_MAX)
1695 		total_gain = SC4210_GAIN_MAX;
1696 
1697 	dgain_total = total_gain * 1000 / 43656;
1698 
1699 		if (total_gain < 2000) { /* 1 - 2x gain */
1700 			*again = 0x03;
1701 			*again_fine = total_gain*64/1000;
1702 			*dgain = 0x00;
1703 			*dgain_fine = 0x80;
1704 		} else if (total_gain < 2750) { /* 2x - 2.75x gain */
1705 			*again = 0x07;
1706 			*again_fine = total_gain*64/2000;
1707 			*dgain = 0x00;
1708 			*dgain_fine = 0x80;
1709 		} else if (total_gain < 2750 * 2) { /* 2.75xx - 5.5x gain */
1710 			*again = 0x23;
1711 			*again_fine = total_gain*64/2750;
1712 			*dgain = 0x00;
1713 			*dgain_fine = 0x80;
1714 		} else if (total_gain < 2750 * 4) { /* 5.5x - 11.0x gain */
1715 			*again = 0x27;
1716 			*again_fine = total_gain*64/5500;
1717 			*dgain = 0x00;
1718 			*dgain_fine = 0x80;
1719 		} else if (total_gain < 2750 * 8) { /* 11.0x - 22.0x gain */
1720 			*again = 0x2f;
1721 			*again_fine = total_gain*64/11000;
1722 			*dgain = 0x00;
1723 			*dgain_fine = 0x80;
1724 		} else if (total_gain < 2750 * 16) { /* 22.0x - 43.656x gain */
1725 			*again = 0x3f;
1726 			*again_fine = total_gain*64/22000;
1727 			*dgain = 0x00;
1728 			*dgain_fine = 0x80;
1729 		} else if (total_gain < 43656 * 2) { /* 43.656x - 87.312x gain */
1730 			*again = 0x3f;
1731 			*again_fine = 0x7f;
1732 			*dgain = 0x00;
1733 			*dgain_fine = dgain_total*128/1000;
1734 		} else if (total_gain < 43656 * 4) { /* 87.312x - 174.624x gain */
1735 			*again = 0x3f;
1736 			*again_fine = 0x7f;
1737 			*dgain = 0x01;
1738 			*dgain_fine = dgain_total*128/2000;
1739 		} else if (total_gain < 43656 * 8) { /* 174.624x - 349.248x gain */
1740 			*again = 0x3f;
1741 			*again_fine = 0x7f;
1742 			*dgain = 0x03;
1743 			*dgain_fine = dgain_total*128/4000;
1744 		} else if (total_gain < 43656 * 16) { /* 349.248x - 698.496x gain */
1745 			*again = 0x3f;
1746 			*again_fine = 0x7f;
1747 			*dgain = 0x07;
1748 			*dgain_fine = dgain_total*128/8000;
1749 		} else if (total_gain < 43656 * 32) { /* 698.496x - 1375.164x gain */
1750 			*again = 0x3f;
1751 			*again_fine = 0x7f;
1752 			*dgain = 0x0f;
1753 			*dgain_fine = dgain_total*128/16000;
1754 		}
1755 }
1756 
sc4210_set_hdrae(struct sc4210 * sc4210,struct preisp_hdrae_exp_s * ae)1757 static int sc4210_set_hdrae(struct sc4210 *sc4210,
1758 			     struct preisp_hdrae_exp_s *ae)
1759 {
1760 	int ret = 0;
1761 	u32 l_exp_time, m_exp_time, s_exp_time;
1762 	u32 l_t_gain, m_t_gain, s_t_gain;
1763 	u32 l_again = 0, l_again_fine = 0, l_dgain = 0, l_dgain_fine = 0;
1764 	u32 s_again = 0, s_again_fine = 0, s_dgain = 0, s_dgain_fine = 0;
1765 
1766 	if (!sc4210->has_init_exp && !sc4210->streaming) {
1767 		sc4210->init_hdrae_exp = *ae;
1768 		sc4210->has_init_exp = true;
1769 		dev_dbg(&sc4210->client->dev,
1770 			"sc4210 don't stream, record exp for hdr!\n");
1771 		return ret;
1772 	}
1773 
1774 	l_exp_time = ae->long_exp_reg;
1775 	m_exp_time = ae->middle_exp_reg;
1776 	s_exp_time = ae->short_exp_reg;
1777 	l_t_gain = ae->long_gain_reg;
1778 	m_t_gain = ae->middle_gain_reg;
1779 	s_t_gain = ae->short_gain_reg;
1780 
1781 	if (sc4210->cur_mode->hdr_mode == HDR_X2) {
1782 		//2 stagger
1783 		l_t_gain = m_t_gain;
1784 		l_exp_time = m_exp_time;
1785 	}
1786 
1787 	l_exp_time = l_exp_time << 1;
1788 	s_exp_time = s_exp_time << 1;
1789 
1790 	// set exposure reg
1791 	ret |= sc4210_write_reg(sc4210->client,
1792 				 SC4210_REG_EXPOSURE_H,
1793 				 SC4210_REG_VALUE_08BIT,
1794 				 SC4210_FETCH_EXP_H(l_exp_time));
1795 	ret |= sc4210_write_reg(sc4210->client,
1796 				 SC4210_REG_EXPOSURE_M,
1797 				 SC4210_REG_VALUE_08BIT,
1798 				 SC4210_FETCH_EXP_M(l_exp_time));
1799 	ret |= sc4210_write_reg(sc4210->client,
1800 				 SC4210_REG_EXPOSURE_L,
1801 				 SC4210_REG_VALUE_08BIT,
1802 				 SC4210_FETCH_EXP_L(l_exp_time));
1803 	//ret |= sc4210_write_reg(sc4210->client,
1804 	//			 SC4210_REG_SHORT_EXPOSURE_H,
1805 	//			 SC4210_REG_VALUE_08BIT,
1806 	//			 SC4210_FETCH_EXP_H(s_exp_time));
1807 	ret |= sc4210_write_reg(sc4210->client,
1808 				 SC4210_REG_SHORT_EXPOSURE_M,
1809 				 SC4210_REG_VALUE_08BIT,
1810 				 SC4210_FETCH_EXP_M(s_exp_time));
1811 	ret |= sc4210_write_reg(sc4210->client,
1812 				 SC4210_REG_SHORT_EXPOSURE_L,
1813 				 SC4210_REG_VALUE_08BIT,
1814 				 SC4210_FETCH_EXP_L(s_exp_time));
1815 
1816 	// set gain reg
1817 	sc4210_get_gain_reg(l_t_gain, &l_again, &l_again_fine, &l_dgain, &l_dgain_fine);
1818 	sc4210_get_gain_reg(s_t_gain, &s_again, &s_again_fine, &s_dgain, &s_dgain_fine);
1819 
1820 	ret |= sc4210_write_reg(sc4210->client,
1821 				 SC4210_REG_DIG_GAIN,
1822 				 SC4210_REG_VALUE_08BIT,
1823 				 l_dgain);
1824 	ret |= sc4210_write_reg(sc4210->client,
1825 				 SC4210_REG_DIG_FINE_GAIN,
1826 				 SC4210_REG_VALUE_08BIT,
1827 				 l_dgain_fine);
1828 	ret |= sc4210_write_reg(sc4210->client,
1829 				 SC4210_REG_ANA_GAIN,
1830 				 SC4210_REG_VALUE_08BIT,
1831 				 l_again);
1832 	ret |= sc4210_write_reg(sc4210->client,
1833 				 SC4210_REG_ANA_FINE_GAIN,
1834 				 SC4210_REG_VALUE_08BIT,
1835 				 l_again_fine);
1836 
1837 	ret |= sc4210_write_reg(sc4210->client,
1838 				 SC4210_REG_SDIG_GAIN,
1839 				 SC4210_REG_VALUE_08BIT,
1840 				 s_dgain);
1841 	ret |= sc4210_write_reg(sc4210->client,
1842 				 SC4210_REG_SDIG_FINE_GAIN,
1843 				 SC4210_REG_VALUE_08BIT,
1844 				 s_dgain_fine);
1845 	ret |= sc4210_write_reg(sc4210->client,
1846 				 SC4210_REG_SANA_GAIN,
1847 				 SC4210_REG_VALUE_08BIT,
1848 				 s_again);
1849 	ret |= sc4210_write_reg(sc4210->client,
1850 				 SC4210_REG_SANA_FINE_GAIN,
1851 				 SC4210_REG_VALUE_08BIT,
1852 				 s_again_fine);
1853 	return ret;
1854 }
1855 
sc4210_get_channel_info(struct sc4210 * sc4210,struct rkmodule_channel_info * ch_info)1856 static int sc4210_get_channel_info(struct sc4210 *sc4210, struct rkmodule_channel_info *ch_info)
1857 {
1858 	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
1859 		return -EINVAL;
1860 	ch_info->vc = sc4210->cur_mode->vc[ch_info->index];
1861 	ch_info->width = sc4210->cur_mode->width;
1862 	ch_info->height = sc4210->cur_mode->height;
1863 	ch_info->bus_fmt = sc4210->cur_mode->bus_fmt;
1864 	return 0;
1865 }
1866 
sc4210_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)1867 static long sc4210_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1868 {
1869 	struct sc4210 *sc4210 = to_sc4210(sd);
1870 	struct rkmodule_hdr_cfg *hdr;
1871 	const struct sc4210_mode *mode;
1872 	struct rkmodule_channel_info *ch_info;
1873 	long ret = 0;
1874 	u32 i, h = 0, w;
1875 	u32 stream = 0;
1876 	int pixel_rate = 0;
1877 
1878 	switch (cmd) {
1879 	case RKMODULE_GET_MODULE_INFO:
1880 		sc4210_get_module_inf(sc4210, (struct rkmodule_inf *)arg);
1881 		break;
1882 	case RKMODULE_GET_HDR_CFG:
1883 		hdr = (struct rkmodule_hdr_cfg *)arg;
1884 		hdr->esp.mode = HDR_NORMAL_VC;
1885 		hdr->hdr_mode = sc4210->cur_mode->hdr_mode;
1886 		break;
1887 	case RKMODULE_SET_HDR_CFG:
1888 		hdr = (struct rkmodule_hdr_cfg *)arg;
1889 		w = sc4210->cur_mode->width;
1890 		h = sc4210->cur_mode->height;
1891 		for (i = 0; i < sc4210->support_modes_num; i++) {
1892 			if (w == sc4210->support_modes[i].width &&
1893 				h == sc4210->support_modes[i].height &&
1894 				sc4210->support_modes[i].hdr_mode == hdr->hdr_mode) {
1895 				sc4210->cur_mode = &sc4210->support_modes[i];
1896 				break;
1897 			}
1898 		}
1899 		if (i == sc4210->support_modes_num) {
1900 			dev_err(&sc4210->client->dev,
1901 				"not find hdr mode:%d %dx%d config\n",
1902 				hdr->hdr_mode, w, h);
1903 			ret = -EINVAL;
1904 		} else {
1905 			mode = sc4210->cur_mode;
1906 			w = sc4210->cur_mode->hts_def -
1907 					sc4210->cur_mode->width;
1908 			h = sc4210->cur_mode->vts_def -
1909 					sc4210->cur_mode->height;
1910 			__v4l2_ctrl_modify_range(sc4210->hblank, w, w, 1, w);
1911 			__v4l2_ctrl_modify_range(sc4210->vblank, h,
1912 						 SC4210_VTS_MAX -
1913 						 sc4210->cur_mode->height,
1914 						 1, h);
1915 
1916 			__v4l2_ctrl_s_ctrl(sc4210->link_freq,
1917 					   mode->mipi_freq_idx);
1918 
1919 			pixel_rate = (int)link_freq_items[mode->mipi_freq_idx]
1920 				     / mode->bpp * 2 * sc4210->lane_num;
1921 
1922 			__v4l2_ctrl_s_ctrl_int64(sc4210->pixel_rate,
1923 						 pixel_rate);
1924 
1925 			dev_info(&sc4210->client->dev, "sensor mode: %d\n",
1926 				 sc4210->cur_mode->hdr_mode);
1927 		}
1928 		break;
1929 	case PREISP_CMD_SET_HDRAE_EXP:
1930 		if (sc4210->cur_mode->hdr_mode == HDR_X2)
1931 			ret = sc4210_set_hdrae(sc4210, arg);
1932 		break;
1933 	case RKMODULE_SET_QUICK_STREAM:
1934 		stream = *((u32 *)arg);
1935 		if (stream)
1936 			ret = sc4210_write_reg(sc4210->client,
1937 						SC4210_REG_CTRL_MODE,
1938 						SC4210_REG_VALUE_08BIT,
1939 						SC4210_MODE_STREAMING);
1940 		else
1941 			ret = sc4210_write_reg(sc4210->client,
1942 						SC4210_REG_CTRL_MODE,
1943 						SC4210_REG_VALUE_08BIT,
1944 						SC4210_MODE_SW_STANDBY);
1945 		break;
1946 	case RKMODULE_GET_CHANNEL_INFO:
1947 		ch_info = (struct rkmodule_channel_info *)arg;
1948 		ret = sc4210_get_channel_info(sc4210, ch_info);
1949 		break;
1950 	default:
1951 		ret = -ENOIOCTLCMD;
1952 		break;
1953 	}
1954 
1955 	return ret;
1956 }
1957 
1958 #ifdef CONFIG_COMPAT
sc4210_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)1959 static long sc4210_compat_ioctl32(struct v4l2_subdev *sd,
1960 					unsigned int cmd, unsigned long arg)
1961 {
1962 	void __user *up = compat_ptr(arg);
1963 	struct rkmodule_inf *inf;
1964 	struct rkmodule_hdr_cfg *hdr;
1965 	struct preisp_hdrae_exp_s *hdrae;
1966 	struct rkmodule_channel_info *ch_info;
1967 	long ret = 0;
1968 	u32 stream = 0;
1969 
1970 	switch (cmd) {
1971 	case RKMODULE_GET_MODULE_INFO:
1972 		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
1973 		if (!inf) {
1974 			ret = -ENOMEM;
1975 			return ret;
1976 		}
1977 
1978 		ret = sc4210_ioctl(sd, cmd, inf);
1979 		if (!ret) {
1980 			ret = copy_to_user(up, inf, sizeof(*inf));
1981 			if (ret)
1982 				return -EFAULT;
1983 		}
1984 		kfree(inf);
1985 		break;
1986 	case RKMODULE_GET_HDR_CFG:
1987 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1988 		if (!hdr) {
1989 			ret = -ENOMEM;
1990 			return ret;
1991 		}
1992 
1993 		ret = sc4210_ioctl(sd, cmd, hdr);
1994 		if (!ret) {
1995 			ret = copy_to_user(up, hdr, sizeof(*hdr));
1996 			if (ret)
1997 				return -EFAULT;
1998 		}
1999 		kfree(hdr);
2000 		break;
2001 	case RKMODULE_SET_HDR_CFG:
2002 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2003 		if (!hdr) {
2004 			ret = -ENOMEM;
2005 			return ret;
2006 		}
2007 
2008 		if (copy_from_user(hdr, up, sizeof(*hdr))) {
2009 			kfree(hdr);
2010 			return -EFAULT;
2011 		}
2012 
2013 		ret = sc4210_ioctl(sd, cmd, hdr);
2014 		kfree(hdr);
2015 		break;
2016 	case PREISP_CMD_SET_HDRAE_EXP:
2017 		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
2018 		if (!hdrae) {
2019 			ret = -ENOMEM;
2020 			return ret;
2021 		}
2022 
2023 		if (copy_from_user(hdrae, up, sizeof(*hdrae))) {
2024 			kfree(hdrae);
2025 			return -EFAULT;
2026 		}
2027 
2028 			ret = sc4210_ioctl(sd, cmd, hdrae);
2029 		kfree(hdrae);
2030 		break;
2031 	case RKMODULE_SET_QUICK_STREAM:
2032 		if (copy_from_user(&stream, up, sizeof(u32)))
2033 			return -EFAULT;
2034 
2035 		ret = sc4210_ioctl(sd, cmd, &stream);
2036 		break;
2037 	case RKMODULE_GET_CHANNEL_INFO:
2038 		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2039 		if (!ch_info) {
2040 			ret = -ENOMEM;
2041 			return ret;
2042 		}
2043 
2044 		ret = sc4210_ioctl(sd, cmd, ch_info);
2045 		if (!ret) {
2046 			ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2047 			if (ret)
2048 				ret = -EFAULT;
2049 		}
2050 		kfree(ch_info);
2051 		break;
2052 	default:
2053 		ret = -ENOIOCTLCMD;
2054 		break;
2055 	}
2056 
2057 	return ret;
2058 }
2059 #endif
2060 
__sc4210_start_stream(struct sc4210 * sc4210)2061 static int __sc4210_start_stream(struct sc4210 *sc4210)
2062 {
2063 	int ret;
2064 
2065 	ret = sc4210_write_array(sc4210->client, sc4210->cur_mode->reg_list);
2066 	if (ret)
2067 		return ret;
2068 
2069 	/* In case these controls are set before streaming */
2070 	ret = __v4l2_ctrl_handler_setup(&sc4210->ctrl_handler);
2071 	if (ret)
2072 		return ret;
2073 	if (sc4210->has_init_exp && sc4210->cur_mode->hdr_mode != NO_HDR) {
2074 		ret = sc4210_ioctl(&sc4210->subdev, PREISP_CMD_SET_HDRAE_EXP,
2075 				    &sc4210->init_hdrae_exp);
2076 		if (ret) {
2077 			dev_err(&sc4210->client->dev,
2078 				"init exp fail in hdr mode\n");
2079 			return ret;
2080 		}
2081 	}
2082 	return sc4210_write_reg(sc4210->client, SC4210_REG_CTRL_MODE,
2083 				 SC4210_REG_VALUE_08BIT,
2084 				 SC4210_MODE_STREAMING);
2085 }
2086 
__sc4210_stop_stream(struct sc4210 * sc4210)2087 static int __sc4210_stop_stream(struct sc4210 *sc4210)
2088 {
2089 	sc4210->has_init_exp = false;
2090 	return sc4210_write_reg(sc4210->client, SC4210_REG_CTRL_MODE,
2091 				 SC4210_REG_VALUE_08BIT,
2092 				 SC4210_MODE_SW_STANDBY);
2093 }
2094 
sc4210_s_stream(struct v4l2_subdev * sd,int on)2095 static int sc4210_s_stream(struct v4l2_subdev *sd, int on)
2096 {
2097 	struct sc4210 *sc4210 = to_sc4210(sd);
2098 	struct i2c_client *client = sc4210->client;
2099 	int ret = 0;
2100 
2101 	mutex_lock(&sc4210->mutex);
2102 	on = !!on;
2103 	if (on == sc4210->streaming)
2104 		goto unlock_and_return;
2105 	if (on) {
2106 		ret = pm_runtime_get_sync(&client->dev);
2107 		if (ret < 0) {
2108 			pm_runtime_put_noidle(&client->dev);
2109 			goto unlock_and_return;
2110 		}
2111 		ret = __sc4210_start_stream(sc4210);
2112 		if (ret) {
2113 			v4l2_err(sd, "start stream failed while write regs\n");
2114 			pm_runtime_put(&client->dev);
2115 			goto unlock_and_return;
2116 		}
2117 	} else {
2118 		__sc4210_stop_stream(sc4210);
2119 		pm_runtime_put(&client->dev);
2120 	}
2121 
2122 	sc4210->streaming = on;
2123 
2124 unlock_and_return:
2125 	mutex_unlock(&sc4210->mutex);
2126 
2127 	return ret;
2128 }
2129 
sc4210_s_power(struct v4l2_subdev * sd,int on)2130 static int sc4210_s_power(struct v4l2_subdev *sd, int on)
2131 {
2132 	struct sc4210 *sc4210 = to_sc4210(sd);
2133 	struct i2c_client *client = sc4210->client;
2134 	int ret = 0;
2135 
2136 	mutex_lock(&sc4210->mutex);
2137 
2138 	/* If the power state is not modified - no work to do. */
2139 	if (sc4210->power_on == !!on)
2140 		goto unlock_and_return;
2141 
2142 	if (on) {
2143 		ret = pm_runtime_get_sync(&client->dev);
2144 		if (ret < 0) {
2145 			pm_runtime_put_noidle(&client->dev);
2146 			goto unlock_and_return;
2147 		}
2148 
2149 		sc4210->power_on = true;
2150 	} else {
2151 		pm_runtime_put(&client->dev);
2152 		sc4210->power_on = false;
2153 	}
2154 
2155 unlock_and_return:
2156 	mutex_unlock(&sc4210->mutex);
2157 
2158 	return ret;
2159 }
2160 
__sc4210_power_on(struct sc4210 * sc4210)2161 static int __sc4210_power_on(struct sc4210 *sc4210)
2162 {
2163 	int ret;
2164 	struct device *dev = &sc4210->client->dev;
2165 
2166 	if (!IS_ERR_OR_NULL(sc4210->pins_default)) {
2167 		ret = pinctrl_select_state(sc4210->pinctrl,
2168 					   sc4210->pins_default);
2169 		if (ret < 0)
2170 			dev_err(dev, "could not set pins\n");
2171 	}
2172 	ret = clk_set_rate(sc4210->xvclk, SC4210_XVCLK_FREQ);
2173 	if (ret < 0)
2174 		dev_warn(dev, "Failed to set xvclk rate (27MHz)\n");
2175 	if (clk_get_rate(sc4210->xvclk) != SC4210_XVCLK_FREQ)
2176 		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
2177 	ret = clk_prepare_enable(sc4210->xvclk);
2178 	if (ret < 0) {
2179 		dev_err(dev, "Failed to enable xvclk\n");
2180 		return ret;
2181 	}
2182 	if (!IS_ERR(sc4210->reset_gpio))
2183 		gpiod_set_value_cansleep(sc4210->reset_gpio, 0);
2184 
2185 	ret = regulator_bulk_enable(sc4210_NUM_SUPPLIES, sc4210->supplies);
2186 	if (ret < 0) {
2187 		dev_err(dev, "Failed to enable regulators\n");
2188 		goto disable_clk;
2189 	}
2190 
2191 	if (!IS_ERR(sc4210->reset_gpio))
2192 		gpiod_set_value_cansleep(sc4210->reset_gpio, 1);
2193 
2194 	usleep_range(500, 1000);
2195 	if (!IS_ERR(sc4210->pwdn_gpio))
2196 		gpiod_set_value_cansleep(sc4210->pwdn_gpio, 1);
2197 
2198 	usleep_range(4000, 5000);
2199 	return 0;
2200 
2201 disable_clk:
2202 	clk_disable_unprepare(sc4210->xvclk);
2203 
2204 	return ret;
2205 }
2206 
__sc4210_power_off(struct sc4210 * sc4210)2207 static void __sc4210_power_off(struct sc4210 *sc4210)
2208 {
2209 	int ret;
2210 	struct device *dev = &sc4210->client->dev;
2211 
2212 	if (!IS_ERR(sc4210->pwdn_gpio))
2213 		gpiod_set_value_cansleep(sc4210->pwdn_gpio, 0);
2214 	clk_disable_unprepare(sc4210->xvclk);
2215 	if (!IS_ERR(sc4210->reset_gpio))
2216 		gpiod_set_value_cansleep(sc4210->reset_gpio, 0);
2217 	if (!IS_ERR_OR_NULL(sc4210->pins_sleep)) {
2218 		ret = pinctrl_select_state(sc4210->pinctrl,
2219 					   sc4210->pins_sleep);
2220 		if (ret < 0)
2221 			dev_dbg(dev, "could not set pins\n");
2222 	}
2223 	regulator_bulk_disable(sc4210_NUM_SUPPLIES, sc4210->supplies);
2224 }
2225 
sc4210_runtime_resume(struct device * dev)2226 static int sc4210_runtime_resume(struct device *dev)
2227 {
2228 	struct i2c_client *client = to_i2c_client(dev);
2229 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2230 	struct sc4210 *sc4210 = to_sc4210(sd);
2231 
2232 	return __sc4210_power_on(sc4210);
2233 }
2234 
sc4210_runtime_suspend(struct device * dev)2235 static int sc4210_runtime_suspend(struct device *dev)
2236 {
2237 	struct i2c_client *client = to_i2c_client(dev);
2238 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2239 	struct sc4210 *sc4210 = to_sc4210(sd);
2240 
2241 	__sc4210_power_off(sc4210);
2242 
2243 	return 0;
2244 }
2245 
2246 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sc4210_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2247 static int sc4210_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2248 {
2249 	struct sc4210 *sc4210 = to_sc4210(sd);
2250 	struct v4l2_mbus_framefmt *try_fmt =
2251 			v4l2_subdev_get_try_format(sd, fh->pad, 0);
2252 	const struct sc4210_mode *def_mode = &sc4210->support_modes[0];
2253 
2254 	mutex_lock(&sc4210->mutex);
2255 	/* Initialize try_fmt */
2256 	try_fmt->width = def_mode->width;
2257 	try_fmt->height = def_mode->height;
2258 	try_fmt->code = def_mode->bus_fmt;
2259 	try_fmt->field = V4L2_FIELD_NONE;
2260 
2261 	mutex_unlock(&sc4210->mutex);
2262 	/* No crop or compose */
2263 
2264 	return 0;
2265 }
2266 #endif
2267 
sc4210_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2268 static int sc4210_enum_frame_interval(struct v4l2_subdev *sd,
2269 				       struct v4l2_subdev_pad_config *cfg,
2270 				       struct v4l2_subdev_frame_interval_enum *fie)
2271 {
2272 	struct sc4210 *sc4210 = to_sc4210(sd);
2273 
2274 	if (fie->index >= sc4210->support_modes_num)
2275 		return -EINVAL;
2276 
2277 	fie->code = sc4210->support_modes[fie->index].bus_fmt;
2278 	fie->width = sc4210->support_modes[fie->index].width;
2279 	fie->height = sc4210->support_modes[fie->index].height;
2280 	fie->interval = sc4210->support_modes[fie->index].max_fps;
2281 	fie->reserved[0] = sc4210->support_modes[fie->index].hdr_mode;
2282 	return 0;
2283 }
2284 
2285 static const struct dev_pm_ops sc4210_pm_ops = {
2286 	SET_RUNTIME_PM_OPS(sc4210_runtime_suspend,
2287 	sc4210_runtime_resume, NULL)
2288 };
2289 
2290 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2291 static const struct v4l2_subdev_internal_ops sc4210_internal_ops = {
2292 	.open = sc4210_open,
2293 };
2294 #endif
2295 
2296 static const struct v4l2_subdev_core_ops sc4210_core_ops = {
2297 	.s_power = sc4210_s_power,
2298 	.ioctl = sc4210_ioctl,
2299 #ifdef CONFIG_COMPAT
2300 	.compat_ioctl32 = sc4210_compat_ioctl32,
2301 #endif
2302 };
2303 
2304 static const struct v4l2_subdev_video_ops sc4210_video_ops = {
2305 	.s_stream = sc4210_s_stream,
2306 	.g_frame_interval = sc4210_g_frame_interval,
2307 };
2308 
2309 static const struct v4l2_subdev_pad_ops sc4210_pad_ops = {
2310 	.enum_mbus_code = sc4210_enum_mbus_code,
2311 	.enum_frame_size = sc4210_enum_frame_sizes,
2312 	.enum_frame_interval = sc4210_enum_frame_interval,
2313 	.get_fmt = sc4210_get_fmt,
2314 	.set_fmt = sc4210_set_fmt,
2315 	.get_mbus_config = sc4210_g_mbus_config,
2316 };
2317 
2318 static const struct v4l2_subdev_ops sc4210_subdev_ops = {
2319 	.core	= &sc4210_core_ops,
2320 	.video	= &sc4210_video_ops,
2321 	.pad	= &sc4210_pad_ops,
2322 };
2323 
sc4210_modify_fps_info(struct sc4210 * sc4210)2324 static void sc4210_modify_fps_info(struct sc4210 *sc4210)
2325 {
2326 	const struct sc4210_mode *mode = sc4210->cur_mode;
2327 
2328 	sc4210->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
2329 				      sc4210->cur_vts;
2330 }
2331 
sc4210_set_ctrl(struct v4l2_ctrl * ctrl)2332 static int sc4210_set_ctrl(struct v4l2_ctrl *ctrl)
2333 {
2334 	struct sc4210 *sc4210 = container_of(ctrl->handler,
2335 					       struct sc4210, ctrl_handler);
2336 	struct i2c_client *client = sc4210->client;
2337 	s64 max;
2338 	u32 again = 0, again_fine = 0, dgain = 0, dgain_fine = 0;
2339 	int ret = 0;
2340 	u32 val = 0, vts = 0;
2341 
2342 	/* Propagate change of current control to all related controls */
2343 	switch (ctrl->id) {
2344 	case V4L2_CID_VBLANK:
2345 		/* Update max exposure while meeting expected vblanking */
2346 		max = sc4210->cur_mode->height + ctrl->val - 2;
2347 		__v4l2_ctrl_modify_range(sc4210->exposure,
2348 					 sc4210->exposure->minimum, max,
2349 					 sc4210->exposure->step,
2350 					 sc4210->exposure->default_value);
2351 		break;
2352 	}
2353 
2354 	if (!pm_runtime_get_if_in_use(&client->dev))
2355 		return 0;
2356 
2357 	switch (ctrl->id) {
2358 	case V4L2_CID_EXPOSURE:
2359 		if (sc4210->cur_mode->hdr_mode != NO_HDR)
2360 			goto ctrl_end;
2361 		val = ctrl->val << 1;
2362 		ret = sc4210_write_reg(sc4210->client,
2363 					SC4210_REG_EXPOSURE_H,
2364 					SC4210_REG_VALUE_08BIT,
2365 					SC4210_FETCH_EXP_H(val));
2366 		ret |= sc4210_write_reg(sc4210->client,
2367 					 SC4210_REG_EXPOSURE_M,
2368 					 SC4210_REG_VALUE_08BIT,
2369 					 SC4210_FETCH_EXP_M(val));
2370 		ret |= sc4210_write_reg(sc4210->client,
2371 					 SC4210_REG_EXPOSURE_L,
2372 					 SC4210_REG_VALUE_08BIT,
2373 					 SC4210_FETCH_EXP_L(val));
2374 
2375 		dev_dbg(&client->dev, "set exposure 0x%x\n", val);
2376 		break;
2377 	case V4L2_CID_ANALOGUE_GAIN:
2378 		if (sc4210->cur_mode->hdr_mode != NO_HDR)
2379 			goto ctrl_end;
2380 
2381 		sc4210_get_gain_reg(ctrl->val, &again, &again_fine, &dgain, &dgain_fine);
2382 		ret = sc4210_write_reg(sc4210->client,
2383 					SC4210_REG_DIG_GAIN,
2384 					SC4210_REG_VALUE_08BIT,
2385 					dgain);
2386 		ret |= sc4210_write_reg(sc4210->client,
2387 					 SC4210_REG_DIG_FINE_GAIN,
2388 					 SC4210_REG_VALUE_08BIT,
2389 					 dgain_fine);
2390 		ret |= sc4210_write_reg(sc4210->client,
2391 					 SC4210_REG_ANA_GAIN,
2392 					SC4210_REG_VALUE_08BIT,
2393 					 again);
2394 		ret |= sc4210_write_reg(sc4210->client,
2395 					 SC4210_REG_ANA_FINE_GAIN,
2396 					SC4210_REG_VALUE_08BIT,
2397 					 again_fine);
2398 		dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
2399 		break;
2400 	case V4L2_CID_VBLANK:
2401 		vts = ctrl->val + sc4210->cur_mode->height;
2402 		ret = sc4210_write_reg(sc4210->client,
2403 					SC4210_REG_VTS_H,
2404 					SC4210_REG_VALUE_08BIT,
2405 					(vts >> 8) & 0x7f);
2406 		ret |= sc4210_write_reg(sc4210->client,
2407 					 SC4210_REG_VTS_L,
2408 					 SC4210_REG_VALUE_08BIT,
2409 					 vts & 0xff);
2410 		sc4210->cur_vts = ctrl->val + sc4210->cur_mode->height;
2411 		sc4210_modify_fps_info(sc4210);
2412 		dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
2413 		break;
2414 	case V4L2_CID_HFLIP:
2415 		ret = sc4210_read_reg(sc4210->client, SC4210_FLIP_MIRROR_REG,
2416 				       SC4210_REG_VALUE_08BIT, &val);
2417 		if (ret)
2418 			break;
2419 
2420 		if (ctrl->val)
2421 			val |= SC4210_MIRROR_MASK;
2422 		else
2423 			val &= ~SC4210_MIRROR_MASK;
2424 		ret |= sc4210_write_reg(sc4210->client,
2425 					 SC4210_FLIP_MIRROR_REG,
2426 					 SC4210_REG_VALUE_08BIT, val);
2427 		break;
2428 	case V4L2_CID_VFLIP:
2429 		ret = sc4210_read_reg(sc4210->client,
2430 				       SC4210_FLIP_MIRROR_REG,
2431 				       SC4210_REG_VALUE_08BIT, &val);
2432 		if (ret)
2433 			break;
2434 
2435 		if (ctrl->val)
2436 			val |= SC4210_FLIP_MASK;
2437 		else
2438 			val &= ~SC4210_FLIP_MASK;
2439 		ret |= sc4210_write_reg(sc4210->client,
2440 					 SC4210_FLIP_MIRROR_REG,
2441 					 SC4210_REG_VALUE_08BIT,
2442 					 val);
2443 		break;
2444 	default:
2445 		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
2446 			 __func__, ctrl->id, ctrl->val);
2447 		break;
2448 	}
2449 
2450 ctrl_end:
2451 	pm_runtime_put(&client->dev);
2452 
2453 	return ret;
2454 }
2455 
2456 static const struct v4l2_ctrl_ops sc4210_ctrl_ops = {
2457 	.s_ctrl = sc4210_set_ctrl,
2458 };
2459 
sc4210_parse_of(struct sc4210 * sc4210)2460 static int sc4210_parse_of(struct sc4210 *sc4210)
2461 {
2462 	struct device *dev = &sc4210->client->dev;
2463 	struct device_node *endpoint;
2464 	struct fwnode_handle *fwnode;
2465 	int rval;
2466 
2467 	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
2468 	if (!endpoint) {
2469 		dev_err(dev, "Failed to get endpoint\n");
2470 		return -EINVAL;
2471 	}
2472 	fwnode = of_fwnode_handle(endpoint);
2473 	rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
2474 	if (rval <= 0) {
2475 		dev_err(dev, " Get mipi lane num failed!\n");
2476 		return -EINVAL;
2477 	}
2478 
2479 	sc4210->lane_num = rval;
2480 	dev_info(dev, "lane_num = %d\n", sc4210->lane_num);
2481 
2482 	if (sc4210->lane_num == 2) {
2483 		sc4210->support_modes = supported_modes_2lane;
2484 		sc4210->support_modes_num = ARRAY_SIZE(supported_modes_2lane);
2485 	} else if (sc4210->lane_num == 4) {
2486 		sc4210->support_modes = supported_modes_4lane;
2487 		sc4210->support_modes_num = ARRAY_SIZE(supported_modes_4lane);
2488 	}
2489 
2490 	sc4210->cur_mode = &sc4210->support_modes[0];
2491 
2492 	return 0;
2493 }
2494 
sc4210_initialize_controls(struct sc4210 * sc4210)2495 static int sc4210_initialize_controls(struct sc4210 *sc4210)
2496 {
2497 	const struct sc4210_mode *mode;
2498 	struct v4l2_ctrl_handler *handler;
2499 	s64 exposure_max, vblank_def;
2500 	u64 dst_pixel_rate = 0;
2501 	u32 h_blank;
2502 	int ret;
2503 
2504 	handler = &sc4210->ctrl_handler;
2505 	mode = sc4210->cur_mode;
2506 	ret = v4l2_ctrl_handler_init(handler, 8);
2507 	if (ret)
2508 		return ret;
2509 	handler->lock = &sc4210->mutex;
2510 
2511 	sc4210->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
2512 				V4L2_CID_LINK_FREQ,
2513 				ARRAY_SIZE(link_freq_items) - 1, 0,
2514 				link_freq_items);
2515 	__v4l2_ctrl_s_ctrl(sc4210->link_freq, mode->mipi_freq_idx);
2516 
2517 	if (mode->mipi_freq_idx == 0)
2518 		dst_pixel_rate = SC4210_PIXEL_RATES_2LANE_LINEAR;
2519 	else if (mode->mipi_freq_idx == 1)
2520 		dst_pixel_rate = SC4210_PIXEL_RATES_2LANE_HDR2;
2521 	else if (mode->mipi_freq_idx == 2)
2522 		dst_pixel_rate = SC4210_PIXEL_RATES_4LANE_LINEAR;
2523 	else if (mode->mipi_freq_idx == 2)
2524 		dst_pixel_rate = SC4210_PIXEL_RATES_4LANE_HDR2;
2525 
2526 	sc4210->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2527 						V4L2_CID_PIXEL_RATE, 0,
2528 						SC4210_MAX_PIXEL_RATE,
2529 						1, dst_pixel_rate);
2530 
2531 	h_blank = mode->hts_def - mode->width;
2532 	sc4210->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
2533 					    h_blank, h_blank, 1, h_blank);
2534 	if (sc4210->hblank)
2535 		sc4210->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2536 
2537 	vblank_def = mode->vts_def - mode->height;
2538 	sc4210->vblank = v4l2_ctrl_new_std(handler, &sc4210_ctrl_ops,
2539 					    V4L2_CID_VBLANK, vblank_def,
2540 					    SC4210_VTS_MAX - mode->height,
2541 					    1, vblank_def);
2542 	sc4210->cur_fps = mode->max_fps;
2543 	exposure_max = (mode->vts_def << 1) - 2;
2544 	sc4210->exposure = v4l2_ctrl_new_std(handler, &sc4210_ctrl_ops,
2545 					      V4L2_CID_EXPOSURE,
2546 					      SC4210_EXPOSURE_MIN,
2547 					      exposure_max,
2548 					      SC4210_EXPOSURE_STEP,
2549 					      mode->exp_def);
2550 
2551 	sc4210->anal_gain = v4l2_ctrl_new_std(handler, &sc4210_ctrl_ops,
2552 					       V4L2_CID_ANALOGUE_GAIN,
2553 					       SC4210_GAIN_MIN,
2554 					       SC4210_GAIN_MAX,
2555 					       SC4210_GAIN_STEP,
2556 					       SC4210_GAIN_DEFAULT);
2557 
2558 	v4l2_ctrl_new_std(handler, &sc4210_ctrl_ops,
2559 			  V4L2_CID_HFLIP, 0, 1, 1, 0);
2560 
2561 	v4l2_ctrl_new_std(handler, &sc4210_ctrl_ops,
2562 			  V4L2_CID_VFLIP, 0, 1, 1, 0);
2563 
2564 	if (handler->error) {
2565 		ret = handler->error;
2566 		dev_err(&sc4210->client->dev,
2567 			"Failed to init controls(%d)\n", ret);
2568 		goto err_free_handler;
2569 	}
2570 	sc4210->subdev.ctrl_handler = handler;
2571 	sc4210->has_init_exp = false;
2572 
2573 	return 0;
2574 
2575 err_free_handler:
2576 	v4l2_ctrl_handler_free(handler);
2577 	return ret;
2578 }
2579 
sc4210_check_sensor_id(struct sc4210 * sc4210,struct i2c_client * client)2580 static int sc4210_check_sensor_id(struct sc4210 *sc4210,
2581 				   struct i2c_client *client)
2582 {
2583 	struct device *dev = &sc4210->client->dev;
2584 	u32 id = 0;
2585 	int ret;
2586 
2587 	ret = sc4210_read_reg(client, SC4210_REG_CHIP_ID,
2588 			       SC4210_REG_VALUE_16BIT, &id);
2589 	if (id != SC4210_CHIP_ID) {
2590 		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
2591 		return -ENODEV;
2592 	}
2593 
2594 	dev_info(dev, "Detected SC%06x sensor\n", SC4210_CHIP_ID);
2595 
2596 	return 0;
2597 }
2598 
sc4210_configure_regulators(struct sc4210 * sc4210)2599 static int sc4210_configure_regulators(struct sc4210 *sc4210)
2600 {
2601 	unsigned int i;
2602 
2603 	for (i = 0; i < sc4210_NUM_SUPPLIES; i++)
2604 		sc4210->supplies[i].supply = sc4210_supply_names[i];
2605 
2606 	return devm_regulator_bulk_get(&sc4210->client->dev,
2607 				       sc4210_NUM_SUPPLIES,
2608 				       sc4210->supplies);
2609 }
2610 
sc4210_probe(struct i2c_client * client,const struct i2c_device_id * id)2611 static int sc4210_probe(struct i2c_client *client,
2612 			 const struct i2c_device_id *id)
2613 {
2614 	struct device *dev = &client->dev;
2615 	struct device_node *node = dev->of_node;
2616 	struct sc4210 *sc4210;
2617 	struct v4l2_subdev *sd;
2618 	char facing[2];
2619 	int ret;
2620 	u32 hdr_mode = 0;
2621 
2622 	dev_info(dev, "driver version: %02x.%02x.%02x",
2623 		 DRIVER_VERSION >> 16,
2624 		 (DRIVER_VERSION & 0xff00) >> 8,
2625 		 DRIVER_VERSION & 0x00ff);
2626 
2627 	sc4210 = devm_kzalloc(dev, sizeof(*sc4210), GFP_KERNEL);
2628 	if (!sc4210)
2629 		return -ENOMEM;
2630 
2631 	of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
2632 	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
2633 				   &sc4210->module_index);
2634 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
2635 				       &sc4210->module_facing);
2636 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
2637 				       &sc4210->module_name);
2638 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
2639 				       &sc4210->len_name);
2640 	if (ret) {
2641 		dev_err(dev, "could not get module information!\n");
2642 		return -EINVAL;
2643 	}
2644 
2645 	sc4210->client = client;
2646 
2647 	ret = sc4210_parse_of(sc4210);
2648 	if (ret)
2649 		return -EINVAL;
2650 
2651 	sc4210->xvclk = devm_clk_get(dev, "xvclk");
2652 	if (IS_ERR(sc4210->xvclk)) {
2653 		dev_err(dev, "Failed to get xvclk\n");
2654 		return -EINVAL;
2655 	}
2656 
2657 	sc4210->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2658 	if (IS_ERR(sc4210->reset_gpio))
2659 		dev_warn(dev, "Failed to get reset-gpios\n");
2660 
2661 	sc4210->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2662 	if (IS_ERR(sc4210->pwdn_gpio))
2663 		dev_warn(dev, "Failed to get pwdn-gpios\n");
2664 
2665 	sc4210->pinctrl = devm_pinctrl_get(dev);
2666 	if (!IS_ERR(sc4210->pinctrl)) {
2667 		sc4210->pins_default =
2668 			pinctrl_lookup_state(sc4210->pinctrl,
2669 					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
2670 		if (IS_ERR(sc4210->pins_default))
2671 			dev_err(dev, "could not get default pinstate\n");
2672 
2673 		sc4210->pins_sleep =
2674 			pinctrl_lookup_state(sc4210->pinctrl,
2675 					     OF_CAMERA_PINCTRL_STATE_SLEEP);
2676 		if (IS_ERR(sc4210->pins_sleep))
2677 			dev_err(dev, "could not get sleep pinstate\n");
2678 	} else {
2679 		dev_err(dev, "no pinctrl\n");
2680 	}
2681 
2682 	ret = sc4210_configure_regulators(sc4210);
2683 	if (ret) {
2684 		dev_err(dev, "Failed to get power regulators\n");
2685 		return ret;
2686 	}
2687 
2688 	mutex_init(&sc4210->mutex);
2689 
2690 	sd = &sc4210->subdev;
2691 	v4l2_i2c_subdev_init(sd, client, &sc4210_subdev_ops);
2692 	ret = sc4210_initialize_controls(sc4210);
2693 	if (ret)
2694 		goto err_destroy_mutex;
2695 
2696 	ret = __sc4210_power_on(sc4210);
2697 	if (ret)
2698 		goto err_free_handler;
2699 
2700 	ret = sc4210_check_sensor_id(sc4210, client);
2701 	if (ret)
2702 		goto err_power_off;
2703 
2704 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2705 	sd->internal_ops = &sc4210_internal_ops;
2706 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
2707 			V4L2_SUBDEV_FL_HAS_EVENTS;
2708 #endif
2709 #if defined(CONFIG_MEDIA_CONTROLLER)
2710 	sc4210->pad.flags = MEDIA_PAD_FL_SOURCE;
2711 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
2712 	ret = media_entity_pads_init(&sd->entity, 1, &sc4210->pad);
2713 	if (ret < 0)
2714 		goto err_power_off;
2715 #endif
2716 
2717 	memset(facing, 0, sizeof(facing));
2718 	if (strcmp(sc4210->module_facing, "back") == 0)
2719 		facing[0] = 'b';
2720 	else
2721 		facing[0] = 'f';
2722 
2723 	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
2724 		sc4210->module_index, facing,
2725 		SC4210_NAME, dev_name(sd->dev));
2726 	ret = v4l2_async_register_subdev_sensor_common(sd);
2727 	if (ret) {
2728 		dev_err(&sc4210->client->dev,
2729 			"v4l2 async register subdev failed\n");
2730 		goto err_clean_entity;
2731 	}
2732 
2733 	pm_runtime_set_active(dev);
2734 	pm_runtime_enable(dev);
2735 	pm_runtime_idle(dev);
2736 
2737 	return 0;
2738 
2739 err_clean_entity:
2740 #if defined(CONFIG_MEDIA_CONTROLLER)
2741 	media_entity_cleanup(&sd->entity);
2742 #endif
2743 err_power_off:
2744 	__sc4210_power_off(sc4210);
2745 err_free_handler:
2746 	v4l2_ctrl_handler_free(&sc4210->ctrl_handler);
2747 err_destroy_mutex:
2748 	mutex_destroy(&sc4210->mutex);
2749 
2750 	return ret;
2751 }
2752 
sc4210_remove(struct i2c_client * client)2753 static int sc4210_remove(struct i2c_client *client)
2754 {
2755 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2756 	struct sc4210 *sc4210 = to_sc4210(sd);
2757 
2758 	v4l2_async_unregister_subdev(sd);
2759 #if defined(CONFIG_MEDIA_CONTROLLER)
2760 	media_entity_cleanup(&sd->entity);
2761 #endif
2762 	v4l2_ctrl_handler_free(&sc4210->ctrl_handler);
2763 	mutex_destroy(&sc4210->mutex);
2764 
2765 	pm_runtime_disable(&client->dev);
2766 	if (!pm_runtime_status_suspended(&client->dev))
2767 		__sc4210_power_off(sc4210);
2768 	pm_runtime_set_suspended(&client->dev);
2769 
2770 	return 0;
2771 }
2772 
2773 #if IS_ENABLED(CONFIG_OF)
2774 static const struct of_device_id sc4210_of_match[] = {
2775 	{ .compatible = "smartsens,sc4210" },
2776 	{ },
2777 };
2778 MODULE_DEVICE_TABLE(of, sc4210_of_match);
2779 #endif
2780 
2781 static const struct i2c_device_id sc4210_match_id[] = {
2782 	{ "smartsens,sc4210", 0 },
2783 	{ },
2784 };
2785 
2786 static struct i2c_driver sc4210_i2c_driver = {
2787 	.driver = {
2788 		.name = SC4210_NAME,
2789 		.pm = &sc4210_pm_ops,
2790 		.of_match_table = of_match_ptr(sc4210_of_match),
2791 	},
2792 	.probe		= &sc4210_probe,
2793 	.remove		= &sc4210_remove,
2794 	.id_table	= sc4210_match_id,
2795 };
2796 
sensor_mod_init(void)2797 static int __init sensor_mod_init(void)
2798 {
2799 	return i2c_add_driver(&sc4210_i2c_driver);
2800 }
2801 
sensor_mod_exit(void)2802 static void __exit sensor_mod_exit(void)
2803 {
2804 	i2c_del_driver(&sc4210_i2c_driver);
2805 }
2806 
2807 device_initcall_sync(sensor_mod_init);
2808 module_exit(sensor_mod_exit);
2809 
2810 MODULE_DESCRIPTION("smartsens sc4210 sensor driver");
2811 MODULE_LICENSE("GPL");
2812