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 *)®_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