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