xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/sc2310.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sc2310 driver
4  *
5  * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd.
6  *
7  * V0.0X01.0X00 first version,adjust sc2310.
8  * V0.0X01.0X01 add set flip ctrl.
9  * V0.0X01.0X02 1.fixed time limit error
10  *		2.fixed gain conversion function
11  *		3.fixed test pattern error
12  *		4.add quick stream on/off
13  */
14 
15 //#define DEBUG
16 #include <linux/clk.h>
17 #include <linux/device.h>
18 #include <linux/delay.h>
19 #include <linux/gpio/consumer.h>
20 #include <linux/i2c.h>
21 #include <linux/module.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/sysfs.h>
25 #include <linux/slab.h>
26 #include <linux/version.h>
27 #include <linux/rk-camera-module.h>
28 #include <media/media-entity.h>
29 #include <media/v4l2-async.h>
30 #include <media/v4l2-ctrls.h>
31 #include <media/v4l2-subdev.h>
32 #include <linux/pinctrl/consumer.h>
33 #include <linux/rk-preisp.h>
34 
35 #define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x02)
36 
37 #ifndef V4L2_CID_DIGITAL_GAIN
38 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
39 #endif
40 
41 #define MIPI_FREQ_186M			186000000 //371.25Mbps/lane
42 #define MIPI_FREQ_380M			380000000 //760Mbps/lane
43 
44 #define SC2310_MAX_PIXEL_RATE		(MIPI_FREQ_380M * 2 / 10 * 2)
45 #define OF_CAMERA_HDR_MODE		"rockchip,camera-hdr-mode"
46 
47 #define SC2310_XVCLK_FREQ		24000000
48 
49 #define CHIP_ID				0x2311
50 #define SC2310_REG_CHIP_ID		0x3107
51 
52 #define SC2310_REG_CTRL_MODE		0x0100
53 #define SC2310_MODE_SW_STANDBY		0x0
54 #define SC2310_MODE_STREAMING		BIT(0)
55 
56 #define	SC2310_EXPOSURE_MIN		2// two lines long exp min
57 #define	SC2310_EXPOSURE_STEP	1
58 #define SC2310_VTS_MAX			0xffff
59 
60 //long exposure
61 #define SC2310_REG_EXP_LONG_H		0x3e00    //[3:0]
62 #define SC2310_REG_EXP_LONG_M		0x3e01    //[7:0]
63 #define SC2310_REG_EXP_LONG_L		0x3e02    //[7:4]
64 
65 //short exposure
66 #define SC2310_REG_EXP_SF_H		0x3e04    //[7:0]
67 #define SC2310_REG_EXP_SF_L		0x3e05    //[7:4]
68 
69 //long frame and normal gain reg
70 #define SC2310_REG_AGAIN		0x3e08
71 #define SC2310_REG_AGAIN_FINE		0x3e09
72 
73 #define SC2310_REG_DGAIN		0x3e06
74 #define SC2310_REG_DGAIN_FINE		0x3e07
75 
76 //short fram gain reg
77 #define SC2310_SF_REG_AGAIN		0x3e12
78 #define SC2310_SF_REG_AGAIN_FINE	0x3e13
79 
80 #define SC2310_SF_REG_DGAIN		0x3e10
81 #define SC2310_SF_REG_DGAIN_FINE	0x3e11
82 
83 #define SC2310_GAIN_MIN			0x40
84 #define SC2310_GAIN_MAX			(44 * 32 * 64)
85 #define SC2310_GAIN_STEP		1
86 #define SC2310_GAIN_DEFAULT		0x40
87 
88 //group hold
89 #define SC2310_GROUP_UPDATE_ADDRESS	0x3812
90 #define SC2310_GROUP_UPDATE_START_DATA	0x00
91 #define SC2310_GROUP_UPDATE_LAUNCH	0x30
92 
93 #define SC2310_SOFTWARE_RESET_REG	0x0103
94 #define SC2310_REG_TEST_PATTERN		0x4501
95 #define SC2310_TEST_PATTERN_ENABLE	0x08
96 
97 #define SC2310_REG_VTS			0x320e
98 #define SC2310_FLIP_REG			0x3221
99 #define SC2310_FLIP_MASK		0x60
100 #define SC2310_MIRROR_MASK		0x06
101 #define REG_NULL			0xFFFF
102 
103 #define SC2310_REG_VALUE_08BIT		1
104 #define SC2310_REG_VALUE_16BIT		2
105 #define SC2310_REG_VALUE_24BIT		3
106 
107 #define SC2310_LANES			2
108 #define LONG_FRAME_MAX_EXP		4297
109 #define SHORT_FRAME_MAX_EXP		260
110 
111 #define OF_CAMERA_PINCTRL_STATE_DEFAULT	"rockchip,camera_default"
112 #define OF_CAMERA_PINCTRL_STATE_SLEEP	"rockchip,camera_sleep"
113 
114 #define SC2310_NAME			"sc2310"
115 
116 static const char * const sc2310_supply_names[] = {
117 	"avdd",		/* Analog power */
118 	"dovdd",	/* Digital I/O power */
119 	"dvdd",		/* Digital core power */
120 };
121 
122 #define SC2310_NUM_SUPPLIES ARRAY_SIZE(sc2310_supply_names)
123 
124 struct regval {
125 	u16 addr;
126 	u8 val;
127 };
128 
129 struct sc2310_mode {
130 	u32 bus_fmt;
131 	u32 width;
132 	u32 height;
133 	struct v4l2_fract max_fps;
134 	u32 hts_def;
135 	u32 vts_def;
136 	u32 exp_def;
137 	const struct regval *reg_list;
138 	u32 hdr_mode;
139 	u32 mipi_freq_idx;
140 	u32 bpp;
141 	u32 vc[PAD_MAX];
142 };
143 
144 struct sc2310 {
145 	struct i2c_client	*client;
146 	struct clk		*xvclk;
147 	struct gpio_desc	*reset_gpio;
148 	struct gpio_desc	*pwdn_gpio;
149 	struct regulator_bulk_data supplies[SC2310_NUM_SUPPLIES];
150 	struct pinctrl		*pinctrl;
151 	struct pinctrl_state	*pins_default;
152 	struct pinctrl_state	*pins_sleep;
153 	struct v4l2_subdev	subdev;
154 	struct media_pad	pad;
155 	struct v4l2_ctrl_handler ctrl_handler;
156 	struct v4l2_ctrl	*exposure;
157 	struct v4l2_ctrl	*anal_gain;
158 	struct v4l2_ctrl	*digi_gain;
159 	struct v4l2_ctrl	*hblank;
160 	struct v4l2_ctrl	*vblank;
161 	struct v4l2_ctrl	*test_pattern;
162 	struct v4l2_ctrl	*pixel_rate;
163 	struct v4l2_ctrl	*link_freq;
164 	struct mutex		mutex;
165 	struct v4l2_fract	cur_fps;
166 	bool			streaming;
167 	bool			power_on;
168 	const struct sc2310_mode *cur_mode;
169 	u32			cfg_num;
170 	u32			module_index;
171 	const char		*module_facing;
172 	const char		*module_name;
173 	const char		*len_name;
174 	bool			has_init_exp;
175 	u32			cur_vts;
176 	struct preisp_hdrae_exp_s init_hdrae_exp;
177 };
178 
179 #define to_sc2310(sd) container_of(sd, struct sc2310, subdev)
180 
181 /*
182  * Xclk 24Mhz linear 1920*1080 30fps 37.125Mbps/lane
183  */
184 static const struct regval sc2310_linear10bit_1920x1080_regs[] = {
185 	{0x0103, 0x01},
186 	{0x0100, 0x00},
187 	{0x36e9, 0x80},
188 	{0x36f9, 0x80},
189 	{0x3001, 0xfe},
190 	{0x3018, 0x33},
191 	{0x3019, 0x0c},
192 	{0x301c, 0x78},
193 	{0x301f, 0x40},
194 	{0x3031, 0x0a},
195 	{0x3037, 0x22},
196 	{0x3038, 0x22},
197 	{0x303f, 0x01},
198 	{0x3200, 0x00},
199 	{0x3201, 0x04},
200 	{0x3202, 0x00},
201 	{0x3203, 0x04},
202 	{0x3204, 0x07},
203 	{0x3205, 0x8b},
204 	{0x3206, 0x04},
205 	{0x3207, 0x43},
206 	{0x3208, 0x07},
207 	{0x3209, 0x80},
208 	{0x320a, 0x04},
209 	{0x320b, 0x38},
210 	{0x320c, 0x04},
211 	{0x320d, 0x4c},
212 	{0x3210, 0x00},
213 	{0x3211, 0x04},
214 	{0x3212, 0x00},
215 	{0x3213, 0x04},
216 	{0x3301, 0x10},
217 	{0x3302, 0x10},
218 	{0x3303, 0x18},
219 	{0x3306, 0x60},
220 	{0x3308, 0x08},
221 	{0x3309, 0x30},
222 	{0x330a, 0x00},
223 	{0x330b, 0xc8},
224 	{0x330e, 0x28},
225 	{0x3314, 0x04},
226 	{0x331b, 0x83},
227 	{0x331e, 0x11},
228 	{0x331f, 0x29},
229 	{0x3320, 0x01},
230 	{0x3324, 0x02},
231 	{0x3325, 0x02},
232 	{0x3326, 0x00},
233 	{0x3333, 0x30},
234 	{0x3334, 0x40},
235 	{0x333d, 0x08},
236 	{0x3341, 0x07},
237 	{0x3343, 0x03},
238 	{0x3364, 0x1d},
239 	{0x3366, 0x80},
240 	{0x3367, 0x08},
241 	{0x3368, 0x04},
242 	{0x3369, 0x00},
243 	{0x336a, 0x00},
244 	{0x336b, 0x00},
245 	{0x336c, 0x42},
246 	{0x337f, 0x03},
247 	{0x3380, 0x1b},
248 	{0x33aa, 0x00},
249 	{0x33b6, 0x07},
250 	{0x33b7, 0x07},
251 	{0x33b8, 0x10},
252 	{0x33b9, 0x10},
253 	{0x33ba, 0x10},
254 	{0x33bb, 0x07},
255 	{0x33bc, 0x07},
256 	{0x33bd, 0x20},
257 	{0x33be, 0x20},
258 	{0x33bf, 0x20},
259 	{0x360f, 0x05},
260 	{0x3621, 0xac},
261 	{0x3622, 0xe6},
262 	{0x3623, 0x18},
263 	{0x3624, 0x47},
264 	{0x3630, 0xc8},
265 	{0x3631, 0x88},
266 	{0x3632, 0x18},
267 	{0x3633, 0x22},
268 	{0x3634, 0x44},
269 	{0x3635, 0x40},
270 	{0x3636, 0x65},
271 	{0x3637, 0x17},
272 	{0x3638, 0x25},
273 	{0x363b, 0x08},
274 	{0x363c, 0x05},
275 	{0x363d, 0x05},
276 	{0x3640, 0x00},
277 	{0x366e, 0x04},
278 	{0x3670, 0x4a},
279 	{0x3671, 0xf6},
280 	{0x3672, 0x16},
281 	{0x3673, 0x16},
282 	{0x3674, 0xc8},
283 	{0x3675, 0x54},
284 	{0x3676, 0x18},
285 	{0x3677, 0x22},
286 	{0x3678, 0x33},
287 	{0x3679, 0x44},
288 	{0x367a, 0x40},
289 	{0x367b, 0x40},
290 	{0x367c, 0x40},
291 	{0x367d, 0x58},
292 	{0x367e, 0x40},
293 	{0x367f, 0x58},
294 	{0x3696, 0x83},
295 	{0x3697, 0x87},
296 	{0x3698, 0x9f},
297 	{0x36a0, 0x58},
298 	{0x36a1, 0x78},
299 	{0x36ea, 0x9f},
300 	{0x36eb, 0x0e},
301 	{0x36ec, 0x1e},
302 	{0x36ed, 0x03},
303 	{0x36fa, 0xf8},
304 	{0x36fb, 0x10},
305 	{0x3802, 0x00},
306 	{0x3907, 0x01},
307 	{0x3908, 0x01},
308 	{0x391e, 0x00},
309 	{0x391f, 0xc0},
310 	{0x3933, 0x28},
311 	{0x3934, 0x0a},
312 	{0x3940, 0x1b},
313 	{0x3941, 0x40},
314 	{0x3942, 0x08},
315 	{0x3943, 0x0e},
316 	{0x3e00, 0x00},
317 	{0x3e01, 0x8c},
318 	{0x3e02, 0x40},
319 	{0x3e03, 0x0b},
320 	{0x3e06, 0x00},
321 	{0x3e07, 0x80},
322 	{0x3e08, 0x03},
323 	{0x3e09, 0x40},
324 	{0x3e0e, 0x66},
325 	{0x3e14, 0xb0},
326 	{0x3e1e, 0x35},
327 	{0x3e25, 0x03},
328 	{0x3e26, 0x40},
329 	{0x3f00, 0x0d},
330 	{0x3f04, 0x02},
331 	{0x3f05, 0x1e},
332 	{0x3f08, 0x04},
333 	{0x4500, 0x59},
334 	{0x4501, 0xb4},
335 	{0x4509, 0x20},
336 	{0x4603, 0x00},
337 	{0x4809, 0x01},
338 	{0x4837, 0x35},
339 	{0x5000, 0x06},
340 	{0x5780, 0x7f},
341 	{0x5781, 0x06},
342 	{0x5782, 0x04},
343 	{0x5783, 0x02},
344 	{0x5784, 0x01},
345 	{0x5785, 0x16},
346 	{0x5786, 0x12},
347 	{0x5787, 0x08},
348 	{0x5788, 0x02},
349 	{0x57a0, 0x00},
350 	{0x57a1, 0x74},
351 	{0x57a2, 0x01},
352 	{0x57a3, 0xf4},
353 	{0x57a4, 0xf0},
354 	{0x6000, 0x00},
355 	{0x6002, 0x00},
356 	{0x36e9, 0x51},
357 	{0x36f9, 0x04},
358 	{REG_NULL, 0x00},
359 };
360 
361 /*
362  * Xclk 24Mhz hdr 2to1 STAGGER 1920*1080 30fps 760Mbps/lane
363  */
364 static __maybe_unused const struct regval sc2310_hdr10bit_1920x1080_regs[] = {
365 	//{0x0103, 0x01},
366 	{0x303f, 0x01},
367 	{0x0100, 0x00},
368 	{0x36e9, 0xa6},
369 	{0x36f9, 0x85},
370 	{0x4509, 0x10},
371 	{0x337f, 0x03},
372 	{0x3368, 0x04},
373 	{0x3369, 0x00},
374 	{0x336a, 0x00},
375 	{0x336b, 0x00},
376 	{0x3367, 0x08},
377 	{0x3326, 0x00},
378 	{0x3631, 0x88},
379 	{0x3018, 0x33},
380 	{0x3031, 0x0a},
381 	{0x3001, 0xfe},
382 	{0x4603, 0x00},
383 	{0x3640, 0x00},
384 	{0x3907, 0x01},
385 	{0x3908, 0x01},
386 	{0x3320, 0x01},
387 	{0x57a4, 0xf0},
388 	{0x3333, 0x30},
389 	{0x331b, 0x83},
390 	{0x3334, 0x40},
391 	{0x3302, 0x10},
392 	{0x36eb, 0x0a},
393 	{0x36ec, 0x0e},
394 	{0x3f08, 0x04},
395 	{0x4501, 0xa4},
396 	{0x3309, 0x48},
397 	{0x331f, 0x39},
398 	{0x330a, 0x00},
399 	{0x3308, 0x10},
400 	{0x3366, 0xc0},
401 	{0x33aa, 0x00},
402 	{0x391e, 0x00},
403 	{0x391f, 0xc0},
404 	{0x3634, 0x44},
405 	{0x4500, 0x59},
406 	{0x3623, 0x18},
407 	{0x3f00, 0x0d},
408 	{0x336c, 0x42},
409 	{0x3933, 0x28},
410 	{0x3934, 0x0a},
411 	{0x3940, 0x1b},
412 	{0x3941, 0x40},
413 	{0x3942, 0x08},
414 	{0x3943, 0x0e},
415 	{0x3624, 0x47},
416 	{0x3621, 0xac},
417 	{0x3222, 0x29},
418 	{0x3901, 0x02},
419 	{0x363b, 0x08},
420 	{0x363c, 0x05},
421 	{0x363d, 0x05},
422 	{0x3324, 0x02},
423 	{0x3325, 0x02},
424 	{0x333d, 0x08},
425 	{0x3314, 0x04},
426 	{0x3802, 0x00},
427 	{0x3e14, 0xb0},
428 	{0x3e1e, 0x35},
429 	{0x3e0e, 0x66},
430 	{0x3364, 0x1d},
431 	{0x33b6, 0x07},
432 	{0x33b7, 0x07},
433 	{0x33b8, 0x10},
434 	{0x33b9, 0x10},
435 	{0x33ba, 0x10},
436 	{0x33bb, 0x07},
437 	{0x33bc, 0x07},
438 	{0x33bd, 0x18},
439 	{0x33be, 0x18},
440 	{0x33bf, 0x18},
441 	{0x360f, 0x05},
442 	{0x367a, 0x40},
443 	{0x367b, 0x40},
444 	{0x3671, 0xf6},
445 	{0x3672, 0x16},
446 	{0x3673, 0x16},
447 	{0x366e, 0x04},
448 	{0x367c, 0x40},
449 	{0x367d, 0x58},
450 	{0x3674, 0xc8},
451 	{0x3675, 0x54},
452 	{0x3676, 0x18},
453 	{0x367e, 0x40},
454 	{0x367f, 0x58},
455 	{0x3677, 0x22},
456 	{0x3678, 0x53},
457 	{0x3679, 0x55},
458 	{0x36a0, 0x58},
459 	{0x36a1, 0x78},
460 	{0x3696, 0x9f},
461 	{0x3697, 0x9f},
462 	{0x3698, 0x9f},
463 	{0x301c, 0x78},
464 	{0x3037, 0x24},
465 	{0x3038, 0x44},
466 	{0x3632, 0x18},
467 	{0x4809, 0x01},
468 	{0x3625, 0x01},
469 	{0x3670, 0x6a},
470 	{0x369e, 0x40},
471 	{0x369f, 0x40},
472 	{0x3693, 0x20},
473 	{0x3694, 0x40},
474 	{0x3695, 0x40},
475 	{0x5000, 0x06},
476 	{0x5780, 0x7f},
477 	{0x57a0, 0x00},
478 	{0x57a1, 0x74},
479 	{0x57a2, 0x01},
480 	{0x57a3, 0xf4},
481 	{0x5781, 0x06},
482 	{0x5782, 0x04},
483 	{0x5783, 0x02},
484 	{0x5784, 0x01},
485 	{0x5785, 0x16},
486 	{0x5786, 0x12},
487 	{0x5787, 0x08},
488 	{0x5788, 0x02},
489 	{0x3637, 0x0c},
490 	{0x3638, 0x24},
491 	{0x3200, 0x00},
492 	{0x3201, 0x04},
493 	{0x3202, 0x00},
494 	{0x3203, 0x00},
495 	{0x3204, 0x07},
496 	{0x3205, 0x8b},
497 	{0x3206, 0x04},
498 	{0x3207, 0x3f},
499 	{0x3208, 0x07},
500 	{0x3209, 0x80},
501 	{0x320a, 0x04},
502 	{0x320b, 0x38},
503 	{0x3211, 0x04},
504 	{0x3213, 0x04},
505 	{0x3380, 0x1b},
506 	{0x3341, 0x07},
507 	{0x3343, 0x03},
508 	{0x3e25, 0x03},
509 	{0x3e26, 0x40},
510 	{0x391d, 0x24},
511 	{0x36ea, 0x2d},
512 	{0x36ed, 0x23},
513 	{0x36fa, 0x6a},
514 	{0x36fb, 0x20},
515 	{0x320c, 0x04},
516 	{0x320d, 0x76},
517 	{0x3636, 0xa8},
518 	{0x3f04, 0x02},
519 	{0x3f05, 0x33},
520 	{0x4837, 0x1a},
521 	{0x331e, 0x21},
522 	{0x3303, 0x30},
523 	{0x330b, 0xb8},
524 	{0x3306, 0x5c},
525 	{0x330e, 0x30},
526 	{0x4816, 0x51},
527 	{0x3220, 0x51},
528 	{0x4602, 0x0f},
529 	{0x33c0, 0x05},
530 	{0x6000, 0x06},
531 	{0x6002, 0x06},
532 	{0x320e, 0x0a},//{0x320e, 0x08},
533 	{0x320f, 0x66},//{0x320f, 0xaa},
534 	{0x3e00, 0x01},
535 	{0x3e01, 0x03},
536 	{0x3e02, 0xe0},
537 	{0x3e04, 0x10},
538 	{0x3e05, 0x40},
539 	{0x3e23, 0x00},
540 	{0x3e24, 0x86},
541 	{0x3e03, 0x0b},
542 	{0x3e06, 0x00},
543 	{0x3e07, 0x80},
544 	{0x3e08, 0x03},
545 	{0x3e09, 0x40},
546 	{0x3622, 0xf6},
547 	{0x3633, 0x22},
548 	{0x3630, 0xc8},
549 	{0x3301, 0x10},
550 	{0x363a, 0x83},
551 	{0x3635, 0x20},
552 	{0x36e9, 0x40},
553 	{0x36f9, 0x05},
554 	{REG_NULL, 0x00},
555 };
556 
557 /*
558  * The width and height must be configured to be
559  * the same as the current output resolution of the sensor.
560  * The input width of the isp needs to be 16 aligned.
561  * The input height of the isp needs to be 8 aligned.
562  * If the width or height does not meet the alignment rules,
563  * you can configure the cropping parameters with the following function to
564  * crop out the appropriate resolution.
565  * struct v4l2_subdev_pad_ops {
566  *	.get_selection
567  * }
568  */
569 static const struct sc2310_mode supported_modes[] = {
570 	{
571 		/* linear modes */
572 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
573 		.width = 1920,
574 		.height = 1080,
575 		.max_fps = {
576 			.numerator = 10000,
577 			.denominator = 300000,
578 		},
579 		.exp_def = 0x048c / 2,
580 		.hts_def = 0x044c * 2,
581 		.vts_def = 0x0465,
582 		.reg_list = sc2310_linear10bit_1920x1080_regs,
583 		.hdr_mode = NO_HDR,
584 		.mipi_freq_idx = 0,
585 		.bpp = 10,
586 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
587 	},
588 	{
589 		/* 2 to 1 hdr */
590 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
591 		.width = 1920,
592 		.height = 1080,
593 		.max_fps = {
594 			.numerator = 10000,
595 			.denominator = 250000,
596 		},
597 		.exp_def = 0x103e / 2,
598 		.hts_def = 0x0476 * 2,
599 		.vts_def = 0x0a66,//0x08aa
600 		.reg_list = sc2310_hdr10bit_1920x1080_regs,
601 		.hdr_mode = HDR_X2,
602 		.mipi_freq_idx = 1,
603 		.bpp = 10,
604 		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
605 		.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
606 		.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
607 		.vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
608 	},
609 };
610 
611 static const s64 link_freq_items[] = {
612 	MIPI_FREQ_186M,
613 	MIPI_FREQ_380M,
614 };
615 
616 static const char * const sc2310_test_pattern_menu[] = {
617 	"Disabled",
618 	"Vertical Color Bar Type 1"
619 };
620 
621 /* Write registers up to 4 at a time */
sc2310_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)622 static int sc2310_write_reg(struct i2c_client *client, u16 reg,
623 			    u32 len, u32 val)
624 {
625 	u32 buf_i, val_i;
626 	u8 buf[6];
627 	u8 *val_p;
628 	__be32 val_be;
629 
630 	if (len > 4)
631 		return -EINVAL;
632 
633 	buf[0] = reg >> 8;
634 	buf[1] = reg & 0xff;
635 
636 	val_be = cpu_to_be32(val);
637 	val_p = (u8 *)&val_be;
638 	buf_i = 2;
639 	val_i = 4 - len;
640 
641 	while (val_i < 4)
642 		buf[buf_i++] = val_p[val_i++];
643 
644 	if (i2c_master_send(client, buf, len + 2) != len + 2)
645 		return -EIO;
646 
647 	return 0;
648 }
649 
sc2310_write_array(struct i2c_client * client,const struct regval * regs)650 static int sc2310_write_array(struct i2c_client *client,
651 			       const struct regval *regs)
652 {
653 	u32 i;
654 	int ret = 0;
655 
656 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
657 		ret |= sc2310_write_reg(client, regs[i].addr,
658 			SC2310_REG_VALUE_08BIT, regs[i].val);
659 	}
660 	return ret;
661 }
662 
663 /* Read registers up to 4 at a time */
sc2310_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)664 static int sc2310_read_reg(struct i2c_client *client,
665 			    u16 reg,
666 			    unsigned int len,
667 			    u32 *val)
668 {
669 	struct i2c_msg msgs[2];
670 	u8 *data_be_p;
671 	__be32 data_be = 0;
672 	__be16 reg_addr_be = cpu_to_be16(reg);
673 	int ret;
674 
675 	if (len > 4 || !len)
676 		return -EINVAL;
677 
678 	data_be_p = (u8 *)&data_be;
679 	/* Write register address */
680 	msgs[0].addr = client->addr;
681 	msgs[0].flags = 0;
682 	msgs[0].len = 2;
683 	msgs[0].buf = (u8 *)&reg_addr_be;
684 
685 	/* Read data from register */
686 	msgs[1].addr = client->addr;
687 	msgs[1].flags = I2C_M_RD;
688 	msgs[1].len = len;
689 	msgs[1].buf = &data_be_p[4 - len];
690 
691 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
692 	if (ret != ARRAY_SIZE(msgs))
693 		return -EIO;
694 
695 	*val = be32_to_cpu(data_be);
696 
697 	return 0;
698 }
699 
sc2310_get_reso_dist(const struct sc2310_mode * mode,struct v4l2_mbus_framefmt * framefmt)700 static int sc2310_get_reso_dist(const struct sc2310_mode *mode,
701 				struct v4l2_mbus_framefmt *framefmt)
702 {
703 	return abs(mode->width - framefmt->width) +
704 	       abs(mode->height - framefmt->height);
705 }
706 
707 static const struct sc2310_mode *
sc2310_find_best_fit(struct sc2310 * sc2310,struct v4l2_subdev_format * fmt)708 sc2310_find_best_fit(struct sc2310 *sc2310, struct v4l2_subdev_format *fmt)
709 {
710 	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
711 	int dist;
712 	int cur_best_fit = 0;
713 	int cur_best_fit_dist = -1;
714 	unsigned int i;
715 
716 	for (i = 0; i < sc2310->cfg_num; i++) {
717 		dist = sc2310_get_reso_dist(&supported_modes[i], framefmt);
718 		if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
719 			(supported_modes[i].bus_fmt == framefmt->code)) {
720 			cur_best_fit_dist = dist;
721 			cur_best_fit = i;
722 		}
723 	}
724 
725 	return &supported_modes[cur_best_fit];
726 }
727 
sc2310_change_mode(struct sc2310 * sc2310,const struct sc2310_mode * mode)728 static void sc2310_change_mode(struct sc2310 *sc2310, const struct sc2310_mode *mode)
729 {
730 	sc2310->cur_mode = mode;
731 	sc2310->cur_vts = sc2310->cur_mode->vts_def;
732 	dev_info(&sc2310->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
733 		mode->width, mode->height, mode->hdr_mode);
734 }
735 
sc2310_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)736 static int sc2310_set_fmt(struct v4l2_subdev *sd,
737 			  struct v4l2_subdev_pad_config *cfg,
738 			  struct v4l2_subdev_format *fmt)
739 {
740 	struct sc2310 *sc2310 = to_sc2310(sd);
741 	const struct sc2310_mode *mode;
742 	s64 h_blank, vblank_def;
743 	u64 pixel_rate = 0;
744 
745 	mutex_lock(&sc2310->mutex);
746 
747 	mode = sc2310_find_best_fit(sc2310, fmt);
748 	fmt->format.code = mode->bus_fmt;
749 	fmt->format.width = mode->width;
750 	fmt->format.height = mode->height;
751 	fmt->format.field = V4L2_FIELD_NONE;
752 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
753 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
754 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
755 #else
756 		mutex_unlock(&sc2310->mutex);
757 		return -ENOTTY;
758 #endif
759 	} else {
760 		sc2310_change_mode(sc2310, mode);
761 		h_blank = mode->hts_def - mode->width;
762 		__v4l2_ctrl_modify_range(sc2310->hblank, h_blank,
763 					 h_blank, 1, h_blank);
764 		vblank_def = mode->vts_def - mode->height;
765 		__v4l2_ctrl_modify_range(sc2310->vblank, vblank_def,
766 					 SC2310_VTS_MAX - mode->height,
767 					 1, vblank_def);
768 		__v4l2_ctrl_s_ctrl(sc2310->link_freq, mode->mipi_freq_idx);
769 		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
770 			mode->bpp * 2 * SC2310_LANES;
771 		__v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate, pixel_rate);
772 		sc2310->cur_fps = mode->max_fps;
773 		sc2310->cur_vts = mode->vts_def;
774 	}
775 
776 	mutex_unlock(&sc2310->mutex);
777 
778 	return 0;
779 }
780 
sc2310_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)781 static int sc2310_get_fmt(struct v4l2_subdev *sd,
782 			  struct v4l2_subdev_pad_config *cfg,
783 			  struct v4l2_subdev_format *fmt)
784 {
785 	struct sc2310 *sc2310 = to_sc2310(sd);
786 	const struct sc2310_mode *mode = sc2310->cur_mode;
787 
788 	mutex_lock(&sc2310->mutex);
789 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
790 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
791 		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
792 #else
793 		mutex_unlock(&sc2310->mutex);
794 		return -ENOTTY;
795 #endif
796 	} else {
797 		fmt->format.width = mode->width;
798 		fmt->format.height = mode->height;
799 		fmt->format.code = mode->bus_fmt;
800 		fmt->format.field = V4L2_FIELD_NONE;
801 		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
802 			fmt->reserved[0] = mode->vc[fmt->pad];
803 		else
804 			fmt->reserved[0] = mode->vc[PAD0];
805 	}
806 	mutex_unlock(&sc2310->mutex);
807 
808 	return 0;
809 }
810 
sc2310_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)811 static int sc2310_enum_mbus_code(struct v4l2_subdev *sd,
812 				 struct v4l2_subdev_pad_config *cfg,
813 				 struct v4l2_subdev_mbus_code_enum *code)
814 {
815 	struct sc2310 *sc2310 = to_sc2310(sd);
816 
817 	if (code->index != 0)
818 		return -EINVAL;
819 	code->code = sc2310->cur_mode->bus_fmt;
820 
821 	return 0;
822 }
823 
sc2310_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)824 static int sc2310_enum_frame_sizes(struct v4l2_subdev *sd,
825 				   struct v4l2_subdev_pad_config *cfg,
826 				   struct v4l2_subdev_frame_size_enum *fse)
827 {
828 	struct sc2310 *sc2310 = to_sc2310(sd);
829 
830 	if (fse->index >= sc2310->cfg_num)
831 		return -EINVAL;
832 
833 	if (fse->code != supported_modes[fse->index].bus_fmt)
834 		return -EINVAL;
835 
836 	fse->min_width  = supported_modes[fse->index].width;
837 	fse->max_width  = supported_modes[fse->index].width;
838 	fse->max_height = supported_modes[fse->index].height;
839 	fse->min_height = supported_modes[fse->index].height;
840 
841 	return 0;
842 }
843 
sc2310_enable_test_pattern(struct sc2310 * sc2310,u32 pattern)844 static int sc2310_enable_test_pattern(struct sc2310 *sc2310, u32 pattern)
845 {
846 	u32 val = 0;
847 	int ret = 0;
848 
849 	ret = sc2310_read_reg(sc2310->client, SC2310_REG_TEST_PATTERN,
850 			      SC2310_REG_VALUE_08BIT, &val);
851 	if (pattern)
852 		val |= SC2310_TEST_PATTERN_ENABLE;
853 	else
854 		val &= ~SC2310_TEST_PATTERN_ENABLE;
855 	ret |= sc2310_write_reg(sc2310->client, SC2310_REG_TEST_PATTERN,
856 				SC2310_REG_VALUE_08BIT, val);
857 	return ret;
858 }
859 
sc2310_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)860 static int sc2310_g_frame_interval(struct v4l2_subdev *sd,
861 				   struct v4l2_subdev_frame_interval *fi)
862 {
863 	struct sc2310 *sc2310 = to_sc2310(sd);
864 	const struct sc2310_mode *mode = sc2310->cur_mode;
865 
866 	if (sc2310->streaming)
867 		fi->interval = sc2310->cur_fps;
868 	else
869 		fi->interval = mode->max_fps;
870 
871 	return 0;
872 }
873 
sc2310_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)874 static int sc2310_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
875 				struct v4l2_mbus_config *config)
876 {
877 	struct sc2310 *sc2310 = to_sc2310(sd);
878 	const struct sc2310_mode *mode = sc2310->cur_mode;
879 	u32 val = 0;
880 
881 	if (mode->hdr_mode == NO_HDR)
882 		val = 1 << (SC2310_LANES - 1) |
883 		V4L2_MBUS_CSI2_CHANNEL_0 |
884 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
885 	if (mode->hdr_mode == HDR_X2)
886 		val = 1 << (SC2310_LANES - 1) |
887 		V4L2_MBUS_CSI2_CHANNEL_0 |
888 		V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
889 		V4L2_MBUS_CSI2_CHANNEL_1;
890 
891 	config->type = V4L2_MBUS_CSI2_DPHY;
892 	config->flags = val;
893 
894 	return 0;
895 }
896 
sc2310_get_module_inf(struct sc2310 * sc2310,struct rkmodule_inf * inf)897 static void sc2310_get_module_inf(struct sc2310 *sc2310,
898 				  struct rkmodule_inf *inf)
899 {
900 	memset(inf, 0, sizeof(*inf));
901 	strlcpy(inf->base.sensor, SC2310_NAME, sizeof(inf->base.sensor));
902 	strlcpy(inf->base.module, sc2310->module_name,
903 		sizeof(inf->base.module));
904 	strlcpy(inf->base.lens, sc2310->len_name, sizeof(inf->base.lens));
905 }
906 
sc2310_get_gain_reg(u32 val,u32 * again_reg,u32 * again_fine_reg,u32 * dgain_reg,u32 * dgain_fine_reg)907 static void sc2310_get_gain_reg(u32 val, u32 *again_reg, u32 *again_fine_reg,
908 	u32 *dgain_reg, u32 *dgain_fine_reg)
909 {
910 	u8 u8Reg0x3e09 = 0x40, u8Reg0x3e08 = 0x03, u8Reg0x3e07 = 0x80, u8Reg0x3e06 = 0x00;
911 	u32 aCoarseGain = 0;
912 	u32 aFineGain = 0;
913 	u32 dCoarseGain = 0;
914 	u32 dFineGain = 0;
915 	u32 again = 0;
916 	u32 dgain = 0;
917 
918 	if (val <= 2764) {
919 		again = val;
920 		dgain = 128;
921 	} else {
922 		again = 2764;
923 		dgain = val * 128 / again;
924 	}
925 
926 	//again
927 	if (again <= 174) {
928 		//a_gain < 2.72x
929 		for (aCoarseGain = 1; aCoarseGain <= 2; aCoarseGain = aCoarseGain * 2) {
930 			//1,2,4,8,16
931 			if (again < (64 * 2 * aCoarseGain))
932 				break;
933 		}
934 
935 		aFineGain = again / aCoarseGain;
936 	} else {
937 		for (aCoarseGain = 1; aCoarseGain <= 8; aCoarseGain = aCoarseGain * 2) {
938 			//1,2,4,8
939 			if (again < (64 * 2 * aCoarseGain * 272 / 100))
940 				break;
941 		}
942 		aFineGain = 100 * again / aCoarseGain / 272;
943 	}
944 	for ( ; aCoarseGain >= 2; aCoarseGain = aCoarseGain / 2)
945 		u8Reg0x3e08 = (u8Reg0x3e08 << 1) | 0x01;
946 
947 	u8Reg0x3e09 = aFineGain;
948 
949 	//dcg = 2.72	-->		2.72*1024=2785.28
950 	u8Reg0x3e08 = (again > 174) ? (u8Reg0x3e08 | 0x20) : (u8Reg0x3e08 & 0x1f);
951 
952 	//------------------------------------------------------
953 	//dgain
954 	for (dCoarseGain = 1; dCoarseGain <= 16; dCoarseGain = dCoarseGain * 2) {
955 		//1,2,4,8,16
956 		if (dgain < (256 * dCoarseGain))
957 			break;
958 	}
959 	dFineGain = dgain / dCoarseGain;
960 
961 	for ( ; dCoarseGain >= 2; dCoarseGain = dCoarseGain / 2)
962 		u8Reg0x3e06 = (u8Reg0x3e06 << 1) | 0x01;
963 
964 	u8Reg0x3e07 = dFineGain;
965 
966 	*again_reg = u8Reg0x3e08;
967 	*again_fine_reg = u8Reg0x3e09;
968 	*dgain_reg = u8Reg0x3e06;
969 	*dgain_fine_reg = u8Reg0x3e07;
970 
971 }
972 
sc2310_set_hdrae(struct sc2310 * sc2310,struct preisp_hdrae_exp_s * ae)973 static int sc2310_set_hdrae(struct sc2310 *sc2310,
974 			     struct preisp_hdrae_exp_s *ae)
975 {
976 	struct i2c_client *client = sc2310->client;
977 	u32 l_exp_time, m_exp_time, s_exp_time;
978 	u32 l_a_gain, m_a_gain, s_a_gain;
979 	u32 l_again, l_again_fine, l_dgain, l_dgain_fine;
980 	u32 s_again, s_again_fine, s_dgain, s_dgain_fine;
981 	int ret = 0;
982 
983 	if (!sc2310->has_init_exp && !sc2310->streaming) {
984 		sc2310->init_hdrae_exp = *ae;
985 		sc2310->has_init_exp = true;
986 		dev_dbg(&client->dev, "sc2310 is not streaming, save hdr ae!\n");
987 		return ret;
988 	}
989 
990 	l_exp_time = ae->long_exp_reg;
991 	m_exp_time = ae->middle_exp_reg;
992 	s_exp_time = ae->short_exp_reg;
993 	l_a_gain = ae->long_gain_reg;
994 	m_a_gain = ae->middle_gain_reg;
995 	s_a_gain = ae->short_gain_reg;
996 	dev_dbg(&client->dev,
997 		"rev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
998 		l_exp_time, m_exp_time, s_exp_time,
999 		l_a_gain, m_a_gain, s_a_gain);
1000 
1001 	if (sc2310->cur_mode->hdr_mode == HDR_X2) {
1002 		l_a_gain = m_a_gain;
1003 		l_exp_time = m_exp_time;
1004 	}
1005 	sc2310_get_gain_reg(l_a_gain, &l_again, &l_again_fine, &l_dgain, &l_dgain_fine);
1006 	sc2310_get_gain_reg(s_a_gain, &s_again, &s_again_fine, &s_dgain, &s_dgain_fine);
1007 
1008 	l_exp_time = l_exp_time << 1;
1009 	s_exp_time = s_exp_time << 1;
1010 
1011 	if (l_exp_time > LONG_FRAME_MAX_EXP)
1012 		l_exp_time = LONG_FRAME_MAX_EXP;
1013 
1014 	if (s_exp_time > SHORT_FRAME_MAX_EXP)
1015 		s_exp_time = SHORT_FRAME_MAX_EXP;
1016 
1017 	ret |= sc2310_write_reg(sc2310->client,
1018 					SC2310_REG_EXP_LONG_L,
1019 					SC2310_REG_VALUE_08BIT,
1020 					(l_exp_time << 4 & 0XF0));
1021 	ret |= sc2310_write_reg(sc2310->client,
1022 					SC2310_REG_EXP_LONG_M,
1023 					SC2310_REG_VALUE_08BIT,
1024 					(l_exp_time >> 4 & 0XFF));
1025 	ret |= sc2310_write_reg(sc2310->client,
1026 					SC2310_REG_EXP_LONG_H,
1027 					SC2310_REG_VALUE_08BIT,
1028 					(l_exp_time >> 12 & 0X0F));
1029 
1030 	ret |= sc2310_write_reg(sc2310->client,
1031 					SC2310_REG_AGAIN,
1032 					SC2310_REG_VALUE_08BIT,
1033 					l_again);
1034 	ret |= sc2310_write_reg(sc2310->client,
1035 					SC2310_REG_AGAIN_FINE,
1036 					SC2310_REG_VALUE_08BIT,
1037 					l_again_fine);
1038 	ret |= sc2310_write_reg(sc2310->client,
1039 					SC2310_REG_DGAIN,
1040 					SC2310_REG_VALUE_08BIT,
1041 					l_dgain);
1042 	ret |= sc2310_write_reg(sc2310->client,
1043 					SC2310_REG_DGAIN_FINE,
1044 					SC2310_REG_VALUE_08BIT,
1045 					l_dgain_fine);
1046 
1047 	ret |= sc2310_write_reg(sc2310->client,
1048 					SC2310_REG_EXP_SF_L,
1049 					SC2310_REG_VALUE_08BIT,
1050 					(s_exp_time << 4 & 0XF0));
1051 	ret |= sc2310_write_reg(sc2310->client,
1052 					SC2310_REG_EXP_SF_H,
1053 					SC2310_REG_VALUE_08BIT,
1054 					(s_exp_time >> 4 & 0XFF));
1055 
1056 	ret |= sc2310_write_reg(sc2310->client,
1057 					SC2310_SF_REG_AGAIN,
1058 					SC2310_REG_VALUE_08BIT,
1059 					s_again);
1060 	ret |= sc2310_write_reg(sc2310->client,
1061 					SC2310_SF_REG_AGAIN_FINE,
1062 					SC2310_REG_VALUE_08BIT,
1063 					s_again_fine);
1064 	ret |= sc2310_write_reg(sc2310->client,
1065 					SC2310_SF_REG_DGAIN,
1066 					SC2310_REG_VALUE_08BIT,
1067 					s_dgain);
1068 	ret |= sc2310_write_reg(sc2310->client,
1069 					SC2310_SF_REG_DGAIN_FINE,
1070 					SC2310_REG_VALUE_08BIT,
1071 					s_dgain_fine);
1072 	if (ret)
1073 		return ret;
1074 	return 0;
1075 }
1076 
sc2310_get_channel_info(struct sc2310 * sc2310,struct rkmodule_channel_info * ch_info)1077 static int sc2310_get_channel_info(struct sc2310 *sc2310, struct rkmodule_channel_info *ch_info)
1078 {
1079 	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
1080 		return -EINVAL;
1081 	ch_info->vc = sc2310->cur_mode->vc[ch_info->index];
1082 	ch_info->width = sc2310->cur_mode->width;
1083 	ch_info->height = sc2310->cur_mode->height;
1084 	ch_info->bus_fmt = sc2310->cur_mode->bus_fmt;
1085 	return 0;
1086 }
1087 
sc2310_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)1088 static long sc2310_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1089 {
1090 	struct sc2310 *sc2310 = to_sc2310(sd);
1091 	struct rkmodule_hdr_cfg *hdr_cfg;
1092 	const struct sc2310_mode *mode;
1093 	struct rkmodule_channel_info *ch_info;
1094 	long ret = 0;
1095 	u64 pixel_rate = 0;
1096 	u32 i, h, w, stream;
1097 
1098 	switch (cmd) {
1099 	case PREISP_CMD_SET_HDRAE_EXP:
1100 		ret = sc2310_set_hdrae(sc2310, arg);
1101 		break;
1102 	case RKMODULE_SET_HDR_CFG:
1103 		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
1104 		if (sc2310->streaming) {
1105 			ret = sc2310_write_array(sc2310->client, sc2310->cur_mode->reg_list);
1106 			if (ret)
1107 				return ret;
1108 		}
1109 		w = sc2310->cur_mode->width;
1110 		h = sc2310->cur_mode->height;
1111 		for (i = 0; i < sc2310->cfg_num; i++) {
1112 			if (w == supported_modes[i].width &&
1113 			h == supported_modes[i].height &&
1114 			supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
1115 				sc2310_change_mode(sc2310, &supported_modes[i]);
1116 				break;
1117 			}
1118 		}
1119 
1120 		if (i == sc2310->cfg_num) {
1121 			dev_err(&sc2310->client->dev,
1122 				"not find hdr mode:%d %dx%d config\n",
1123 				hdr_cfg->hdr_mode, w, h);
1124 			ret = -EINVAL;
1125 		} else {
1126 			mode = sc2310->cur_mode;
1127 			w = mode->hts_def - mode->width;
1128 			h = mode->vts_def - mode->height;
1129 			__v4l2_ctrl_modify_range(sc2310->hblank, w, w, 1, w);
1130 			__v4l2_ctrl_modify_range(sc2310->vblank, h,
1131 				SC2310_VTS_MAX - mode->height,
1132 				1, h);
1133 			__v4l2_ctrl_s_ctrl(sc2310->link_freq, mode->mipi_freq_idx);
1134 			pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
1135 				mode->bpp * 2 * SC2310_LANES;
1136 			__v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate,
1137 						 pixel_rate);
1138 			sc2310->cur_fps = mode->max_fps;
1139 			sc2310->cur_vts = mode->vts_def;
1140 			dev_info(&sc2310->client->dev,
1141 				"sensor mode: %d\n", mode->hdr_mode);
1142 		}
1143 		break;
1144 	case RKMODULE_GET_MODULE_INFO:
1145 		sc2310_get_module_inf(sc2310, (struct rkmodule_inf *)arg);
1146 		break;
1147 	case RKMODULE_GET_HDR_CFG:
1148 		hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
1149 		hdr_cfg->esp.mode = HDR_NORMAL_VC;
1150 		hdr_cfg->hdr_mode = sc2310->cur_mode->hdr_mode;
1151 		break;
1152 	case RKMODULE_SET_QUICK_STREAM:
1153 
1154 		stream = *((u32 *)arg);
1155 
1156 		if (stream)
1157 			ret = sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE,
1158 				SC2310_REG_VALUE_08BIT, SC2310_MODE_STREAMING);
1159 		else
1160 			ret = sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE,
1161 				SC2310_REG_VALUE_08BIT, SC2310_MODE_SW_STANDBY);
1162 		break;
1163 	case RKMODULE_GET_CHANNEL_INFO:
1164 		ch_info = (struct rkmodule_channel_info *)arg;
1165 		ret = sc2310_get_channel_info(sc2310, ch_info);
1166 		break;
1167 	default:
1168 		ret = -ENOIOCTLCMD;
1169 		break;
1170 	}
1171 
1172 	return ret;
1173 }
1174 
1175 #ifdef CONFIG_COMPAT
sc2310_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)1176 static long sc2310_compat_ioctl32(struct v4l2_subdev *sd,
1177 				  unsigned int cmd, unsigned long arg)
1178 {
1179 	void __user *up = compat_ptr(arg);
1180 	struct rkmodule_inf *inf;
1181 	struct rkmodule_awb_cfg *cfg;
1182 	struct rkmodule_hdr_cfg *hdr;
1183 	struct preisp_hdrae_exp_s *hdrae;
1184 	struct rkmodule_channel_info *ch_info;
1185 	long ret = 0;
1186 	u32 cg = 0;
1187 	u32 stream = 0;
1188 
1189 	switch (cmd) {
1190 	case RKMODULE_GET_MODULE_INFO:
1191 		inf = kzalloc(sizeof(*inf), GFP_KERNEL);
1192 		if (!inf) {
1193 			ret = -ENOMEM;
1194 			return ret;
1195 		}
1196 
1197 		ret = sc2310_ioctl(sd, cmd, inf);
1198 		if (!ret) {
1199 			if (copy_to_user(up, inf, sizeof(*inf))) {
1200 				kfree(inf);
1201 				return -EFAULT;
1202 			}
1203 		}
1204 		kfree(inf);
1205 		break;
1206 	case RKMODULE_AWB_CFG:
1207 		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1208 		if (!cfg) {
1209 			ret = -ENOMEM;
1210 			return ret;
1211 		}
1212 
1213 		if (copy_from_user(cfg, up, sizeof(*cfg))) {
1214 			kfree(cfg);
1215 			return -EFAULT;
1216 		}
1217 		ret = sc2310_ioctl(sd, cmd, cfg);
1218 		kfree(cfg);
1219 		break;
1220 	case RKMODULE_GET_HDR_CFG:
1221 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1222 		if (!hdr) {
1223 			ret = -ENOMEM;
1224 			return ret;
1225 		}
1226 
1227 		ret = sc2310_ioctl(sd, cmd, hdr);
1228 		if (!ret) {
1229 			if (copy_to_user(up, hdr, sizeof(*hdr))) {
1230 				kfree(hdr);
1231 				return -EFAULT;
1232 			}
1233 		}
1234 		kfree(hdr);
1235 		break;
1236 	case RKMODULE_SET_HDR_CFG:
1237 		hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1238 		if (!hdr) {
1239 			ret = -ENOMEM;
1240 			return ret;
1241 		}
1242 
1243 		if (copy_from_user(hdr, up, sizeof(*hdr))) {
1244 			kfree(hdr);
1245 			return -EFAULT;
1246 		}
1247 		ret = sc2310_ioctl(sd, cmd, hdr);
1248 		kfree(hdr);
1249 		break;
1250 	case PREISP_CMD_SET_HDRAE_EXP:
1251 		hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
1252 		if (!hdrae) {
1253 			ret = -ENOMEM;
1254 			return ret;
1255 		}
1256 
1257 		if (copy_from_user(hdrae, up, sizeof(*hdrae))) {
1258 			kfree(hdrae);
1259 			return -EFAULT;
1260 		}
1261 		ret = sc2310_ioctl(sd, cmd, hdrae);
1262 		kfree(hdrae);
1263 		break;
1264 	case RKMODULE_SET_CONVERSION_GAIN:
1265 		if (copy_from_user(&cg, up, sizeof(cg)))
1266 			return -EFAULT;
1267 		ret = sc2310_ioctl(sd, cmd, &cg);
1268 		break;
1269 	case RKMODULE_SET_QUICK_STREAM:
1270 		if (copy_from_user(&stream, up, sizeof(u32)))
1271 			return -EFAULT;
1272 		ret = sc2310_ioctl(sd, cmd, &stream);
1273 		break;
1274 	case RKMODULE_GET_CHANNEL_INFO:
1275 		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
1276 		if (!ch_info) {
1277 			ret = -ENOMEM;
1278 			return ret;
1279 		}
1280 
1281 		ret = sc2310_ioctl(sd, cmd, ch_info);
1282 		if (!ret) {
1283 			ret = copy_to_user(up, ch_info, sizeof(*ch_info));
1284 			if (ret)
1285 				ret = -EFAULT;
1286 		}
1287 		kfree(ch_info);
1288 		break;
1289 	default:
1290 		ret = -ENOIOCTLCMD;
1291 		break;
1292 	}
1293 
1294 	return ret;
1295 }
1296 #endif
1297 
__sc2310_start_stream(struct sc2310 * sc2310)1298 static int __sc2310_start_stream(struct sc2310 *sc2310)
1299 {
1300 	int ret;
1301 
1302 	ret = sc2310_write_array(sc2310->client, sc2310->cur_mode->reg_list);
1303 	if (ret)
1304 		return ret;
1305 
1306 	ret = __v4l2_ctrl_handler_setup(&sc2310->ctrl_handler);
1307 	if (ret)
1308 		return ret;
1309 
1310 	/* In case these controls are set before streaming */
1311 	if (sc2310->has_init_exp && sc2310->cur_mode->hdr_mode != NO_HDR) {
1312 		ret = sc2310_ioctl(&sc2310->subdev, PREISP_CMD_SET_HDRAE_EXP,
1313 			&sc2310->init_hdrae_exp);
1314 		if (ret) {
1315 			dev_err(&sc2310->client->dev,
1316 				"init exp fail in hdr mode\n");
1317 			return ret;
1318 		}
1319 	}
1320 
1321 	return sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE,
1322 		SC2310_REG_VALUE_08BIT, SC2310_MODE_STREAMING);
1323 }
1324 
__sc2310_stop_stream(struct sc2310 * sc2310)1325 static int __sc2310_stop_stream(struct sc2310 *sc2310)
1326 {
1327 	sc2310->has_init_exp = false;
1328 	return sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE,
1329 		SC2310_REG_VALUE_08BIT, SC2310_MODE_SW_STANDBY);
1330 }
1331 
sc2310_s_stream(struct v4l2_subdev * sd,int on)1332 static int sc2310_s_stream(struct v4l2_subdev *sd, int on)
1333 {
1334 	struct sc2310 *sc2310 = to_sc2310(sd);
1335 	struct i2c_client *client = sc2310->client;
1336 	int ret = 0;
1337 
1338 	mutex_lock(&sc2310->mutex);
1339 	on = !!on;
1340 	if (on == sc2310->streaming)
1341 		goto unlock_and_return;
1342 
1343 	if (on) {
1344 		ret = pm_runtime_get_sync(&client->dev);
1345 		if (ret < 0) {
1346 			pm_runtime_put_noidle(&client->dev);
1347 			goto unlock_and_return;
1348 		}
1349 
1350 		ret = __sc2310_start_stream(sc2310);
1351 		if (ret) {
1352 			v4l2_err(sd, "start stream failed while write regs\n");
1353 			pm_runtime_put(&client->dev);
1354 			goto unlock_and_return;
1355 		}
1356 	} else {
1357 		__sc2310_stop_stream(sc2310);
1358 		pm_runtime_put(&client->dev);
1359 	}
1360 
1361 	sc2310->streaming = on;
1362 
1363 unlock_and_return:
1364 	mutex_unlock(&sc2310->mutex);
1365 
1366 	return ret;
1367 }
1368 
sc2310_s_power(struct v4l2_subdev * sd,int on)1369 static int sc2310_s_power(struct v4l2_subdev *sd, int on)
1370 {
1371 	struct sc2310 *sc2310 = to_sc2310(sd);
1372 	struct i2c_client *client = sc2310->client;
1373 	int ret = 0;
1374 
1375 	mutex_lock(&sc2310->mutex);
1376 
1377 	/* If the power state is not modified - no work to do. */
1378 	if (sc2310->power_on == !!on)
1379 		goto unlock_and_return;
1380 
1381 	if (on) {
1382 		ret = pm_runtime_get_sync(&client->dev);
1383 		if (ret < 0) {
1384 			pm_runtime_put_noidle(&client->dev);
1385 			goto unlock_and_return;
1386 		}
1387 
1388 		ret |= sc2310_write_reg(sc2310->client,
1389 			SC2310_SOFTWARE_RESET_REG,
1390 			SC2310_REG_VALUE_08BIT,
1391 			0x01);
1392 		usleep_range(100, 200);
1393 		ret |= sc2310_write_reg(sc2310->client,
1394 			0x303f,
1395 			SC2310_REG_VALUE_08BIT,
1396 			0x01);
1397 
1398 		sc2310->power_on = true;
1399 	} else {
1400 		pm_runtime_put(&client->dev);
1401 		sc2310->power_on = false;
1402 	}
1403 
1404 unlock_and_return:
1405 	mutex_unlock(&sc2310->mutex);
1406 
1407 	return ret;
1408 }
1409 
__sc2310_power_on(struct sc2310 * sc2310)1410 static int __sc2310_power_on(struct sc2310 *sc2310)
1411 {
1412 	int ret;
1413 	struct device *dev = &sc2310->client->dev;
1414 
1415 	if (!IS_ERR_OR_NULL(sc2310->pins_default)) {
1416 		ret = pinctrl_select_state(sc2310->pinctrl,
1417 					   sc2310->pins_default);
1418 		if (ret < 0)
1419 			dev_err(dev, "could not set pins\n");
1420 	}
1421 	ret = clk_set_rate(sc2310->xvclk, SC2310_XVCLK_FREQ);
1422 	if (ret < 0)
1423 		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
1424 	if (clk_get_rate(sc2310->xvclk) != SC2310_XVCLK_FREQ)
1425 		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
1426 	ret = clk_prepare_enable(sc2310->xvclk);
1427 	if (ret < 0) {
1428 		dev_err(dev, "Failed to enable xvclk\n");
1429 		return ret;
1430 	}
1431 	if (!IS_ERR(sc2310->reset_gpio))
1432 		gpiod_set_value_cansleep(sc2310->reset_gpio, 1);
1433 
1434 	ret = regulator_bulk_enable(SC2310_NUM_SUPPLIES, sc2310->supplies);
1435 	if (ret < 0) {
1436 		dev_err(dev, "Failed to enable regulators\n");
1437 		goto disable_clk;
1438 	}
1439 
1440 	if (!IS_ERR(sc2310->reset_gpio))
1441 		gpiod_set_value_cansleep(sc2310->reset_gpio, 0);
1442 
1443 	usleep_range(500, 1000);
1444 	if (!IS_ERR(sc2310->pwdn_gpio))
1445 		gpiod_set_value_cansleep(sc2310->pwdn_gpio, 0);
1446 	usleep_range(2000, 4000);
1447 
1448 	return 0;
1449 
1450 disable_clk:
1451 	clk_disable_unprepare(sc2310->xvclk);
1452 
1453 	return ret;
1454 }
1455 
__sc2310_power_off(struct sc2310 * sc2310)1456 static void __sc2310_power_off(struct sc2310 *sc2310)
1457 {
1458 	int ret;
1459 	struct device *dev = &sc2310->client->dev;
1460 
1461 	if (!IS_ERR(sc2310->pwdn_gpio))
1462 		gpiod_set_value_cansleep(sc2310->pwdn_gpio, 1);
1463 	clk_disable_unprepare(sc2310->xvclk);
1464 	if (!IS_ERR(sc2310->reset_gpio))
1465 		gpiod_set_value_cansleep(sc2310->reset_gpio, 1);
1466 	if (!IS_ERR_OR_NULL(sc2310->pins_sleep)) {
1467 		ret = pinctrl_select_state(sc2310->pinctrl,
1468 					   sc2310->pins_sleep);
1469 		if (ret < 0)
1470 			dev_dbg(dev, "could not set pins\n");
1471 	}
1472 	regulator_bulk_disable(SC2310_NUM_SUPPLIES, sc2310->supplies);
1473 }
1474 
sc2310_runtime_resume(struct device * dev)1475 static int sc2310_runtime_resume(struct device *dev)
1476 {
1477 	struct i2c_client *client = to_i2c_client(dev);
1478 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1479 	struct sc2310 *sc2310 = to_sc2310(sd);
1480 
1481 	return __sc2310_power_on(sc2310);
1482 }
1483 
sc2310_runtime_suspend(struct device * dev)1484 static int sc2310_runtime_suspend(struct device *dev)
1485 {
1486 	struct i2c_client *client = to_i2c_client(dev);
1487 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1488 	struct sc2310 *sc2310 = to_sc2310(sd);
1489 
1490 	__sc2310_power_off(sc2310);
1491 
1492 	return 0;
1493 }
1494 
1495 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sc2310_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)1496 static int sc2310_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1497 {
1498 	struct sc2310 *sc2310 = to_sc2310(sd);
1499 	struct v4l2_mbus_framefmt *try_fmt =
1500 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
1501 	const struct sc2310_mode *def_mode = &supported_modes[0];
1502 
1503 	mutex_lock(&sc2310->mutex);
1504 	/* Initialize try_fmt */
1505 	try_fmt->width = def_mode->width;
1506 	try_fmt->height = def_mode->height;
1507 	try_fmt->code = def_mode->bus_fmt;
1508 	try_fmt->field = V4L2_FIELD_NONE;
1509 
1510 	mutex_unlock(&sc2310->mutex);
1511 	/* No crop or compose */
1512 
1513 	return 0;
1514 }
1515 #endif
1516 
sc2310_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)1517 static int sc2310_enum_frame_interval(struct v4l2_subdev *sd,
1518 				       struct v4l2_subdev_pad_config *cfg,
1519 				       struct v4l2_subdev_frame_interval_enum *fie)
1520 {
1521 	struct sc2310 *sc2310 = to_sc2310(sd);
1522 
1523 	if (fie->index >= sc2310->cfg_num)
1524 		return -EINVAL;
1525 
1526 	fie->code = supported_modes[fie->index].bus_fmt;
1527 	fie->width = supported_modes[fie->index].width;
1528 	fie->height = supported_modes[fie->index].height;
1529 	fie->interval = supported_modes[fie->index].max_fps;
1530 	fie->reserved[0] = supported_modes[fie->index].hdr_mode;
1531 	return 0;
1532 }
1533 
1534 static const struct dev_pm_ops sc2310_pm_ops = {
1535 	SET_RUNTIME_PM_OPS(sc2310_runtime_suspend,
1536 			   sc2310_runtime_resume, NULL)
1537 };
1538 
1539 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1540 static const struct v4l2_subdev_internal_ops sc2310_internal_ops = {
1541 	.open = sc2310_open,
1542 };
1543 #endif
1544 
1545 static const struct v4l2_subdev_core_ops sc2310_core_ops = {
1546 	.s_power = sc2310_s_power,
1547 	.ioctl = sc2310_ioctl,
1548 #ifdef CONFIG_COMPAT
1549 	.compat_ioctl32 = sc2310_compat_ioctl32,
1550 #endif
1551 };
1552 
1553 static const struct v4l2_subdev_video_ops sc2310_video_ops = {
1554 	.s_stream = sc2310_s_stream,
1555 	.g_frame_interval = sc2310_g_frame_interval,
1556 };
1557 
1558 static const struct v4l2_subdev_pad_ops sc2310_pad_ops = {
1559 	.enum_mbus_code = sc2310_enum_mbus_code,
1560 	.enum_frame_size = sc2310_enum_frame_sizes,
1561 	.enum_frame_interval = sc2310_enum_frame_interval,
1562 	.get_fmt = sc2310_get_fmt,
1563 	.set_fmt = sc2310_set_fmt,
1564 	.get_mbus_config = sc2310_g_mbus_config,
1565 };
1566 
1567 static const struct v4l2_subdev_ops sc2310_subdev_ops = {
1568 	.core	= &sc2310_core_ops,   /* v4l2_subdev_core_ops sc2310_core_ops */
1569 	.video	= &sc2310_video_ops,  /* */
1570 	.pad	= &sc2310_pad_ops,    /* */
1571 };
1572 
sc2310_modify_fps_info(struct sc2310 * sc2310)1573 static void sc2310_modify_fps_info(struct sc2310 *sc2310)
1574 {
1575 	const struct sc2310_mode *mode = sc2310->cur_mode;
1576 
1577 	sc2310->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1578 				      sc2310->cur_vts;
1579 }
1580 
sc2310_set_ctrl(struct v4l2_ctrl * ctrl)1581 static int sc2310_set_ctrl(struct v4l2_ctrl *ctrl)
1582 {
1583 	struct sc2310 *sc2310 = container_of(ctrl->handler,
1584 					     struct sc2310, ctrl_handler);
1585 	struct i2c_client *client = sc2310->client;
1586 	s64 max;
1587 	u32 again, again_fine, dgain, dgain_fine;
1588 	int ret = 0;
1589 	u32 val;
1590 
1591 	/* Propagate change of current control to all related controls */
1592 	switch (ctrl->id) {
1593 	case V4L2_CID_VBLANK:
1594 		/* Update max exposure while meeting expected vblanking */
1595 		max = sc2310->cur_mode->height + ctrl->val - 3;
1596 		__v4l2_ctrl_modify_range(sc2310->exposure,
1597 					 sc2310->exposure->minimum, max,
1598 					 sc2310->exposure->step,
1599 					 sc2310->exposure->default_value);
1600 		break;
1601 	}
1602 
1603 	if (!pm_runtime_get_if_in_use(&client->dev))
1604 		return 0;
1605 
1606 	switch (ctrl->id) {
1607 	case V4L2_CID_EXPOSURE:
1608 		if (sc2310->cur_mode->hdr_mode != NO_HDR)
1609 			goto out_ctrl;
1610 		val = ctrl->val << 1;
1611 		ret = sc2310_write_reg(sc2310->client,
1612 					SC2310_REG_EXP_LONG_L,
1613 					SC2310_REG_VALUE_08BIT,
1614 					(val << 4 & 0XF0));
1615 		ret |= sc2310_write_reg(sc2310->client,
1616 					SC2310_REG_EXP_LONG_M,
1617 					SC2310_REG_VALUE_08BIT,
1618 					(val >> 4 & 0XFF));
1619 		ret |= sc2310_write_reg(sc2310->client,
1620 					SC2310_REG_EXP_LONG_H,
1621 					SC2310_REG_VALUE_08BIT,
1622 					(val >> 12 & 0X0F));
1623 		dev_dbg(&client->dev, "set exposure 0x%x\n", val);
1624 		break;
1625 
1626 	case V4L2_CID_ANALOGUE_GAIN:
1627 		if (sc2310->cur_mode->hdr_mode != NO_HDR)
1628 			goto out_ctrl;
1629 		sc2310_get_gain_reg(ctrl->val, &again, &again_fine, &dgain, &dgain_fine);
1630 		dev_dbg(&client->dev, "recv:%d set again 0x%x, again_fine 0x%x, set dgain 0x%x, dgain_fine 0x%x\n",
1631 			ctrl->val, again, again_fine, dgain, dgain_fine);
1632 
1633 		ret |= sc2310_write_reg(sc2310->client,
1634 					SC2310_REG_AGAIN,
1635 					SC2310_REG_VALUE_08BIT,
1636 					again);
1637 		ret |= sc2310_write_reg(sc2310->client,
1638 					SC2310_REG_AGAIN_FINE,
1639 					SC2310_REG_VALUE_08BIT,
1640 					again_fine);
1641 		ret |= sc2310_write_reg(sc2310->client,
1642 					SC2310_REG_DGAIN,
1643 					SC2310_REG_VALUE_08BIT,
1644 					dgain);
1645 		ret |= sc2310_write_reg(sc2310->client,
1646 					SC2310_REG_DGAIN_FINE,
1647 					SC2310_REG_VALUE_08BIT,
1648 					dgain_fine);
1649 		break;
1650 	case V4L2_CID_VBLANK:
1651 		ret = sc2310_write_reg(sc2310->client, SC2310_REG_VTS,
1652 					SC2310_REG_VALUE_16BIT,
1653 					ctrl->val + sc2310->cur_mode->height);
1654 		if (!ret)
1655 			sc2310->cur_vts = ctrl->val + sc2310->cur_mode->height;
1656 		sc2310_modify_fps_info(sc2310);
1657 		dev_dbg(&client->dev, "set vblank 0x%x\n",
1658 			ctrl->val);
1659 		break;
1660 	case V4L2_CID_TEST_PATTERN:
1661 		ret = sc2310_enable_test_pattern(sc2310, ctrl->val);
1662 		break;
1663 	case V4L2_CID_HFLIP:
1664 		ret = sc2310_read_reg(sc2310->client, SC2310_FLIP_REG,
1665 				      SC2310_REG_VALUE_08BIT, &val);
1666 		if (ret)
1667 			break;
1668 		if (ctrl->val)
1669 			val |= SC2310_MIRROR_MASK;
1670 		else
1671 			val &= ~SC2310_MIRROR_MASK;
1672 		ret |= sc2310_write_reg(sc2310->client, SC2310_FLIP_REG,
1673 					SC2310_REG_VALUE_08BIT, val);
1674 		break;
1675 	case V4L2_CID_VFLIP:
1676 		ret = sc2310_read_reg(sc2310->client, SC2310_FLIP_REG,
1677 				      SC2310_REG_VALUE_08BIT, &val);
1678 		if (ret)
1679 			break;
1680 		if (ctrl->val)
1681 			val |= SC2310_FLIP_MASK;
1682 		else
1683 			val &= ~SC2310_FLIP_MASK;
1684 		ret |= sc2310_write_reg(sc2310->client, SC2310_FLIP_REG,
1685 					SC2310_REG_VALUE_08BIT, val);
1686 		break;
1687 	default:
1688 		dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
1689 			 __func__, ctrl->id, ctrl->val);
1690 		break;
1691 	}
1692 
1693 out_ctrl:
1694 	pm_runtime_put(&client->dev);
1695 
1696 	return ret;
1697 }
1698 
1699 static const struct v4l2_ctrl_ops sc2310_ctrl_ops = {
1700 	.s_ctrl = sc2310_set_ctrl,
1701 };
1702 
sc2310_initialize_controls(struct sc2310 * sc2310)1703 static int sc2310_initialize_controls(struct sc2310 *sc2310)
1704 {
1705 	const struct sc2310_mode *mode;
1706 	struct v4l2_ctrl_handler *handler;
1707 	s64 exposure_max, vblank_def;
1708 	u32 h_blank;
1709 	int ret;
1710 	u64 pixel_rate = 0;
1711 
1712 	handler = &sc2310->ctrl_handler;
1713 	mode = sc2310->cur_mode;
1714 	ret = v4l2_ctrl_handler_init(handler, 9);
1715 	if (ret)
1716 		return ret;
1717 	handler->lock = &sc2310->mutex;
1718 
1719 	sc2310->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
1720 			V4L2_CID_LINK_FREQ,
1721 			ARRAY_SIZE(link_freq_items) - 1, 0,
1722 			link_freq_items);
1723 	__v4l2_ctrl_s_ctrl(sc2310->link_freq, mode->mipi_freq_idx);
1724 
1725 	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
1726 	pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC2310_LANES;
1727 	sc2310->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1728 		V4L2_CID_PIXEL_RATE, 0, SC2310_MAX_PIXEL_RATE,
1729 		1, pixel_rate);
1730 
1731 	h_blank = mode->hts_def - mode->width;
1732 	sc2310->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1733 				h_blank, h_blank, 1, h_blank);
1734 	if (sc2310->hblank)
1735 		sc2310->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1736 
1737 	vblank_def = mode->vts_def - mode->height;
1738 	sc2310->vblank = v4l2_ctrl_new_std(handler, &sc2310_ctrl_ops,
1739 				V4L2_CID_VBLANK, vblank_def,
1740 				SC2310_VTS_MAX - mode->height,
1741 				1, vblank_def);
1742 
1743 	exposure_max = mode->vts_def - 3;
1744 	sc2310->exposure = v4l2_ctrl_new_std(handler, &sc2310_ctrl_ops,
1745 				V4L2_CID_EXPOSURE, SC2310_EXPOSURE_MIN,
1746 				exposure_max, SC2310_EXPOSURE_STEP,
1747 				mode->exp_def);
1748 
1749 	sc2310->anal_gain = v4l2_ctrl_new_std(handler, &sc2310_ctrl_ops,
1750 				V4L2_CID_ANALOGUE_GAIN, SC2310_GAIN_MIN,
1751 				SC2310_GAIN_MAX, SC2310_GAIN_STEP,
1752 				SC2310_GAIN_DEFAULT);
1753 
1754 	sc2310->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
1755 				&sc2310_ctrl_ops, V4L2_CID_TEST_PATTERN,
1756 				ARRAY_SIZE(sc2310_test_pattern_menu) - 1,
1757 				0, 0, sc2310_test_pattern_menu);
1758 
1759 	v4l2_ctrl_new_std(handler, &sc2310_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1760 	v4l2_ctrl_new_std(handler, &sc2310_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1761 
1762 	if (handler->error) {
1763 		ret = handler->error;
1764 		dev_err(&sc2310->client->dev,
1765 			"Failed to init controls(%d)\n", ret);
1766 		goto err_free_handler;
1767 	}
1768 
1769 	sc2310->subdev.ctrl_handler = handler;
1770 	sc2310->has_init_exp = false;
1771 	sc2310->cur_fps = mode->max_fps;
1772 	sc2310->cur_vts = mode->vts_def;
1773 
1774 	return 0;
1775 
1776 err_free_handler:
1777 	v4l2_ctrl_handler_free(handler);
1778 
1779 	return ret;
1780 }
1781 
sc2310_check_sensor_id(struct sc2310 * sc2310,struct i2c_client * client)1782 static int sc2310_check_sensor_id(struct sc2310 *sc2310,
1783 				  struct i2c_client *client)
1784 {
1785 	struct device *dev = &sc2310->client->dev;
1786 	u32 id = 0;
1787 	int ret;
1788 
1789 	ret = sc2310_read_reg(client, SC2310_REG_CHIP_ID,
1790 		SC2310_REG_VALUE_16BIT, &id);
1791 	if (id != CHIP_ID) {
1792 		dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret);
1793 		return -ENODEV;
1794 	}
1795 
1796 	dev_info(dev, "Detected SC%04x sensor\n", CHIP_ID);
1797 
1798 	return 0;
1799 }
1800 
sc2310_configure_regulators(struct sc2310 * sc2310)1801 static int sc2310_configure_regulators(struct sc2310 *sc2310)
1802 {
1803 	unsigned int i;
1804 
1805 	for (i = 0; i < SC2310_NUM_SUPPLIES; i++)
1806 		sc2310->supplies[i].supply = sc2310_supply_names[i];
1807 
1808 	return devm_regulator_bulk_get(&sc2310->client->dev,
1809 				       SC2310_NUM_SUPPLIES,
1810 				       sc2310->supplies);
1811 }
1812 
sc2310_probe(struct i2c_client * client,const struct i2c_device_id * id)1813 static int sc2310_probe(struct i2c_client *client,
1814 			const struct i2c_device_id *id)
1815 {
1816 	struct device *dev = &client->dev;
1817 	struct device_node *node = dev->of_node;
1818 	struct sc2310 *sc2310;
1819 	struct v4l2_subdev *sd;
1820 	char facing[2];
1821 	int ret;
1822 	u32 i, hdr_mode = 0;
1823 
1824 	dev_info(dev, "driver version: %02x.%02x.%02x",
1825 		DRIVER_VERSION >> 16,
1826 		(DRIVER_VERSION & 0xff00) >> 8,
1827 		DRIVER_VERSION & 0x00ff);
1828 
1829 	sc2310 = devm_kzalloc(dev, sizeof(*sc2310), GFP_KERNEL);
1830 	if (!sc2310)
1831 		return -ENOMEM;
1832 
1833 	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
1834 				   &sc2310->module_index);
1835 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
1836 				       &sc2310->module_facing);
1837 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
1838 				       &sc2310->module_name);
1839 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
1840 				       &sc2310->len_name);
1841 	if (ret) {
1842 		dev_err(dev, "could not get module information!\n");
1843 		return -EINVAL;
1844 	}
1845 
1846 	ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
1847 			&hdr_mode);
1848 
1849 	if (ret) {
1850 		hdr_mode = NO_HDR;
1851 		dev_warn(dev, " Get hdr mode failed! no hdr default\n");
1852 	}
1853 
1854 	sc2310->cfg_num = ARRAY_SIZE(supported_modes);
1855 	for (i = 0; i < sc2310->cfg_num; i++) {
1856 		if (hdr_mode == supported_modes[i].hdr_mode) {
1857 			sc2310->cur_mode = &supported_modes[i];
1858 			break;
1859 		}
1860 	}
1861 	sc2310->client = client;
1862 
1863 	sc2310->xvclk = devm_clk_get(dev, "xvclk");
1864 	if (IS_ERR(sc2310->xvclk)) {
1865 		dev_err(dev, "Failed to get xvclk\n");
1866 		return -EINVAL;
1867 	}
1868 
1869 	sc2310->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1870 	if (IS_ERR(sc2310->reset_gpio))
1871 		dev_warn(dev, "Failed to get reset-gpios\n");
1872 
1873 	sc2310->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1874 	if (IS_ERR(sc2310->pwdn_gpio))
1875 		dev_warn(dev, "Failed to get pwdn-gpios\n");
1876 
1877 	sc2310->pinctrl = devm_pinctrl_get(dev);
1878 	if (!IS_ERR(sc2310->pinctrl)) {
1879 		sc2310->pins_default =
1880 			pinctrl_lookup_state(sc2310->pinctrl,
1881 					     OF_CAMERA_PINCTRL_STATE_DEFAULT);
1882 		if (IS_ERR(sc2310->pins_default))
1883 			dev_err(dev, "could not get default pinstate\n");
1884 
1885 		sc2310->pins_sleep =
1886 			pinctrl_lookup_state(sc2310->pinctrl,
1887 					     OF_CAMERA_PINCTRL_STATE_SLEEP);
1888 		if (IS_ERR(sc2310->pins_sleep))
1889 			dev_err(dev, "could not get sleep pinstate\n");
1890 	} else {
1891 		dev_err(dev, "no pinctrl\n");
1892 	}
1893 
1894 	ret = sc2310_configure_regulators(sc2310);
1895 	if (ret) {
1896 		dev_err(dev, "Failed to get power regulators\n");
1897 		return ret;
1898 	}
1899 
1900 	mutex_init(&sc2310->mutex);
1901 
1902 	sd = &sc2310->subdev;
1903 	v4l2_i2c_subdev_init(sd, client, &sc2310_subdev_ops);
1904 	ret = sc2310_initialize_controls(sc2310);
1905 	if (ret)
1906 		goto err_destroy_mutex;
1907 
1908 	ret = __sc2310_power_on(sc2310);
1909 	if (ret)
1910 		goto err_free_handler;
1911 
1912 	ret = sc2310_check_sensor_id(sc2310, client);
1913 	if (ret)
1914 		goto err_power_off;
1915 
1916 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1917 	sd->internal_ops = &sc2310_internal_ops;
1918 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1919 #endif
1920 #if defined(CONFIG_MEDIA_CONTROLLER)
1921 	sc2310->pad.flags = MEDIA_PAD_FL_SOURCE;
1922 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1923 	ret = media_entity_pads_init(&sd->entity, 1, &sc2310->pad);
1924 	if (ret < 0)
1925 		goto err_power_off;
1926 #endif
1927 
1928 	memset(facing, 0, sizeof(facing));
1929 	if (strcmp(sc2310->module_facing, "back") == 0)
1930 		facing[0] = 'b';
1931 	else
1932 		facing[0] = 'f';
1933 
1934 	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
1935 		 sc2310->module_index, facing,
1936 		 SC2310_NAME, dev_name(sd->dev));
1937 	ret = v4l2_async_register_subdev_sensor_common(sd);
1938 	if (ret) {
1939 		dev_err(dev, "v4l2 async register subdev failed\n");
1940 		goto err_clean_entity;
1941 	}
1942 
1943 	pm_runtime_set_active(dev);
1944 	pm_runtime_enable(dev);
1945 	pm_runtime_idle(dev);
1946 #ifdef USED_SYS_DEBUG
1947 	add_sysfs_interfaces(dev);
1948 #endif
1949 	return 0;
1950 
1951 err_clean_entity:
1952 #if defined(CONFIG_MEDIA_CONTROLLER)
1953 	media_entity_cleanup(&sd->entity);
1954 #endif
1955 err_power_off:
1956 	__sc2310_power_off(sc2310);
1957 err_free_handler:
1958 	v4l2_ctrl_handler_free(&sc2310->ctrl_handler);
1959 err_destroy_mutex:
1960 	mutex_destroy(&sc2310->mutex);
1961 
1962 	return ret;
1963 }
1964 
sc2310_remove(struct i2c_client * client)1965 static int sc2310_remove(struct i2c_client *client)
1966 {
1967 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1968 	struct sc2310 *sc2310 = to_sc2310(sd);
1969 
1970 	v4l2_async_unregister_subdev(sd);
1971 #if defined(CONFIG_MEDIA_CONTROLLER)
1972 	media_entity_cleanup(&sd->entity);
1973 #endif
1974 	v4l2_ctrl_handler_free(&sc2310->ctrl_handler);
1975 	mutex_destroy(&sc2310->mutex);
1976 
1977 	pm_runtime_disable(&client->dev);
1978 	if (!pm_runtime_status_suspended(&client->dev))
1979 		__sc2310_power_off(sc2310);
1980 	pm_runtime_set_suspended(&client->dev);
1981 
1982 	return 0;
1983 }
1984 
1985 #if IS_ENABLED(CONFIG_OF)
1986 static const struct of_device_id sc2310_of_match[] = {
1987 	{ .compatible = "smartsens,sc2310" },
1988 	{ },
1989 };
1990 MODULE_DEVICE_TABLE(of, sc2310_of_match);
1991 #endif
1992 
1993 static const struct i2c_device_id sc2310_match_id[] = {
1994 	{ "smartsens,sc2310", 0 },
1995 	{ },
1996 };
1997 
1998 static struct i2c_driver sc2310_i2c_driver = {
1999 	.driver = {
2000 		.name = SC2310_NAME,
2001 		.pm = &sc2310_pm_ops,
2002 		.of_match_table = of_match_ptr(sc2310_of_match),
2003 	},
2004 	.probe		= &sc2310_probe,
2005 	.remove		= &sc2310_remove,
2006 	.id_table	= sc2310_match_id,
2007 };
2008 
2009 #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
2010 module_i2c_driver(sc2310_i2c_driver);
2011 #else
sensor_mod_init(void)2012 static int __init sensor_mod_init(void)
2013 {
2014 	return i2c_add_driver(&sc2310_i2c_driver);
2015 }
2016 
sensor_mod_exit(void)2017 static void __exit sensor_mod_exit(void)
2018 {
2019 	i2c_del_driver(&sc2310_i2c_driver);
2020 }
2021 
2022 device_initcall_sync(sensor_mod_init);
2023 module_exit(sensor_mod_exit);
2024 #endif
2025 
2026 MODULE_DESCRIPTION("Smartsens sc2310 sensor driver");
2027 MODULE_LICENSE("GPL v2");
2028