1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * ov12d2q driver
4 *
5 * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
6 *
7 * V0.0X01.0X00 first version.
8 */
9
10 #include <linux/clk.h>
11 #include <linux/device.h>
12 #include <linux/delay.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/i2c.h>
15 #include <linux/module.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/sysfs.h>
19 #include <linux/slab.h>
20 #include <linux/version.h>
21 #include <linux/rk-camera-module.h>
22 #include <media/media-entity.h>
23 #include <media/v4l2-async.h>
24 #include <media/v4l2-ctrls.h>
25 #include <media/v4l2-subdev.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/rk-preisp.h>
28 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
29
30 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
31
32 #ifndef V4L2_CID_DIGITAL_GAIN
33 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
34 #endif
35
36 #define OV12D2Q_LANES 4
37 #define OV12D2Q_BITS_PER_SAMPLE 10
38 #define MIPI_FREQ_625M 625000000LL
39 #define PIXEL_RATE_WITH_625M (MIPI_FREQ_625M * 2 * \
40 OV12D2Q_LANES / OV12D2Q_BITS_PER_SAMPLE)
41
42 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
43
44 #define OV12D2Q_XVCLK_FREQ 24000000
45
46 #define CHIP_ID 0x561441
47 #define OV12D2Q_REG_CHIP_ID 0x300a
48
49 #define OV12D2Q_REG_CTRL_MODE 0x0100
50 #define OV12D2Q_MODE_SW_STANDBY 0x0
51 #define OV12D2Q_MODE_STREAMING BIT(0)
52
53 #define OV12D2Q_EXPOSURE_MIN 8
54 #define OV12D2Q_EXPOSURE_STEP 1
55 #define OV12D2Q_VTS_MAX 0xffff
56
57 #define OV12D2Q_GAIN_MIN 0x80
58 #define OV12D2Q_GAIN_MAX 0x3df61
59 #define OV12D2Q_GAIN_STEP 1
60 #define OV12D2Q_GAIN_DEFAULT 0x80
61
62 #define OV12D2Q_REG_AGAIN_L 0x3508
63 #define OV12D2Q_REG_AGAIN_M 0x3548
64 #define OV12D2Q_REG_AGAIN_S 0x3588
65 #define OV12D2Q_REG_DGAIN_L_H_B 0x350A
66 #define OV12D2Q_REG_DGAIN_L_H_GB 0x3510
67 #define OV12D2Q_REG_DGAIN_L_H_GR 0x3513
68 #define OV12D2Q_REG_DGAIN_L_H_R 0x3516
69
70 #define OV12D2Q_REG_DGAIN_M_H_B 0x354A
71
72 #define OV12D2Q_REG_DGAIN_S_H_B 0x358A
73 #define OV12D2Q_REG_DGAIN_S_H_GB 0x3590
74 #define OV12D2Q_REG_DGAIN_S_H_GR 0x3593
75 #define OV12D2Q_REG_DGAIN_S_H_R 0x3596
76
77 #define OV12D2Q_REG_EXP_L_H 0x3501
78 #define OV12D2Q_REG_EXP_M_H 0x3541
79 #define OV12D2Q_REG_EXP_S_H 0x3581
80
81 #define OV12D2Q_SOFTWARE_RESET_REG 0x0103
82 #define OV12D2Q_REG_ISP_X_WIN 0x3810
83 #define OV12D2Q_REG_ISP_Y_WIN 0x3812
84
85 #define OV12D2Q_GROUP_UPDATE_ADDRESS 0x3208
86 #define OV12D2Q_GROUP_UPDATE_START_DATA 0x00
87 #define OV12D2Q_GROUP_UPDATE_END_DATA 0x10
88 #define OV12D2Q_GROUP_UPDATE_LAUNCH 0xA0
89
90 #define OV12D2Q_REG_TEST_PATTERN 0x5081
91 #define OV12D2Q_TEST_PATTERN_ENABLE 0x01
92 #define OV12D2Q_TEST_PATTERN_DISABLE 0x0
93
94 #define OV12D2Q_REG_VTS 0x380e
95
96 #define REG_NULL 0xFFFF
97
98 #define OV12D2Q_REG_VALUE_08BIT 1
99 #define OV12D2Q_REG_VALUE_16BIT 2
100 #define OV12D2Q_REG_VALUE_24BIT 3
101
102 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
103 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
104
105 #define OV12D2Q_NAME "ov12d2q"
106
107 static const char * const ov12d2q_supply_names[] = {
108 "avdd", /* Analog power */
109 "dovdd", /* Digital I/O power */
110 "dvdd", /* Digital core power */
111 };
112
113 #define OV12D2Q_NUM_SUPPLIES ARRAY_SIZE(ov12d2q_supply_names)
114
115 #define OV12D2Q_FLIP_REG 0x3820
116 #define OV12D2Q_MIRROR_REG 0x3821
117 #define MIRROR_BIT_MASK BIT(2)
118 #define FLIP_BIT_MASK BIT(2)
119
120 struct regval {
121 u16 addr;
122 u8 val;
123 };
124
125 struct ov12d2q_mode {
126 u32 bus_fmt;
127 u32 width;
128 u32 height;
129 struct v4l2_fract max_fps;
130 u32 hts_def;
131 u32 vts_def;
132 u32 exp_def;
133 const struct regval *reg_list;
134 u32 hdr_mode;
135 u32 vc[PAD_MAX];
136 };
137
138 struct ov12d2q {
139 struct i2c_client *client;
140 struct clk *xvclk;
141 struct gpio_desc *reset_gpio;
142 struct gpio_desc *pwdn_gpio;
143 struct regulator_bulk_data supplies[OV12D2Q_NUM_SUPPLIES];
144
145 struct pinctrl *pinctrl;
146 struct pinctrl_state *pins_default;
147 struct pinctrl_state *pins_sleep;
148
149 struct v4l2_subdev subdev;
150 struct media_pad pad;
151 struct v4l2_ctrl_handler ctrl_handler;
152 struct v4l2_ctrl *exposure;
153 struct v4l2_ctrl *anal_gain;
154 struct v4l2_ctrl *digi_gain;
155 struct v4l2_ctrl *hblank;
156 struct v4l2_ctrl *vblank;
157 struct v4l2_ctrl *test_pattern;
158 struct v4l2_ctrl *pixel_rate;
159 struct v4l2_ctrl *link_freq;
160 struct v4l2_ctrl *h_flip;
161 struct v4l2_ctrl *v_flip;
162 struct mutex mutex;
163 bool streaming;
164 bool power_on;
165 const struct ov12d2q_mode *cur_mode;
166 u32 cfg_num;
167 u32 module_index;
168 const char *module_facing;
169 const char *module_name;
170 const char *len_name;
171 bool is_thunderboot;
172 bool is_thunderboot_ng;
173 bool is_first_streamoff;
174 u8 flip;
175 };
176
177 #define to_ov12d2q(sd) container_of(sd, struct ov12d2q, subdev)
178
179 /*
180 * Xclk 24Mhz
181 */
182 static const struct regval ov12d2q_global_regs[] = {
183 {REG_NULL, 0x00},
184 };
185
186
187 /*
188 * Xclk 24Mhz
189 * max_framerate 60fps
190 */
191 static const struct regval ov12d2q_2256x1256_regs[] = {
192 {0x0301, 0xc0},
193 {0x0302, 0x01},
194 {0x0303, 0x06},
195 {0x0304, 0x02},
196 {0x0305, 0x71},
197 {0x0306, 0x04},
198 {0x0307, 0x00},
199 {0x0309, 0x01},
200 {0x0320, 0x20},
201 {0x0323, 0x06},
202 {0x0324, 0x01},
203 {0x0325, 0xc2},
204 {0x0326, 0xd3},
205 {0x032b, 0x06},
206 {0x0343, 0x06},
207 {0x0344, 0x01},
208 {0x0345, 0xb8},
209 {0x0346, 0xcb},
210 {0x0350, 0x02},
211 {0x0360, 0x09},
212 {0x3002, 0x80},
213 {0x300d, 0x11},
214 {0x300e, 0x11},
215 {0x3012, 0x41},
216 {0x3016, 0xf0},
217 {0x3017, 0xd0},
218 {0x3018, 0xf0},
219 {0x3019, 0xc2},
220 {0x301a, 0xf0},
221 {0x301b, 0x34},
222 {0x301c, 0x91},
223 {0x301d, 0x02},
224 {0x301e, 0x98},
225 {0x301f, 0x21},
226 {0x3022, 0xf0},
227 {0x3027, 0x2e},
228 {0x302c, 0x01},
229 {0x302d, 0x00},
230 {0x302e, 0x00},
231 {0x302f, 0x00},
232 {0x3030, 0x03},
233 {0x3044, 0xc2},
234 {0x304b, 0x00},
235 {0x30d4, 0x00},
236 {0x3209, 0x00},
237 {0x320a, 0x00},
238 {0x320b, 0x00},
239 {0x320c, 0x00},
240 {0x320d, 0x01},
241 {0x3216, 0x01},
242 {0x3218, 0x80},
243 {0x33c0, 0x00},
244 {0x33c3, 0x00},
245 {0x33c4, 0x00},
246 {0x3400, 0x04},
247 {0x3408, 0x05},
248 {0x340c, 0x10},
249 {0x340e, 0x30},
250 {0x3421, 0x08},
251 {0x3422, 0x00},
252 {0x3423, 0x15},
253 {0x3424, 0x40},
254 {0x3425, 0x10},
255 {0x3426, 0x20},
256 {0x3500, 0x00},
257 {0x3501, 0x05},
258 {0x3502, 0x60},
259 {0x3504, 0x08},
260 {0x3508, 0x01},
261 {0x3509, 0x00},
262 {0x350a, 0x01},
263 {0x350b, 0x00},
264 {0x350c, 0x00},
265 {0x350e, 0x00},
266 {0x3510, 0x01},
267 {0x3511, 0x00},
268 {0x3512, 0x00},
269 {0x3513, 0x01},
270 {0x3514, 0x00},
271 {0x3515, 0x00},
272 {0x3516, 0x01},
273 {0x3517, 0x00},
274 {0x3518, 0x00},
275 {0x352d, 0x00},
276 {0x352e, 0x00},
277 {0x352f, 0x00},
278 {0x3541, 0x00},
279 {0x3542, 0x40},
280 {0x3548, 0x01},
281 {0x3549, 0x00},
282 {0x354a, 0x01},
283 {0x354b, 0x00},
284 {0x354c, 0x00},
285 {0x354e, 0x80},
286 {0x3550, 0x01},
287 {0x3551, 0x00},
288 {0x3552, 0x00},
289 {0x3581, 0x00},
290 {0x3582, 0x40},
291 {0x3588, 0x01},
292 {0x3589, 0x00},
293 {0x358a, 0x01},
294 {0x358b, 0x00},
295 {0x358c, 0x00},
296 {0x3590, 0x01},
297 {0x3591, 0x00},
298 {0x3592, 0x00},
299 {0x3610, 0x80},
300 {0x3615, 0x27},
301 {0x3617, 0x5a},
302 {0x3624, 0x88},
303 {0x3628, 0x77},
304 {0x3644, 0x20},
305 {0x3652, 0x00},
306 {0x3653, 0x00},
307 {0x3663, 0x6b},
308 {0x3660, 0x4f},
309 {0x3661, 0xd0},
310 {0x3662, 0x09},
311 {0x3680, 0xc1},
312 {0x3683, 0x80},
313 {0x3684, 0x03},
314 {0x3685, 0x52},
315 {0x3687, 0xd2},
316 {0x3689, 0x27},
317 {0x368a, 0x38},
318 {0x368b, 0x08},
319 {0x368c, 0x06},
320 {0x368e, 0x00},
321 {0x3692, 0x00},
322 {0x3693, 0x00},
323 {0x3696, 0x26},
324 {0x3697, 0x1f},
325 {0x3698, 0x1d},
326 {0x3699, 0x59},
327 {0x369a, 0x01},
328 {0x369b, 0x20},
329 {0x3700, 0x2e},
330 {0x3701, 0x06},
331 {0x3702, 0x4f},
332 {0x3703, 0x28},
333 {0x3704, 0x07},
334 {0x3705, 0x00},
335 {0x3706, 0x2f},
336 {0x3707, 0x08},
337 {0x3708, 0x2d},
338 {0x3709, 0x5d},
339 {0x370a, 0x00},
340 {0x370b, 0x69},
341 {0x370c, 0x0c},
342 {0x3711, 0x30},
343 {0x3712, 0x00},
344 {0x3713, 0x00},
345 {0x3714, 0x63},
346 {0x371a, 0x1c},
347 {0x371b, 0xd0},
348 {0x371c, 0x04},
349 {0x371d, 0x24},
350 {0x371e, 0x13},
351 {0x371f, 0x0c},
352 {0x3720, 0x08},
353 {0x3721, 0x15},
354 {0x3724, 0x08},
355 {0x3725, 0x32},
356 {0x3727, 0x22},
357 {0x3728, 0x11},
358 {0x3729, 0x00},
359 {0x372a, 0x00},
360 {0x372b, 0x00},
361 {0x3752, 0x02},
362 {0x3753, 0x03},
363 {0x3754, 0xee},
364 {0x3760, 0x04},
365 {0x3761, 0x14},
366 {0x3762, 0x04},
367 {0x3765, 0x08},
368 {0x3766, 0x0c},
369 {0x3767, 0x00},
370 {0x376a, 0x00},
371 {0x376b, 0x00},
372 {0x376d, 0x1b},
373 {0x376f, 0x02},
374 {0x37d9, 0x08},
375 {0x37f6, 0x07},
376 {0x37f7, 0x04},
377 {0x37f8, 0x2d},
378 {0x37f9, 0x02},
379 {0x37fa, 0x02},
380 {0x37fb, 0x02},
381 {0x3800, 0x00},
382 {0x3801, 0x00},
383 {0x3802, 0x00},
384 {0x3803, 0x40},
385 {0x3804, 0x12},
386 {0x3805, 0x1f},
387 {0x3806, 0x0a},
388 {0x3807, 0x1f},
389 {0x3808, 0x08},
390 {0x3809, 0xd0},
391 {0x380a, 0x04},
392 {0x380b, 0xe8},
393 {0x380c, 0x02},
394 {0x380d, 0x1b},
395 {0x380e, 0x05},
396 {0x380f, 0x70},
397 {0x3810, 0x00},
398 {0x3811, 0x21},
399 {0x3812, 0x00},
400 {0x3813, 0x04},
401 {0x3814, 0x22},
402 {0x3815, 0x22},
403 {0x381a, 0x00},
404 {0x381b, 0x01},
405 {0x381e, 0x00},
406 {0x381f, 0x02},
407 {0x3820, 0x01},
408 {0x3821, 0x0d},
409 {0x3822, 0x00},
410 {0x3823, 0x04},
411 {0x3824, 0x00},
412 {0x3825, 0x00},
413 {0x3826, 0x00},
414 {0x3827, 0x64},
415 {0x3828, 0xf7},
416 {0x382a, 0x83},
417 {0x382c, 0x00},
418 {0x382d, 0x00},
419 {0x3835, 0x00},
420 {0x3836, 0x00},
421 {0x3837, 0x08},
422 {0x3839, 0x00},
423 {0x383b, 0x00},
424 {0x383c, 0x00},
425 {0x383d, 0x08},
426 {0x383e, 0x00},
427 {0x383f, 0x33},
428 {0x3842, 0x00},
429 {0x3856, 0x00},
430 {0x3857, 0x08},
431 {0x3858, 0x00},
432 {0x3859, 0x10},
433 {0x3865, 0x70},
434 {0x3867, 0x08},
435 {0x3868, 0x00},
436 {0x3904, 0x33},
437 {0x3907, 0x33},
438 {0x390a, 0x9a},
439 {0x3914, 0x34},
440 {0x3938, 0x4b},
441 {0x3939, 0x0c},
442 {0x393b, 0x4b},
443 {0x393c, 0x0c},
444 {0x393e, 0x40},
445 {0x393f, 0x0c},
446 {0x3975, 0x05},
447 {0x3979, 0x32},
448 {0x397d, 0x69},
449 {0x3981, 0x15},
450 {0x3983, 0x33},
451 {0x3985, 0x1a},
452 {0x3986, 0x08},
453 {0x398a, 0x09},
454 {0x39cd, 0x00},
455 {0x39ce, 0x24},
456 {0x39cf, 0x40},
457 {0x39d0, 0x0a},
458 {0x39d1, 0x50},
459 {0x39d2, 0x05},
460 {0x39d3, 0x94},
461 {0x39d4, 0x01},
462 {0x39d5, 0x79},
463 {0x3a12, 0x00},
464 {0x3a13, 0x00},
465 {0x3a14, 0x00},
466 {0x3a15, 0x00},
467 {0x3a16, 0x00},
468 {0x3a18, 0x04},
469 {0x3a1a, 0x05},
470 {0x3a1c, 0x0a},
471 {0x3a1e, 0x03},
472 {0x3a1f, 0x34},
473 {0x3a22, 0x12},
474 {0x3a24, 0x00},
475 {0x3a25, 0xfe},
476 {0x3a26, 0x01},
477 {0x3a27, 0x01},
478 {0x3a2a, 0xa8},
479 {0x3a2b, 0xa8},
480 {0x3a36, 0x00},
481 {0x3d84, 0x00},
482 {0x3d85, 0x1b},
483 {0x3d88, 0x00},
484 {0x3d89, 0x00},
485 {0x3d8a, 0x03},
486 {0x3d8b, 0xff},
487 {0x3d8c, 0xa3},
488 {0x3d8d, 0xc4},
489 {0x3da4, 0x04},
490 {0x3daa, 0xa0},
491 {0x3dab, 0x10},
492 {0x3dac, 0xa1},
493 {0x3dad, 0x8c},
494 {0x3dae, 0xa1},
495 {0x3daf, 0xb3},
496 {0x3e00, 0x0e},
497 {0x3e01, 0x0e},
498 {0x3e02, 0x0e},
499 {0x3e03, 0x0e},
500 {0x3e04, 0x0e},
501 {0x3e05, 0x0e},
502 {0x3e06, 0x0e},
503 {0x3e07, 0x0e},
504 {0x3e09, 0x47},
505 {0x3e0b, 0x25},
506 {0x3e0d, 0x13},
507 {0x3e0f, 0x09},
508 {0x3e11, 0x07},
509 {0x3e13, 0x06},
510 {0x3e15, 0x05},
511 {0x3e17, 0x04},
512 {0x3e18, 0x38},
513 {0x3e19, 0x38},
514 {0x3e1a, 0x13},
515 {0x3e1b, 0x30},
516 {0x3e1c, 0x07},
517 {0x3e1d, 0x06},
518 {0x3e1e, 0x05},
519 {0x3e1f, 0x04},
520 {0x3e20, 0x0f},
521 {0x3e21, 0x0f},
522 {0x3e22, 0x0f},
523 {0x3e23, 0x0f},
524 {0x3e24, 0x0f},
525 {0x3e25, 0x0f},
526 {0x3e26, 0x0f},
527 {0x3e27, 0x0f},
528 {0x3e28, 0x07},
529 {0x3e29, 0x07},
530 {0x3e2a, 0x07},
531 {0x3e2b, 0x02},
532 {0x3e2c, 0x07},
533 {0x3e2d, 0x07},
534 {0x3e30, 0x07},
535 {0x3e3a, 0x02},
536 {0x3e3b, 0xdf},
537 {0x3e3c, 0xff},
538 {0x3e3d, 0x44},
539 {0x3e3e, 0x00},
540 {0x3e3f, 0x00},
541 {0x3e40, 0xc1},
542 {0x3e42, 0x54},
543 {0x3e43, 0x54},
544 {0x3e44, 0x54},
545 {0x3e45, 0x54},
546 {0x3f00, 0x10},
547 {0x3f01, 0x26},
548 {0x3f03, 0x40},
549 {0x4002, 0xf3},
550 {0x4009, 0x02},
551 {0x400e, 0xc6},
552 {0x400f, 0x00},
553 {0x4010, 0x28},
554 {0x4011, 0x01},
555 {0x4012, 0x0d},
556 {0x4015, 0x02},
557 {0x4016, 0x11},
558 {0x4017, 0x00},
559 {0x4018, 0x03},
560 {0x401a, 0x40},
561 {0x401e, 0x00},
562 {0x401f, 0xcc},
563 {0x4020, 0x04},
564 {0x4021, 0x00},
565 {0x4022, 0x04},
566 {0x4023, 0x00},
567 {0x4024, 0x04},
568 {0x4025, 0x00},
569 {0x4026, 0x04},
570 {0x4027, 0x00},
571 {0x4028, 0x01},
572 {0x4030, 0x00},
573 {0x4031, 0x10},
574 {0x4032, 0x00},
575 {0x4033, 0x10},
576 {0x4034, 0x08},
577 {0x4035, 0x10},
578 {0x4036, 0x08},
579 {0x4037, 0x10},
580 {0x4040, 0x08},
581 {0x4041, 0x10},
582 {0x4042, 0x08},
583 {0x4043, 0x10},
584 {0x4044, 0x00},
585 {0x4045, 0x10},
586 {0x4046, 0x00},
587 {0x4047, 0x10},
588 {0x4050, 0x00},
589 {0x4051, 0x00},
590 {0x4056, 0x25},
591 {0x4102, 0xf3},
592 {0x4109, 0x02},
593 {0x410e, 0xc6},
594 {0x410f, 0x00},
595 {0x4110, 0x28},
596 {0x4111, 0x01},
597 {0x4112, 0x0d},
598 {0x4115, 0x04},
599 {0x4116, 0x1b},
600 {0x4117, 0x00},
601 {0x4118, 0x07},
602 {0x411a, 0x40},
603 {0x411e, 0x00},
604 {0x411f, 0xcc},
605 {0x4128, 0x01},
606 {0x4156, 0x25},
607 {0x4702, 0xf3},
608 {0x4709, 0x02},
609 {0x470e, 0xc6},
610 {0x470f, 0x00},
611 {0x4710, 0x28},
612 {0x4711, 0x01},
613 {0x4712, 0x0d},
614 {0x4715, 0x04},
615 {0x4716, 0x1b},
616 {0x4717, 0x00},
617 {0x4718, 0x07},
618 {0x471a, 0x40},
619 {0x471e, 0x00},
620 {0x471f, 0xcc},
621 {0x4728, 0x01},
622 {0x4756, 0x25},
623 {0x4301, 0x00},
624 {0x4303, 0x00},
625 {0x4305, 0x00},
626 {0x4307, 0x00},
627 {0x4308, 0x00},
628 {0x430b, 0xff},
629 {0x430d, 0x00},
630 {0x430e, 0x00},
631 {0x4503, 0x0f},
632 {0x4504, 0x82},
633 {0x4508, 0x00},
634 {0x451d, 0x00},
635 {0x451e, 0x00},
636 {0x451f, 0x00},
637 {0x4523, 0x00},
638 {0x4526, 0x00},
639 {0x4527, 0x00},
640 {0x4530, 0x00},
641 {0x4547, 0x06},
642 {0x4640, 0x00},
643 {0x4641, 0x30},
644 {0x4643, 0x00},
645 {0x4645, 0x13},
646 {0x464a, 0x00},
647 {0x464b, 0x30},
648 {0x4680, 0x00},
649 {0x4681, 0x24},
650 {0x4683, 0x0c},
651 {0x4800, 0x64},
652 {0x480b, 0x10},
653 {0x480c, 0x80},
654 {0x480e, 0x04},
655 {0x480f, 0x32},
656 {0x4826, 0x32},
657 {0x4833, 0x18},
658 {0x4837, 0x06},
659 {0x484b, 0x27},
660 {0x4850, 0x47},
661 {0x4860, 0x00},
662 {0x4861, 0xec},
663 {0x4862, 0x04},
664 {0x4883, 0x00},
665 {0x4885, 0x10},
666 {0x4888, 0x10},
667 {0x4889, 0x03},
668 {0x4d00, 0x04},
669 {0x4d01, 0x8f},
670 {0x4d02, 0xb9},
671 {0x4d03, 0xc1},
672 {0x4d04, 0xb6},
673 {0x4d05, 0x7e},
674 {0x5000, 0xeb},
675 {0x5001, 0xcb},
676 {0x5002, 0x15},
677 {0x5003, 0x01},
678 {0x5007, 0x1e},
679 {0x5008, 0x00},
680 {0x5009, 0x00},
681 {0x500a, 0x00},
682 {0x500b, 0x30},
683 {0x500c, 0x12},
684 {0x500d, 0x1f},
685 {0x500e, 0x0a},
686 {0x500f, 0x0f},
687 {0x504b, 0x40},
688 {0x5081, 0x00},
689 {0x50c4, 0xaa},
690 {0x50d0, 0x00},
691 {0x50d1, 0x10},
692 {0x50d2, 0x01},
693 {0x50d3, 0xb3},
694 {0x515a, 0x06},
695 {0x515b, 0x06},
696 {0x515c, 0x02},
697 {0x515d, 0x02},
698 {0x515e, 0x02},
699 {0x515f, 0x06},
700 {0x5160, 0x0a},
701 {0x5161, 0x0e},
702 {0x5180, 0x09},
703 {0x5181, 0x10},
704 {0x5182, 0x05},
705 {0x5183, 0x20},
706 {0x5184, 0x00},
707 {0x5185, 0x10},
708 {0x5186, 0x00},
709 {0x5187, 0x10},
710 {0x5188, 0x12},
711 {0x5189, 0x00},
712 {0x518a, 0x0a},
713 {0x518b, 0x20},
714 {0x518d, 0x09},
715 {0x5192, 0x00},
716 {0x5193, 0x18},
717 {0x51d2, 0x10},
718 {0x51da, 0x00},
719 {0x51db, 0x30},
720 {0x5250, 0x8e},
721 {0x5251, 0x00},
722 {0x5252, 0x10},
723 {0x5254, 0x00},
724 {0x5255, 0x70},
725 {0x5256, 0x00},
726 {0x5257, 0xc7},
727 {0x5258, 0x12},
728 {0x5259, 0x10},
729 {0x525a, 0x0a},
730 {0x525b, 0x30},
731 {0x525e, 0x00},
732 {0x525f, 0x18},
733 {0x5260, 0x00},
734 {0x5261, 0x10},
735 {0x5262, 0x00},
736 {0x5263, 0x10},
737 {0x5264, 0x12},
738 {0x5265, 0x00},
739 {0x5266, 0x0a},
740 {0x5267, 0x20},
741 {0x5268, 0x00},
742 {0x5269, 0x00},
743 {0x526a, 0x00},
744 {0x526b, 0x00},
745 {0x526c, 0x12},
746 {0x526d, 0x10},
747 {0x526e, 0x0a},
748 {0x526f, 0x30},
749 {0x5278, 0x08},
750 {0x5279, 0x10},
751 {0x527a, 0x00},
752 {0x527b, 0x00},
753 {0x527c, 0x06},
754 {0x527d, 0x06},
755 {0x527e, 0x02},
756 {0x527f, 0x02},
757 {0x5280, 0x02},
758 {0x5281, 0x06},
759 {0x5282, 0x0a},
760 {0x5283, 0x0e},
761 {0x5381, 0x00},
762 {0x53c4, 0xaa},
763 {0x545a, 0x06},
764 {0x545b, 0x06},
765 {0x545c, 0x02},
766 {0x545d, 0x02},
767 {0x545e, 0x02},
768 {0x545f, 0x06},
769 {0x5460, 0x0a},
770 {0x5461, 0x0e},
771 {0x5480, 0x09},
772 {0x5481, 0x10},
773 {0x5482, 0x05},
774 {0x5483, 0x20},
775 {0x5484, 0x00},
776 {0x5485, 0x08},
777 {0x5486, 0x00},
778 {0x5487, 0x00},
779 {0x5488, 0x09},
780 {0x5489, 0x00},
781 {0x548a, 0x05},
782 {0x548b, 0x20},
783 {0x548d, 0x09},
784 {0x54d2, 0x10},
785 {0x54da, 0x00},
786 {0x54da, 0x00},
787 {0x54db, 0x30},
788 {0x54db, 0x30},
789 {0x5550, 0xec},
790 {0x5551, 0x00},
791 {0x5552, 0x10},
792 {0x5554, 0x00},
793 {0x5555, 0x72},
794 {0x5556, 0x00},
795 {0x5557, 0xca},
796 {0x5558, 0x12},
797 {0x5559, 0x10},
798 {0x555a, 0x0a},
799 {0x555b, 0x30},
800 {0x555e, 0x00},
801 {0x555f, 0x18},
802 {0x5560, 0x00},
803 {0x5561, 0x00},
804 {0x5562, 0x00},
805 {0x5563, 0x08},
806 {0x5564, 0x12},
807 {0x5565, 0x10},
808 {0x5566, 0x0a},
809 {0x5567, 0x30},
810 {0x5568, 0x00},
811 {0x5569, 0x00},
812 {0x556a, 0x00},
813 {0x556b, 0x00},
814 {0x556c, 0x12},
815 {0x556d, 0x10},
816 {0x556e, 0x0a},
817 {0x556f, 0x30},
818 {0x557c, 0x06},
819 {0x557d, 0x06},
820 {0x557e, 0x02},
821 {0x557f, 0x02},
822 {0x5580, 0x02},
823 {0x5581, 0x06},
824 {0x5582, 0x0a},
825 {0x5583, 0x0e},
826 {0x5681, 0x00},
827 {0x56c4, 0xaa},
828 {0x575a, 0x06},
829 {0x575b, 0x06},
830 {0x575c, 0x02},
831 {0x575d, 0x02},
832 {0x575e, 0x02},
833 {0x575f, 0x06},
834 {0x5760, 0x0a},
835 {0x5761, 0x0e},
836 {0x5780, 0x09},
837 {0x5781, 0x10},
838 {0x5782, 0x05},
839 {0x5783, 0x20},
840 {0x5784, 0x00},
841 {0x5785, 0x08},
842 {0x5786, 0x00},
843 {0x5787, 0x00},
844 {0x5788, 0x09},
845 {0x5789, 0x00},
846 {0x578a, 0x05},
847 {0x578b, 0x20},
848 {0x578d, 0x09},
849 {0x5792, 0x00},
850 {0x5793, 0x18},
851 {0x57d2, 0x10},
852 {0x57da, 0x00},
853 {0x57db, 0x30},
854 {0x5850, 0xec},
855 {0x5851, 0x00},
856 {0x5852, 0x10},
857 {0x5854, 0x00},
858 {0x5855, 0x72},
859 {0x5856, 0x00},
860 {0x5857, 0xca},
861 {0x5858, 0x12},
862 {0x5859, 0x10},
863 {0x585a, 0x0a},
864 {0x585b, 0x30},
865 {0x585e, 0x00},
866 {0x585f, 0x18},
867 {0x5860, 0x00},
868 {0x5861, 0x00},
869 {0x5862, 0x00},
870 {0x5863, 0x08},
871 {0x5864, 0x12},
872 {0x5865, 0x10},
873 {0x5866, 0x0a},
874 {0x5867, 0x30},
875 {0x5868, 0x00},
876 {0x5869, 0x00},
877 {0x586a, 0x00},
878 {0x586b, 0x00},
879 {0x586c, 0x12},
880 {0x586d, 0x10},
881 {0x586e, 0x0a},
882 {0x586f, 0x30},
883 {0x587c, 0x06},
884 {0x587d, 0x06},
885 {0x587e, 0x02},
886 {0x587f, 0x02},
887 {0x5880, 0x02},
888 {0x5881, 0x06},
889 {0x5882, 0x0a},
890 {0x5883, 0x0e},
891 {0x5f06, 0x10},
892 {0x5f07, 0x20},
893 {0x5f08, 0x0c},
894 {0x5f09, 0x0c},
895 {0x5f0a, 0x04},
896 {0x5f0b, 0x04},
897 {0x5f0c, 0x04},
898 {0x5f0d, 0x0c},
899 {0x5f0e, 0x14},
900 {0x5f0f, 0x1c},
901 {0x5f10, 0x01},
902 {0x5f11, 0x01},
903 {0x5f18, 0x12},
904 {0x5f19, 0x20},
905 {0x5f1a, 0x0a},
906 {0x5f1b, 0x40},
907 {0x5f1d, 0x10},
908 {0x5f1f, 0x00},
909 {0x5f20, 0x12},
910 {0x5f21, 0x00},
911 {0x5f22, 0x0a},
912 {0x5f23, 0x40},
913 {0x5f25, 0x09},
914 {0x5f2a, 0x00},
915 {0x5f2b, 0x18},
916 {0x6600, 0x00},
917 {0x6601, 0x00},
918 {0x6602, 0x00},
919 {0x6603, 0x83},
920 {0x6960, 0x0f},
921 {0x69a2, 0x09},
922 {0x69a3, 0x00},
923 {0x69a6, 0x05},
924 {0x69a7, 0x10},
925 {0x69aa, 0x09},
926 {0x69ab, 0x00},
927 {0x69ae, 0x05},
928 {0x69af, 0x10},
929 {0x69b2, 0x09},
930 {0x69b3, 0x00},
931 {0x69b6, 0x05},
932 {0x69b7, 0x10},
933 {0x69ba, 0x09},
934 {0x69bb, 0x00},
935 {0x69be, 0x05},
936 {0x69bf, 0x10},
937 {0x6a24, 0x09},
938 {0x6a25, 0x00},
939 {0x6a2a, 0x05},
940 {0x6a2b, 0x10},
941 {0x6a61, 0x40},
942 {0x6a64, 0x09},
943 {0x6a65, 0x00},
944 {0x6a6a, 0x05},
945 {0x6a6b, 0x10},
946 {0x6a23, 0x00},
947 {0x6a27, 0x00},
948 {0x6a63, 0x00},
949 {0x6a67, 0x00},
950 {0x69a1, 0x00},
951 {0x69a5, 0x00},
952 {0x69a9, 0x00},
953 {0x69ad, 0x00},
954 {0x69b1, 0x00},
955 {0x69b5, 0x00},
956 {0x69b9, 0x00},
957 {0x69bd, 0x00},
958 {0xfff4, 0x01},
959 {0xfff6, 0x00},
960 {0x0361, 0x07},
961 {0x3644, 0x20},
962 {0x5000, 0x2b},
963 {0x5001, 0x0b},
964 {0x50d4, 0x00},
965 {0x5171, 0xbe},
966 {0x3222, 0x03},
967 {0x3208, 0x06},
968 {0x3938, 0x41},
969 {0x393b, 0x41},
970 {0x3208, 0x16},
971 {0x3208, 0x07},
972 {0x3938, 0x43},
973 {0x393b, 0x44},
974 {0x3208, 0x17},
975 {0x3208, 0x08},
976 {0x3938, 0x45},
977 {0x393b, 0x46},
978 {0x3208, 0x18},
979 {0x3208, 0x09},
980 {0x3938, 0x4b},
981 {0x393b, 0x4b},
982 {0x3208, 0x19},
983 {0x5000, 0x29},
984 {0x5001, 0x01},
985 {REG_NULL, 0x00},
986 };
987
988 /*
989 * Xclk 24Mhz
990 * max_framerate 30fps
991 */
992 static const struct regval ov12d2q_4512x2512_regs[] = {
993 {0x0301, 0xc0},
994 {0x0302, 0x01},
995 {0x0303, 0x06},
996 {0x0304, 0x02},
997 {0x0305, 0x71},
998 {0x0306, 0x04},
999 {0x0307, 0x00},
1000 {0x0309, 0x01},
1001 {0x0320, 0x20},
1002 {0x0323, 0x06},
1003 {0x0324, 0x01},
1004 {0x0325, 0xc2},
1005 {0x0326, 0xd3},
1006 {0x032b, 0x06},
1007 {0x0343, 0x06},
1008 {0x0344, 0x01},
1009 {0x0345, 0xb8},
1010 {0x0346, 0xcb},
1011 {0x0350, 0x02},
1012 {0x0360, 0x09},
1013 {0x3002, 0x80},
1014 {0x300d, 0x11},
1015 {0x300e, 0x11},
1016 {0x3012, 0x41},
1017 {0x3016, 0xf0},
1018 {0x3017, 0xd0},
1019 {0x3018, 0xf0},
1020 {0x3019, 0xc2},
1021 {0x301a, 0xf0},
1022 {0x301b, 0x34},
1023 {0x301c, 0x91},
1024 {0x301d, 0x02},
1025 {0x301e, 0x98},
1026 {0x301f, 0x21},
1027 {0x3022, 0xf0},
1028 {0x3027, 0x2e},
1029 {0x302c, 0x01},
1030 {0x302d, 0x00},
1031 {0x302e, 0x00},
1032 {0x302f, 0x00},
1033 {0x3030, 0x03},
1034 {0x3044, 0xc2},
1035 {0x304b, 0x00},
1036 {0x30d4, 0x00},
1037 {0x3209, 0x00},
1038 {0x320a, 0x00},
1039 {0x320b, 0x00},
1040 {0x320c, 0x00},
1041 {0x320d, 0x01},
1042 {0x3216, 0x01},
1043 {0x3218, 0x80},
1044 {0x33c0, 0x00},
1045 {0x33c3, 0x00},
1046 {0x33c4, 0x00},
1047 {0x3400, 0x04},
1048 {0x3408, 0x05},
1049 {0x340c, 0x10},
1050 {0x340e, 0x30},
1051 {0x3421, 0x08},
1052 {0x3422, 0x00},
1053 {0x3423, 0x15},
1054 {0x3424, 0x40},
1055 {0x3425, 0x10},
1056 {0x3426, 0x20},
1057 {0x3500, 0x00},
1058 {0x3501, 0x0a},
1059 {0x3502, 0xd0},
1060 {0x3504, 0x08},
1061 {0x3508, 0x01},
1062 {0x3509, 0x00},
1063 {0x350a, 0x01},
1064 {0x350b, 0x00},
1065 {0x350c, 0x00},
1066 {0x350e, 0x00},
1067 {0x3510, 0x01},
1068 {0x3511, 0x00},
1069 {0x3512, 0x00},
1070 {0x3513, 0x01},
1071 {0x3514, 0x00},
1072 {0x3515, 0x00},
1073 {0x3516, 0x01},
1074 {0x3517, 0x00},
1075 {0x3518, 0x00},
1076 {0x352d, 0x00},
1077 {0x352e, 0x00},
1078 {0x352f, 0x00},
1079 {0x3541, 0x00},
1080 {0x3542, 0x40},
1081 {0x3548, 0x01},
1082 {0x3549, 0x00},
1083 {0x354a, 0x01},
1084 {0x354b, 0x00},
1085 {0x354c, 0x00},
1086 {0x354e, 0x80},
1087 {0x3550, 0x01},
1088 {0x3551, 0x00},
1089 {0x3552, 0x00},
1090 {0x3581, 0x00},
1091 {0x3582, 0x40},
1092 {0x3588, 0x01},
1093 {0x3589, 0x00},
1094 {0x358a, 0x01},
1095 {0x358b, 0x00},
1096 {0x358c, 0x00},
1097 {0x3590, 0x01},
1098 {0x3591, 0x00},
1099 {0x3592, 0x00},
1100 {0x3610, 0x80},
1101 {0x3615, 0x27},
1102 {0x3617, 0x5a},
1103 {0x3624, 0x88},
1104 {0x3628, 0x77},
1105 {0x3644, 0x20},
1106 {0x3652, 0x00},
1107 {0x3653, 0x00},
1108 {0x3663, 0x6b},
1109 {0x3660, 0x4f},
1110 {0x3661, 0xd0},
1111 {0x3662, 0x09},
1112 {0x3680, 0xc1},
1113 {0x3683, 0x80},
1114 {0x3684, 0x03},
1115 {0x3685, 0x52},
1116 {0x3687, 0xc2},
1117 {0x3689, 0x27},
1118 {0x368a, 0x38},
1119 {0x368b, 0x08},
1120 {0x368c, 0x06},
1121 {0x368e, 0x00},
1122 {0x3692, 0x00},
1123 {0x3693, 0x00},
1124 {0x3696, 0x26},
1125 {0x3697, 0x1f},
1126 {0x3698, 0x1d},
1127 {0x3699, 0x59},
1128 {0x369a, 0x02},
1129 {0x369b, 0x34},
1130 {0x3700, 0x2e},
1131 {0x3701, 0x06},
1132 {0x3702, 0x4f},
1133 {0x3703, 0x28},
1134 {0x3704, 0x07},
1135 {0x3705, 0x00},
1136 {0x3706, 0x2f},
1137 {0x3707, 0x08},
1138 {0x3708, 0x2d},
1139 {0x3709, 0x5d},
1140 {0x370a, 0x00},
1141 {0x370b, 0x69},
1142 {0x370c, 0x0c},
1143 {0x3711, 0x00},
1144 {0x3712, 0x01},
1145 {0x3713, 0x00},
1146 {0x3714, 0x69},
1147 {0x371a, 0x1c},
1148 {0x371b, 0xd0},
1149 {0x371c, 0x04},
1150 {0x371d, 0x24},
1151 {0x371e, 0x13},
1152 {0x371f, 0x0c},
1153 {0x3720, 0x08},
1154 {0x3721, 0x15},
1155 {0x3724, 0x08},
1156 {0x3725, 0x32},
1157 {0x3727, 0x22},
1158 {0x3728, 0x11},
1159 {0x3729, 0x00},
1160 {0x372a, 0x00},
1161 {0x372b, 0x00},
1162 {0x3752, 0x02},
1163 {0x3753, 0x03},
1164 {0x3754, 0xee},
1165 {0x3760, 0x04},
1166 {0x3761, 0x14},
1167 {0x3762, 0x04},
1168 {0x3765, 0x08},
1169 {0x3766, 0x0c},
1170 {0x3767, 0x00},
1171 {0x376a, 0x00},
1172 {0x376b, 0x00},
1173 {0x376d, 0x1b},
1174 {0x376f, 0x02},
1175 {0x37d9, 0x08},
1176 {0x37f6, 0x07},
1177 {0x37f7, 0x04},
1178 {0x37f8, 0x2d},
1179 {0x37f9, 0x02},
1180 {0x37fa, 0x02},
1181 {0x37fb, 0x02},
1182 {0x3800, 0x00},
1183 {0x3801, 0x00},
1184 {0x3802, 0x00},
1185 {0x3803, 0x40},
1186 {0x3804, 0x12},
1187 {0x3805, 0x1f},
1188 {0x3806, 0x0a},
1189 {0x3807, 0x1f},
1190 {0x3808, 0x11},
1191 {0x3809, 0xa0},
1192 {0x380a, 0x09},
1193 {0x380b, 0xd0},
1194 {0x380c, 0x02},
1195 {0x380d, 0x1c},
1196 {0x380e, 0x0a},
1197 {0x380f, 0xe0},
1198 {0x3810, 0x00},
1199 {0x3811, 0x21},
1200 {0x3812, 0x00},
1201 {0x3813, 0x04},
1202 {0x3814, 0x11},
1203 {0x3815, 0x11},
1204 {0x381a, 0x00},
1205 {0x381b, 0x01},
1206 {0x381e, 0x00},
1207 {0x381f, 0x02},
1208 {0x3820, 0x00},
1209 {0x3821, 0x04},
1210 {0x3822, 0x00},
1211 {0x3823, 0x04},
1212 {0x3824, 0x00},
1213 {0x3825, 0x00},
1214 {0x3826, 0x00},
1215 {0x3827, 0x00},
1216 {0x3828, 0xf7},
1217 {0x382a, 0x83},
1218 {0x382c, 0x00},
1219 {0x382d, 0x00},
1220 {0x3835, 0x00},
1221 {0x3836, 0x00},
1222 {0x3837, 0x10},
1223 {0x3839, 0x00},
1224 {0x383b, 0x00},
1225 {0x383c, 0x00},
1226 {0x383d, 0x10},
1227 {0x383e, 0x00},
1228 {0x383f, 0x33},
1229 {0x3842, 0x00},
1230 {0x3856, 0x00},
1231 {0x3857, 0x10},
1232 {0x3858, 0x00},
1233 {0x3859, 0x20},
1234 {0x3865, 0x00},
1235 {0x3867, 0x08},
1236 {0x3868, 0x00},
1237 {0x3904, 0x33},
1238 {0x3907, 0x33},
1239 {0x390a, 0x9a},
1240 {0x3914, 0x34},
1241 {0x3938, 0x4b},
1242 {0x3939, 0x0c},
1243 {0x393b, 0x4b},
1244 {0x393c, 0x0c},
1245 {0x393e, 0x40},
1246 {0x393f, 0x0c},
1247 {0x3975, 0x05},
1248 {0x3979, 0x32},
1249 {0x397d, 0x69},
1250 {0x3981, 0x15},
1251 {0x3983, 0x33},
1252 {0x3985, 0x1a},
1253 {0x3986, 0x08},
1254 {0x398a, 0x09},
1255 {0x39cd, 0x00},
1256 {0x39ce, 0x24},
1257 {0x39cf, 0x40},
1258 {0x39d0, 0x0a},
1259 {0x39d1, 0x50},
1260 {0x39d2, 0x05},
1261 {0x39d3, 0x94},
1262 {0x39d4, 0x01},
1263 {0x39d5, 0x79},
1264 {0x3a12, 0x00},
1265 {0x3a13, 0x00},
1266 {0x3a14, 0x00},
1267 {0x3a15, 0x00},
1268 {0x3a16, 0x00},
1269 {0x3a18, 0x04},
1270 {0x3a1a, 0x05},
1271 {0x3a1c, 0x0a},
1272 {0x3a1e, 0x03},
1273 {0x3a1f, 0x34},
1274 {0x3a22, 0x12},
1275 {0x3a24, 0x00},
1276 {0x3a25, 0xfe},
1277 {0x3a26, 0x01},
1278 {0x3a27, 0x01},
1279 {0x3a2a, 0xa8},
1280 {0x3a2b, 0xa8},
1281 {0x3a36, 0x00},
1282 {0x3d84, 0x00},
1283 {0x3d85, 0x1b},
1284 {0x3d88, 0x00},
1285 {0x3d89, 0x00},
1286 {0x3d8a, 0x03},
1287 {0x3d8b, 0xff},
1288 {0x3d8c, 0xa3},
1289 {0x3d8d, 0xc4},
1290 {0x3da4, 0x04},
1291 {0x3daa, 0xa0},
1292 {0x3dab, 0x10},
1293 {0x3dac, 0xa1},
1294 {0x3dad, 0x8c},
1295 {0x3dae, 0xa1},
1296 {0x3daf, 0xb3},
1297 {0x3e00, 0x0e},
1298 {0x3e01, 0x0e},
1299 {0x3e02, 0x0e},
1300 {0x3e03, 0x0e},
1301 {0x3e04, 0x0e},
1302 {0x3e05, 0x0e},
1303 {0x3e06, 0x0e},
1304 {0x3e07, 0x0e},
1305 {0x3e09, 0x47},
1306 {0x3e0b, 0x25},
1307 {0x3e0d, 0x13},
1308 {0x3e0f, 0x09},
1309 {0x3e11, 0x07},
1310 {0x3e13, 0x06},
1311 {0x3e15, 0x05},
1312 {0x3e17, 0x04},
1313 {0x3e18, 0x38},
1314 {0x3e19, 0x38},
1315 {0x3e1a, 0x13},
1316 {0x3e1b, 0x30},
1317 {0x3e1c, 0x07},
1318 {0x3e1d, 0x06},
1319 {0x3e1e, 0x05},
1320 {0x3e1f, 0x04},
1321 {0x3e20, 0x0f},
1322 {0x3e21, 0x0f},
1323 {0x3e22, 0x0f},
1324 {0x3e23, 0x0f},
1325 {0x3e24, 0x0f},
1326 {0x3e25, 0x0f},
1327 {0x3e26, 0x0f},
1328 {0x3e27, 0x0f},
1329 {0x3e28, 0x07},
1330 {0x3e29, 0x07},
1331 {0x3e2a, 0x07},
1332 {0x3e2b, 0x02},
1333 {0x3e2c, 0x07},
1334 {0x3e2d, 0x07},
1335 {0x3e30, 0x07},
1336 {0x3e3a, 0x02},
1337 {0x3e3b, 0xdf},
1338 {0x3e3c, 0xff},
1339 {0x3e3d, 0x44},
1340 {0x3e3e, 0x00},
1341 {0x3e3f, 0x00},
1342 {0x3e40, 0xc1},
1343 {0x3e42, 0x54},
1344 {0x3e43, 0x54},
1345 {0x3e44, 0x54},
1346 {0x3e45, 0x54},
1347 {0x3f00, 0x10},
1348 {0x3f01, 0x26},
1349 {0x3f03, 0x40},
1350 {0x4002, 0xf3},
1351 {0x4009, 0x02},
1352 {0x400e, 0xc6},
1353 {0x400f, 0x00},
1354 {0x4010, 0x38},
1355 {0x4011, 0x01},
1356 {0x4012, 0x0d},
1357 {0x4015, 0x04},
1358 {0x4016, 0x23},
1359 {0x4017, 0x00},
1360 {0x4018, 0x07},
1361 {0x401a, 0x40},
1362 {0x401e, 0x00},
1363 {0x401f, 0xcc},
1364 {0x4020, 0x04},
1365 {0x4021, 0x00},
1366 {0x4022, 0x04},
1367 {0x4023, 0x00},
1368 {0x4024, 0x04},
1369 {0x4025, 0x00},
1370 {0x4026, 0x04},
1371 {0x4027, 0x00},
1372 {0x4028, 0x01},
1373 {0x4030, 0x00},
1374 {0x4031, 0x00},
1375 {0x4032, 0x00},
1376 {0x4033, 0x00},
1377 {0x4034, 0x00},
1378 {0x4035, 0x00},
1379 {0x4036, 0x00},
1380 {0x4037, 0x00},
1381 {0x4040, 0x00},
1382 {0x4041, 0x40},
1383 {0x4042, 0x00},
1384 {0x4043, 0x40},
1385 {0x4044, 0x00},
1386 {0x4045, 0x40},
1387 {0x4046, 0x00},
1388 {0x4047, 0x40},
1389 {0x4050, 0x00},
1390 {0x4051, 0x00},
1391 {0x4056, 0x25},
1392 {0x4102, 0xf3},
1393 {0x4109, 0x02},
1394 {0x410e, 0xc6},
1395 {0x410f, 0x00},
1396 {0x4110, 0x28},
1397 {0x4111, 0x01},
1398 {0x4112, 0x0d},
1399 {0x4115, 0x04},
1400 {0x4116, 0x1b},
1401 {0x4117, 0x00},
1402 {0x4118, 0x07},
1403 {0x411a, 0x40},
1404 {0x411e, 0x00},
1405 {0x411f, 0xcc},
1406 {0x4128, 0x01},
1407 {0x4156, 0x25},
1408 {0x4702, 0xf3},
1409 {0x4709, 0x02},
1410 {0x470e, 0xc6},
1411 {0x470f, 0x00},
1412 {0x4710, 0x28},
1413 {0x4711, 0x01},
1414 {0x4712, 0x0d},
1415 {0x4715, 0x04},
1416 {0x4716, 0x1b},
1417 {0x4717, 0x00},
1418 {0x4718, 0x07},
1419 {0x471a, 0x40},
1420 {0x471e, 0x00},
1421 {0x471f, 0xcc},
1422 {0x4728, 0x01},
1423 {0x4756, 0x25},
1424 {0x4301, 0x00},
1425 {0x4303, 0x00},
1426 {0x4305, 0x00},
1427 {0x4307, 0x00},
1428 {0x4308, 0x00},
1429 {0x430b, 0xff},
1430 {0x430d, 0x00},
1431 {0x430e, 0x00},
1432 {0x4503, 0x0f},
1433 {0x4504, 0x82},
1434 {0x4508, 0x00},
1435 {0x451d, 0x00},
1436 {0x451e, 0x00},
1437 {0x451f, 0x00},
1438 {0x4523, 0x00},
1439 {0x4526, 0x00},
1440 {0x4527, 0x00},
1441 {0x4530, 0x80},
1442 {0x4547, 0x06},
1443 {0x4640, 0x00},
1444 {0x4641, 0x30},
1445 {0x4643, 0x00},
1446 {0x4645, 0x13},
1447 {0x464a, 0x00},
1448 {0x464b, 0x30},
1449 {0x4680, 0x00},
1450 {0x4681, 0x24},
1451 {0x4683, 0x00},
1452 {0x4800, 0x64},
1453 {0x480b, 0x10},
1454 {0x480c, 0x80},
1455 {0x480e, 0x04},
1456 {0x480f, 0x32},
1457 {0x4826, 0x32},
1458 {0x4833, 0x18},
1459 {0x4837, 0x06},
1460 {0x484b, 0x27},
1461 {0x4850, 0x47},
1462 {0x4860, 0x00},
1463 {0x4861, 0xec},
1464 {0x4862, 0x04},
1465 {0x4883, 0x00},
1466 {0x4885, 0x10},
1467 {0x4888, 0x10},
1468 {0x4889, 0x03},
1469 {0x4d00, 0x04},
1470 {0x4d01, 0x8f},
1471 {0x4d02, 0xb9},
1472 {0x4d03, 0xc1},
1473 {0x4d04, 0xb6},
1474 {0x4d05, 0x7e},
1475 {0x5000, 0xfb},
1476 {0x5001, 0xdb},
1477 {0x5002, 0x15},
1478 {0x5003, 0x01},
1479 {0x5007, 0x1e},
1480 {0x5008, 0x00},
1481 {0x5009, 0x00},
1482 {0x500a, 0x00},
1483 {0x500b, 0x30},
1484 {0x500c, 0x12},
1485 {0x500d, 0x1f},
1486 {0x500e, 0x0a},
1487 {0x500f, 0x0f},
1488 {0x504b, 0x40},
1489 {0x5081, 0x00},
1490 {0x50c4, 0xaa},
1491 {0x50d0, 0x00},
1492 {0x50d1, 0x10},
1493 {0x50d2, 0x01},
1494 {0x50d3, 0xb3},
1495 {0x515a, 0x06},
1496 {0x515b, 0x06},
1497 {0x515c, 0x02},
1498 {0x515d, 0x02},
1499 {0x515e, 0x02},
1500 {0x515f, 0x06},
1501 {0x5160, 0x0a},
1502 {0x5161, 0x0e},
1503 {0x5180, 0x09},
1504 {0x5181, 0x10},
1505 {0x5182, 0x05},
1506 {0x5183, 0x20},
1507 {0x5184, 0x00},
1508 {0x5185, 0x08},
1509 {0x5186, 0x00},
1510 {0x5187, 0x00},
1511 {0x5188, 0x09},
1512 {0x5189, 0x00},
1513 {0x518a, 0x05},
1514 {0x518b, 0x20},
1515 {0x518d, 0x09},
1516 {0x5192, 0x00},
1517 {0x5193, 0x30},
1518 {0x51d2, 0x10},
1519 {0x51da, 0x00},
1520 {0x51db, 0x30},
1521 {0x5250, 0xec},
1522 {0x5251, 0x00},
1523 {0x5252, 0x10},
1524 {0x5254, 0x00},
1525 {0x5255, 0x72},
1526 {0x5256, 0x00},
1527 {0x5257, 0xca},
1528 {0x5258, 0x12},
1529 {0x5259, 0x20},
1530 {0x525a, 0x0a},
1531 {0x525b, 0x40},
1532 {0x525e, 0x00},
1533 {0x525f, 0x30},
1534 {0x5260, 0x00},
1535 {0x5261, 0x10},
1536 {0x5262, 0x00},
1537 {0x5263, 0x10},
1538 {0x5264, 0x12},
1539 {0x5265, 0x00},
1540 {0x5266, 0x0a},
1541 {0x5267, 0x20},
1542 {0x5268, 0x00},
1543 {0x5269, 0x00},
1544 {0x526a, 0x00},
1545 {0x526b, 0x00},
1546 {0x526c, 0x12},
1547 {0x526d, 0x10},
1548 {0x526e, 0x0a},
1549 {0x526f, 0x30},
1550 {0x5278, 0x10},
1551 {0x5279, 0x20},
1552 {0x527a, 0x01},
1553 {0x527b, 0x01},
1554 {0x527c, 0x0c},
1555 {0x527d, 0x0c},
1556 {0x527e, 0x04},
1557 {0x527f, 0x04},
1558 {0x5280, 0x04},
1559 {0x5281, 0x0c},
1560 {0x5282, 0x14},
1561 {0x5283, 0x1c},
1562 {0x5381, 0x00},
1563 {0x53c4, 0xaa},
1564 {0x545a, 0x06},
1565 {0x545b, 0x06},
1566 {0x545c, 0x02},
1567 {0x545d, 0x02},
1568 {0x545e, 0x02},
1569 {0x545f, 0x06},
1570 {0x5460, 0x0a},
1571 {0x5461, 0x0e},
1572 {0x5480, 0x09},
1573 {0x5481, 0x10},
1574 {0x5482, 0x05},
1575 {0x5483, 0x20},
1576 {0x5484, 0x00},
1577 {0x5485, 0x08},
1578 {0x5486, 0x00},
1579 {0x5487, 0x00},
1580 {0x5488, 0x09},
1581 {0x5489, 0x00},
1582 {0x548a, 0x05},
1583 {0x548b, 0x20},
1584 {0x548d, 0x09},
1585 {0x54d2, 0x10},
1586 {0x54da, 0x00},
1587 {0x54da, 0x00},
1588 {0x54db, 0x30},
1589 {0x54db, 0x30},
1590 {0x5550, 0xec},
1591 {0x5551, 0x00},
1592 {0x5552, 0x10},
1593 {0x5554, 0x00},
1594 {0x5555, 0x72},
1595 {0x5556, 0x00},
1596 {0x5557, 0xca},
1597 {0x5558, 0x12},
1598 {0x5559, 0x10},
1599 {0x555a, 0x0a},
1600 {0x555b, 0x30},
1601 {0x555e, 0x00},
1602 {0x555f, 0x30},
1603 {0x5560, 0x00},
1604 {0x5561, 0x00},
1605 {0x5562, 0x00},
1606 {0x5563, 0x08},
1607 {0x5564, 0x12},
1608 {0x5565, 0x10},
1609 {0x5566, 0x0a},
1610 {0x5567, 0x30},
1611 {0x5568, 0x00},
1612 {0x5569, 0x00},
1613 {0x556a, 0x00},
1614 {0x556b, 0x00},
1615 {0x556c, 0x12},
1616 {0x556d, 0x10},
1617 {0x556e, 0x0a},
1618 {0x556f, 0x30},
1619 {0x557c, 0x06},
1620 {0x557d, 0x06},
1621 {0x557e, 0x02},
1622 {0x557f, 0x02},
1623 {0x5580, 0x02},
1624 {0x5581, 0x06},
1625 {0x5582, 0x0a},
1626 {0x5583, 0x0e},
1627 {0x5681, 0x00},
1628 {0x56c4, 0xaa},
1629 {0x575a, 0x06},
1630 {0x575b, 0x06},
1631 {0x575c, 0x02},
1632 {0x575d, 0x02},
1633 {0x575e, 0x02},
1634 {0x575f, 0x06},
1635 {0x5760, 0x0a},
1636 {0x5761, 0x0e},
1637 {0x5780, 0x09},
1638 {0x5781, 0x10},
1639 {0x5782, 0x05},
1640 {0x5783, 0x20},
1641 {0x5784, 0x00},
1642 {0x5785, 0x08},
1643 {0x5786, 0x00},
1644 {0x5787, 0x00},
1645 {0x5788, 0x09},
1646 {0x5789, 0x00},
1647 {0x578a, 0x05},
1648 {0x578b, 0x20},
1649 {0x578d, 0x09},
1650 {0x5792, 0x00},
1651 {0x5793, 0x30},
1652 {0x57d2, 0x10},
1653 {0x57da, 0x00},
1654 {0x57db, 0x30},
1655 {0x5850, 0xec},
1656 {0x5851, 0x00},
1657 {0x5852, 0x10},
1658 {0x5854, 0x00},
1659 {0x5855, 0x72},
1660 {0x5856, 0x00},
1661 {0x5857, 0xca},
1662 {0x5858, 0x12},
1663 {0x5859, 0x10},
1664 {0x585a, 0x0a},
1665 {0x585b, 0x30},
1666 {0x585e, 0x00},
1667 {0x585f, 0x30},
1668 {0x5860, 0x00},
1669 {0x5861, 0x00},
1670 {0x5862, 0x00},
1671 {0x5863, 0x08},
1672 {0x5864, 0x12},
1673 {0x5865, 0x10},
1674 {0x5866, 0x0a},
1675 {0x5867, 0x30},
1676 {0x5868, 0x00},
1677 {0x5869, 0x00},
1678 {0x586a, 0x00},
1679 {0x586b, 0x00},
1680 {0x586c, 0x12},
1681 {0x586d, 0x10},
1682 {0x586e, 0x0a},
1683 {0x586f, 0x30},
1684 {0x587c, 0x06},
1685 {0x587d, 0x06},
1686 {0x587e, 0x02},
1687 {0x587f, 0x02},
1688 {0x5880, 0x02},
1689 {0x5881, 0x06},
1690 {0x5882, 0x0a},
1691 {0x5883, 0x0e},
1692 {0x5f06, 0x10},
1693 {0x5f07, 0x20},
1694 {0x5f08, 0x0c},
1695 {0x5f09, 0x0c},
1696 {0x5f0a, 0x04},
1697 {0x5f0b, 0x04},
1698 {0x5f0c, 0x04},
1699 {0x5f0d, 0x0c},
1700 {0x5f0e, 0x14},
1701 {0x5f0f, 0x1c},
1702 {0x5f10, 0x01},
1703 {0x5f11, 0x01},
1704 {0x5f18, 0x12},
1705 {0x5f19, 0x20},
1706 {0x5f1a, 0x0a},
1707 {0x5f1b, 0x40},
1708 {0x5f1d, 0x10},
1709 {0x5f1f, 0x10},
1710 {0x5f20, 0x12},
1711 {0x5f21, 0x00},
1712 {0x5f22, 0x0a},
1713 {0x5f23, 0x20},
1714 {0x5f25, 0x09},
1715 {0x5f2a, 0x00},
1716 {0x5f2b, 0x30},
1717 {0x6600, 0x00},
1718 {0x6601, 0x00},
1719 {0x6602, 0x00},
1720 {0x6603, 0x83},
1721 {0x6960, 0x0f},
1722 {0x69a2, 0x09},
1723 {0x69a3, 0x00},
1724 {0x69a6, 0x05},
1725 {0x69a7, 0x10},
1726 {0x69aa, 0x09},
1727 {0x69ab, 0x00},
1728 {0x69ae, 0x05},
1729 {0x69af, 0x10},
1730 {0x69b2, 0x09},
1731 {0x69b3, 0x00},
1732 {0x69b6, 0x05},
1733 {0x69b7, 0x10},
1734 {0x69ba, 0x09},
1735 {0x69bb, 0x00},
1736 {0x69be, 0x05},
1737 {0x69bf, 0x10},
1738 {0x6a24, 0x09},
1739 {0x6a25, 0x00},
1740 {0x6a2a, 0x05},
1741 {0x6a2b, 0x10},
1742 {0x6a61, 0x40},
1743 {0x6a64, 0x09},
1744 {0x6a65, 0x00},
1745 {0x6a6a, 0x05},
1746 {0x6a6b, 0x10},
1747 {0x6a23, 0x00},
1748 {0x6a27, 0x00},
1749 {0x6a63, 0x00},
1750 {0x6a67, 0x00},
1751 {0x69a1, 0x00},
1752 {0x69a5, 0x00},
1753 {0x69a9, 0x00},
1754 {0x69ad, 0x00},
1755 {0x69b1, 0x00},
1756 {0x69b5, 0x00},
1757 {0x69b9, 0x00},
1758 {0x69bd, 0x00},
1759 {0xfff4, 0x01},
1760 {0xfff6, 0x00},
1761 {0x0361, 0x07},
1762 {0x3644, 0x20},
1763 {0x50d4, 0x00},
1764 {0x5a02, 0x0f},
1765 {0x5002, 0x55},
1766 {0x5331, 0x0a},
1767 {0x5332, 0x43},
1768 {0x5333, 0x45},
1769 {0x5284, 0x03},
1770 {0x5285, 0x02},
1771 {0x5286, 0x02},
1772 {0x5287, 0x03},
1773 {0x5f15, 0xeb},
1774 {0x5290, 0x00},
1775 {0x5291, 0x50},
1776 {0x5292, 0x00},
1777 {0x5293, 0x50},
1778 {0x5294, 0x00},
1779 {0x5295, 0x50},
1780 {0x5296, 0x00},
1781 {0x5297, 0x50},
1782 {0x5298, 0x00},
1783 {0x5299, 0x50},
1784 {0x529a, 0x01},
1785 {0x529b, 0x00},
1786 {0x529c, 0x01},
1787 {0x529d, 0x00},
1788 {0x529e, 0x00},
1789 {0x529f, 0x50},
1790 {0x52a0, 0x00},
1791 {0x52a1, 0x50},
1792 {0x52a2, 0x01},
1793 {0x52a3, 0x00},
1794 {0x52a4, 0x01},
1795 {0x52a5, 0x00},
1796 {0x52a6, 0x00},
1797 {0x52a7, 0x50},
1798 {0x52a8, 0x00},
1799 {0x52a9, 0x50},
1800 {0x52aa, 0x00},
1801 {0x52ab, 0x50},
1802 {0x52ac, 0x00},
1803 {0x52ad, 0x50},
1804 {0x52ae, 0x00},
1805 {0x52af, 0x50},
1806 {0x52b0, 0x00},
1807 {0x52b1, 0x50},
1808 {0x52b2, 0x00},
1809 {0x52b3, 0x50},
1810 {0x52b4, 0x00},
1811 {0x52b5, 0x50},
1812 {0x52b6, 0x00},
1813 {0x52b7, 0x50},
1814 {0x52b8, 0x00},
1815 {0x52b9, 0x50},
1816 {0x52ba, 0x01},
1817 {0x52bb, 0x00},
1818 {0x52bc, 0x01},
1819 {0x52bd, 0x00},
1820 {0x52be, 0x00},
1821 {0x52bf, 0x50},
1822 {0x52c0, 0x00},
1823 {0x52c1, 0x50},
1824 {0x52c2, 0x01},
1825 {0x52c3, 0x00},
1826 {0x52c4, 0x01},
1827 {0x52c5, 0x00},
1828 {0x52c6, 0x00},
1829 {0x52c7, 0x50},
1830 {0x52c8, 0x00},
1831 {0x52c9, 0x50},
1832 {0x52ca, 0x00},
1833 {0x52cb, 0x50},
1834 {0x52cc, 0x00},
1835 {0x52cd, 0x50},
1836 {0x52ce, 0x00},
1837 {0x52cf, 0x50},
1838 {0x5f00, 0x29},
1839 {0x5f2d, 0x28},
1840 {0x5f2e, 0x28},
1841 {0x52f0, 0x04},
1842 {0x52f1, 0x03},
1843 {0x52f2, 0x02},
1844 {0x52f3, 0x01},
1845 {0x52f4, 0x08},
1846 {0x52f5, 0x07},
1847 {0x52f6, 0x06},
1848 {0x52f7, 0x05},
1849 {0x52f8, 0x0c},
1850 {0x52f9, 0x0b},
1851 {0x52fa, 0x0a},
1852 {0x52fb, 0x09},
1853 {0x52fc, 0x10},
1854 {0x52fd, 0x0f},
1855 {0x52fe, 0x0e},
1856 {0x52ff, 0x0d},
1857 {0x5300, 0x14},
1858 {0x5301, 0x13},
1859 {0x5302, 0x12},
1860 {0x5303, 0x11},
1861 {0x5304, 0x18},
1862 {0x5305, 0x17},
1863 {0x5306, 0x16},
1864 {0x5307, 0x15},
1865 {0x5308, 0x1c},
1866 {0x5309, 0x1b},
1867 {0x530a, 0x1a},
1868 {0x530b, 0x19},
1869 {0x530c, 0x20},
1870 {0x530d, 0x1f},
1871 {0x530e, 0x1e},
1872 {0x530f, 0x1d},
1873 {0x5353, 0x21},
1874 {0x5354, 0x01},
1875 {0x5355, 0x02},
1876 {0x5356, 0x04},
1877 {0x5357, 0x06},
1878 {0x5358, 0x08},
1879 {0x5359, 0x0c},
1880 {0x535a, 0x10},
1881 {0x535b, 0x10},
1882 {0x5990, 0x00},
1883 {0x5991, 0x00},
1884 {0x5992, 0x01},
1885 {0x5993, 0x01},
1886 {0x5994, 0x02},
1887 {0x5995, 0x04},
1888 {0x5996, 0x06},
1889 {0x5997, 0x08},
1890 {0x5998, 0x0a},
1891 {0x5999, 0x0c},
1892 {0x599a, 0x0e},
1893 {0x599b, 0x10},
1894 {0x599c, 0x12},
1895 {0x599d, 0x14},
1896 {0x599e, 0x16},
1897 {0x599f, 0x18},
1898 {0x3222, 0x03},
1899 {0x3208, 0x06},
1900 {0x3938, 0x41},
1901 {0x393b, 0x41},
1902 {0x3208, 0x16},
1903 {0x3208, 0x07},
1904 {0x3938, 0x43},
1905 {0x393b, 0x44},
1906 {0x3208, 0x17},
1907 {0x3208, 0x08},
1908 {0x3938, 0x45},
1909 {0x393b, 0x46},
1910 {0x3208, 0x18},
1911 {0x3208, 0x09},
1912 {0x3938, 0x4b},
1913 {0x393b, 0x4b},
1914 {0x3208, 0x19},
1915 {0x5000, 0x29},
1916 {0x5001, 0xd1},
1917 {REG_NULL, 0x00},
1918 };
1919
1920 /*
1921 * The width and height must be configured to be
1922 * the same as the current output resolution of the sensor.
1923 * The input width of the isp needs to be 16 aligned.
1924 * The input height of the isp needs to be 8 aligned.
1925 * If the width or height does not meet the alignment rules,
1926 * you can configure the cropping parameters with the following function to
1927 * crop out the appropriate resolution.
1928 * struct v4l2_subdev_pad_ops {
1929 * .get_selection
1930 * }
1931 */
1932 static const struct ov12d2q_mode supported_modes[] = {
1933 {
1934 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1935 .width = 2256,
1936 .height = 1256,
1937 .max_fps = {
1938 .numerator = 10000,
1939 .denominator = 600000,
1940 },
1941 .exp_def = 0x0560,
1942 .hts_def = 0x021b*5,
1943 .vts_def = 0x0570,
1944 .reg_list = ov12d2q_2256x1256_regs,
1945 .hdr_mode = NO_HDR,
1946 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1947 },
1948 {
1949 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
1950 .width = 4512,
1951 .height = 2512,
1952 .max_fps = {
1953 .numerator = 10000,
1954 .denominator = 300000,
1955 },
1956 .exp_def = 0x0ad0,
1957 .hts_def = 0x021c*9,
1958 .vts_def = 0x0ae0,
1959 .reg_list = ov12d2q_4512x2512_regs,
1960 .hdr_mode = NO_HDR,
1961 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1962 },
1963 };
1964
1965 static const s64 link_freq_menu_items[] = {
1966 MIPI_FREQ_625M,
1967 };
1968
1969 static const char * const ov12d2q_test_pattern_menu[] = {
1970 "Disabled",
1971 "Vertical Color Bar Type 1",
1972 "Vertical Color Bar Type 2",
1973 "Vertical Color Bar Type 3",
1974 "Vertical Color Bar Type 4"
1975 };
1976
1977 static int __ov12d2q_power_on(struct ov12d2q *ov12d2q);
1978
1979 /* Write registers up to 4 at a time */
ov12d2q_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)1980 static int ov12d2q_write_reg(struct i2c_client *client, u16 reg,
1981 u32 len, u32 val)
1982 {
1983 u32 buf_i, val_i;
1984 u8 buf[6];
1985 u8 *val_p;
1986 __be32 val_be;
1987
1988 if (len > 4)
1989 return -EINVAL;
1990
1991 buf[0] = reg >> 8;
1992 buf[1] = reg & 0xff;
1993
1994 val_be = cpu_to_be32(val);
1995 val_p = (u8 *)&val_be;
1996 buf_i = 2;
1997 val_i = 4 - len;
1998
1999 while (val_i < 4)
2000 buf[buf_i++] = val_p[val_i++];
2001
2002 if (i2c_master_send(client, buf, len + 2) != len + 2)
2003 return -EIO;
2004
2005 return 0;
2006 }
2007
ov12d2q_write_array(struct i2c_client * client,const struct regval * regs)2008 static int ov12d2q_write_array(struct i2c_client *client,
2009 const struct regval *regs)
2010 {
2011 u32 i;
2012 int ret = 0;
2013
2014 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
2015 ret |= ov12d2q_write_reg(client, regs[i].addr,
2016 OV12D2Q_REG_VALUE_08BIT, regs[i].val);
2017 }
2018 return ret;
2019 }
2020
2021 /* Read registers up to 4 at a time */
ov12d2q_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)2022 static int ov12d2q_read_reg(struct i2c_client *client,
2023 u16 reg,
2024 unsigned int len,
2025 u32 *val)
2026 {
2027 struct i2c_msg msgs[2];
2028 u8 *data_be_p;
2029 __be32 data_be = 0;
2030 __be16 reg_addr_be = cpu_to_be16(reg);
2031 int ret;
2032
2033 if (len > 4 || !len)
2034 return -EINVAL;
2035
2036 data_be_p = (u8 *)&data_be;
2037 /* Write register address */
2038 msgs[0].addr = client->addr;
2039 msgs[0].flags = 0;
2040 msgs[0].len = 2;
2041 msgs[0].buf = (u8 *)®_addr_be;
2042
2043 /* Read data from register */
2044 msgs[1].addr = client->addr;
2045 msgs[1].flags = I2C_M_RD;
2046 msgs[1].len = len;
2047 msgs[1].buf = &data_be_p[4 - len];
2048
2049 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
2050 if (ret != ARRAY_SIZE(msgs))
2051 return -EIO;
2052
2053 *val = be32_to_cpu(data_be);
2054
2055 return 0;
2056 }
2057
ov12d2q_get_reso_dist(const struct ov12d2q_mode * mode,struct v4l2_mbus_framefmt * framefmt)2058 static int ov12d2q_get_reso_dist(const struct ov12d2q_mode *mode,
2059 struct v4l2_mbus_framefmt *framefmt)
2060 {
2061 return abs(mode->width - framefmt->width) +
2062 abs(mode->height - framefmt->height);
2063 }
2064
2065 static const struct ov12d2q_mode *
ov12d2q_find_best_fit(struct ov12d2q * ov12d2q,struct v4l2_subdev_format * fmt)2066 ov12d2q_find_best_fit(struct ov12d2q *ov12d2q, struct v4l2_subdev_format *fmt)
2067 {
2068 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
2069 int dist;
2070 int cur_best_fit = 0;
2071 int cur_best_fit_dist = -1;
2072 unsigned int i;
2073
2074 for (i = 0; i < ov12d2q->cfg_num; i++) {
2075 dist = ov12d2q_get_reso_dist(&supported_modes[i], framefmt);
2076 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
2077 (supported_modes[i].bus_fmt == framefmt->code)) {
2078 cur_best_fit_dist = dist;
2079 cur_best_fit = i;
2080 }
2081 }
2082
2083 return &supported_modes[cur_best_fit];
2084 }
2085
ov12d2q_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)2086 static int ov12d2q_set_fmt(struct v4l2_subdev *sd,
2087 struct v4l2_subdev_pad_config *cfg,
2088 struct v4l2_subdev_format *fmt)
2089 {
2090 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2091 const struct ov12d2q_mode *mode;
2092 s64 h_blank, vblank_def;
2093 u64 dst_link_freq = 0;
2094 u64 dst_pixel_rate = 0;
2095
2096 mutex_lock(&ov12d2q->mutex);
2097
2098 mode = ov12d2q_find_best_fit(ov12d2q, fmt);
2099 fmt->format.code = mode->bus_fmt;
2100 fmt->format.width = mode->width;
2101 fmt->format.height = mode->height;
2102 fmt->format.field = V4L2_FIELD_NONE;
2103 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2104 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2105 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
2106 #else
2107 mutex_unlock(&ov12d2q->mutex);
2108 return -ENOTTY;
2109 #endif
2110 } else {
2111 ov12d2q->cur_mode = mode;
2112 h_blank = mode->hts_def - mode->width;
2113 __v4l2_ctrl_modify_range(ov12d2q->hblank, h_blank,
2114 h_blank, 1, h_blank);
2115 vblank_def = mode->vts_def - mode->height;
2116 __v4l2_ctrl_modify_range(ov12d2q->vblank, vblank_def,
2117 OV12D2Q_VTS_MAX - mode->height,
2118 1, vblank_def);
2119 if (mode->hdr_mode == NO_HDR) {
2120 dst_link_freq = 0;
2121 dst_pixel_rate = PIXEL_RATE_WITH_625M;
2122 }
2123 __v4l2_ctrl_s_ctrl_int64(ov12d2q->pixel_rate,
2124 dst_pixel_rate);
2125 __v4l2_ctrl_s_ctrl(ov12d2q->link_freq,
2126 dst_link_freq);
2127 }
2128
2129 mutex_unlock(&ov12d2q->mutex);
2130
2131 return 0;
2132 }
2133
ov12d2q_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)2134 static int ov12d2q_get_fmt(struct v4l2_subdev *sd,
2135 struct v4l2_subdev_pad_config *cfg,
2136 struct v4l2_subdev_format *fmt)
2137 {
2138 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2139 const struct ov12d2q_mode *mode = ov12d2q->cur_mode;
2140
2141 mutex_lock(&ov12d2q->mutex);
2142 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2143 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2144 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2145 #else
2146 mutex_unlock(&ov12d2q->mutex);
2147 return -ENOTTY;
2148 #endif
2149 } else {
2150 fmt->format.width = mode->width;
2151 fmt->format.height = mode->height;
2152 fmt->format.code = mode->bus_fmt;
2153 fmt->format.field = V4L2_FIELD_NONE;
2154 if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
2155 fmt->reserved[0] = mode->vc[fmt->pad];
2156 else
2157 fmt->reserved[0] = mode->vc[PAD0];
2158 }
2159 mutex_unlock(&ov12d2q->mutex);
2160
2161 return 0;
2162 }
2163
ov12d2q_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)2164 static int ov12d2q_enum_mbus_code(struct v4l2_subdev *sd,
2165 struct v4l2_subdev_pad_config *cfg,
2166 struct v4l2_subdev_mbus_code_enum *code)
2167 {
2168 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2169
2170 if (code->index != 0)
2171 return -EINVAL;
2172 code->code = ov12d2q->cur_mode->bus_fmt;
2173
2174 return 0;
2175 }
2176
ov12d2q_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)2177 static int ov12d2q_enum_frame_sizes(struct v4l2_subdev *sd,
2178 struct v4l2_subdev_pad_config *cfg,
2179 struct v4l2_subdev_frame_size_enum *fse)
2180 {
2181 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2182
2183 if (fse->index >= ov12d2q->cfg_num)
2184 return -EINVAL;
2185
2186 if (fse->code != supported_modes[fse->index].bus_fmt)
2187 return -EINVAL;
2188
2189 fse->min_width = supported_modes[fse->index].width;
2190 fse->max_width = supported_modes[fse->index].width;
2191 fse->max_height = supported_modes[fse->index].height;
2192 fse->min_height = supported_modes[fse->index].height;
2193
2194 return 0;
2195 }
2196
ov12d2q_enable_test_pattern(struct ov12d2q * ov12d2q,u32 pattern)2197 static int ov12d2q_enable_test_pattern(struct ov12d2q *ov12d2q, u32 pattern)
2198 {
2199 u32 val;
2200 int ret = 0;
2201
2202 if (pattern)
2203 val = ((pattern - 1) << 4) | OV12D2Q_TEST_PATTERN_ENABLE;
2204 else
2205 val = OV12D2Q_TEST_PATTERN_DISABLE;
2206
2207 ret = ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_TEST_PATTERN,
2208 OV12D2Q_REG_VALUE_08BIT, val);
2209
2210 return ret;
2211 }
2212
ov12d2q_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)2213 static int ov12d2q_g_frame_interval(struct v4l2_subdev *sd,
2214 struct v4l2_subdev_frame_interval *fi)
2215 {
2216 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2217 const struct ov12d2q_mode *mode = ov12d2q->cur_mode;
2218
2219 fi->interval = mode->max_fps;
2220
2221 return 0;
2222 }
2223
ov12d2q_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)2224 static int ov12d2q_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
2225 struct v4l2_mbus_config *config)
2226 {
2227 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2228 const struct ov12d2q_mode *mode = ov12d2q->cur_mode;
2229 u32 val = 0;
2230
2231 if (mode->hdr_mode == NO_HDR)
2232 val = 1 << (OV12D2Q_LANES - 1) |
2233 V4L2_MBUS_CSI2_CHANNEL_0 |
2234 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
2235 if (mode->hdr_mode == HDR_X2)
2236 val = 1 << (OV12D2Q_LANES - 1) |
2237 V4L2_MBUS_CSI2_CHANNEL_0 |
2238 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
2239 V4L2_MBUS_CSI2_CHANNEL_1;
2240
2241 config->type = V4L2_MBUS_CSI2_DPHY;
2242 config->flags = val;
2243
2244 return 0;
2245 }
2246
ov12d2q_get_module_inf(struct ov12d2q * ov12d2q,struct rkmodule_inf * inf)2247 static void ov12d2q_get_module_inf(struct ov12d2q *ov12d2q,
2248 struct rkmodule_inf *inf)
2249 {
2250 memset(inf, 0, sizeof(*inf));
2251 strlcpy(inf->base.sensor, OV12D2Q_NAME, sizeof(inf->base.sensor));
2252 strlcpy(inf->base.module, ov12d2q->module_name,
2253 sizeof(inf->base.module));
2254 strlcpy(inf->base.lens, ov12d2q->len_name, sizeof(inf->base.lens));
2255 }
2256
ov12d2q_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)2257 static long ov12d2q_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
2258 {
2259 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2260 struct rkmodule_hdr_cfg *hdr_cfg;
2261 long ret = 0;
2262 u32 i, h, w;
2263 u32 stream = 0;
2264
2265 switch (cmd) {
2266 case PREISP_CMD_SET_HDRAE_EXP:
2267 break;
2268 case RKMODULE_SET_HDR_CFG:
2269 hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
2270 w = ov12d2q->cur_mode->width;
2271 h = ov12d2q->cur_mode->height;
2272 for (i = 0; i < ov12d2q->cfg_num; i++) {
2273 if (w == supported_modes[i].width &&
2274 h == supported_modes[i].height &&
2275 supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
2276 ov12d2q->cur_mode = &supported_modes[i];
2277 break;
2278 }
2279 }
2280 if (i == ov12d2q->cfg_num) {
2281 dev_err(&ov12d2q->client->dev,
2282 "not find hdr mode:%d %dx%d config\n",
2283 hdr_cfg->hdr_mode, w, h);
2284 ret = -EINVAL;
2285 } else {
2286 w = ov12d2q->cur_mode->hts_def - ov12d2q->cur_mode->width;
2287 h = ov12d2q->cur_mode->vts_def - ov12d2q->cur_mode->height;
2288 __v4l2_ctrl_modify_range(ov12d2q->hblank, w, w, 1, w);
2289 __v4l2_ctrl_modify_range(ov12d2q->vblank, h,
2290 OV12D2Q_VTS_MAX - ov12d2q->cur_mode->height,
2291 1, h);
2292 dev_info(&ov12d2q->client->dev,
2293 "sensor mode: %d\n",
2294 ov12d2q->cur_mode->hdr_mode);
2295 }
2296 break;
2297 case RKMODULE_GET_MODULE_INFO:
2298 ov12d2q_get_module_inf(ov12d2q, (struct rkmodule_inf *)arg);
2299 break;
2300 case RKMODULE_GET_HDR_CFG:
2301 hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
2302 hdr_cfg->esp.mode = HDR_NORMAL_VC;
2303 hdr_cfg->hdr_mode = ov12d2q->cur_mode->hdr_mode;
2304 break;
2305 case RKMODULE_SET_QUICK_STREAM:
2306 stream = *((u32 *)arg);
2307
2308 if (stream)
2309 ret = ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_CTRL_MODE,
2310 OV12D2Q_REG_VALUE_08BIT, OV12D2Q_MODE_STREAMING);
2311 else
2312 ret = ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_CTRL_MODE,
2313 OV12D2Q_REG_VALUE_08BIT, OV12D2Q_MODE_SW_STANDBY);
2314 break;
2315 default:
2316 ret = -ENOIOCTLCMD;
2317 break;
2318 }
2319
2320 return ret;
2321 }
2322
2323 #ifdef CONFIG_COMPAT
ov12d2q_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)2324 static long ov12d2q_compat_ioctl32(struct v4l2_subdev *sd,
2325 unsigned int cmd, unsigned long arg)
2326 {
2327 void __user *up = compat_ptr(arg);
2328 struct rkmodule_inf *inf;
2329 struct rkmodule_awb_cfg *cfg;
2330 struct rkmodule_hdr_cfg *hdr;
2331 struct preisp_hdrae_exp_s *hdrae;
2332 long ret;
2333 u32 cg = 0;
2334 u32 stream = 0;
2335
2336 switch (cmd) {
2337 case RKMODULE_GET_MODULE_INFO:
2338 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
2339 if (!inf) {
2340 ret = -ENOMEM;
2341 return ret;
2342 }
2343
2344 ret = ov12d2q_ioctl(sd, cmd, inf);
2345 if (!ret)
2346 ret = copy_to_user(up, inf, sizeof(*inf));
2347 kfree(inf);
2348 break;
2349 case RKMODULE_AWB_CFG:
2350 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
2351 if (!cfg) {
2352 ret = -ENOMEM;
2353 return ret;
2354 }
2355
2356 ret = copy_from_user(cfg, up, sizeof(*cfg));
2357 if (!ret)
2358 ret = ov12d2q_ioctl(sd, cmd, cfg);
2359 kfree(cfg);
2360 break;
2361 case RKMODULE_GET_HDR_CFG:
2362 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2363 if (!hdr) {
2364 ret = -ENOMEM;
2365 return ret;
2366 }
2367
2368 ret = ov12d2q_ioctl(sd, cmd, hdr);
2369 if (!ret)
2370 ret = copy_to_user(up, hdr, sizeof(*hdr));
2371 kfree(hdr);
2372 break;
2373 case RKMODULE_SET_HDR_CFG:
2374 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2375 if (!hdr) {
2376 ret = -ENOMEM;
2377 return ret;
2378 }
2379
2380 ret = copy_from_user(hdr, up, sizeof(*hdr));
2381 if (!ret)
2382 ret = ov12d2q_ioctl(sd, cmd, hdr);
2383 kfree(hdr);
2384 break;
2385 case PREISP_CMD_SET_HDRAE_EXP:
2386 hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
2387 if (!hdrae) {
2388 ret = -ENOMEM;
2389 return ret;
2390 }
2391
2392 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
2393 if (!ret)
2394 ret = ov12d2q_ioctl(sd, cmd, hdrae);
2395 kfree(hdrae);
2396 break;
2397 case RKMODULE_SET_CONVERSION_GAIN:
2398 ret = copy_from_user(&cg, up, sizeof(cg));
2399 if (!ret)
2400 ret = ov12d2q_ioctl(sd, cmd, &cg);
2401 break;
2402 case RKMODULE_SET_QUICK_STREAM:
2403 ret = copy_from_user(&stream, up, sizeof(u32));
2404 if (!ret)
2405 ret = ov12d2q_ioctl(sd, cmd, &stream);
2406 break;
2407 default:
2408 ret = -ENOIOCTLCMD;
2409 break;
2410 }
2411
2412 return ret;
2413 }
2414 #endif
2415
__ov12d2q_start_stream(struct ov12d2q * ov12d2q)2416 static int __ov12d2q_start_stream(struct ov12d2q *ov12d2q)
2417 {
2418 int ret;
2419
2420 if (!ov12d2q->is_thunderboot) {
2421 ret = ov12d2q_write_array(ov12d2q->client, ov12d2q_global_regs);
2422 if (ret) {
2423 dev_err(&ov12d2q->client->dev,
2424 "could not set init registers\n");
2425 return ret;
2426 }
2427
2428 ret = ov12d2q_write_array(ov12d2q->client, ov12d2q->cur_mode->reg_list);
2429 if (ret)
2430 return ret;
2431 }
2432
2433 /* In case these controls are set before streaming */
2434 ret = __v4l2_ctrl_handler_setup(&ov12d2q->ctrl_handler);
2435 if (ret)
2436 return ret;
2437
2438 return ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_CTRL_MODE,
2439 OV12D2Q_REG_VALUE_08BIT, OV12D2Q_MODE_STREAMING);
2440 }
2441
__ov12d2q_stop_stream(struct ov12d2q * ov12d2q)2442 static int __ov12d2q_stop_stream(struct ov12d2q *ov12d2q)
2443 {
2444 if (ov12d2q->is_thunderboot)
2445 ov12d2q->is_first_streamoff = true;
2446 return ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_CTRL_MODE,
2447 OV12D2Q_REG_VALUE_08BIT, OV12D2Q_MODE_SW_STANDBY);
2448 }
2449
ov12d2q_s_stream(struct v4l2_subdev * sd,int on)2450 static int ov12d2q_s_stream(struct v4l2_subdev *sd, int on)
2451 {
2452 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2453 struct i2c_client *client = ov12d2q->client;
2454 int ret = 0;
2455
2456 mutex_lock(&ov12d2q->mutex);
2457 on = !!on;
2458 if (on == ov12d2q->streaming)
2459 goto unlock_and_return;
2460
2461 if (on) {
2462 if (ov12d2q->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
2463 ov12d2q->is_thunderboot = false;
2464 __ov12d2q_power_on(ov12d2q);
2465 }
2466 ret = pm_runtime_get_sync(&client->dev);
2467 if (ret < 0) {
2468 pm_runtime_put_noidle(&client->dev);
2469 goto unlock_and_return;
2470 }
2471
2472 ret = __ov12d2q_start_stream(ov12d2q);
2473 if (ret) {
2474 v4l2_err(sd, "start stream failed while write regs\n");
2475 pm_runtime_put(&client->dev);
2476 goto unlock_and_return;
2477 }
2478 } else {
2479 __ov12d2q_stop_stream(ov12d2q);
2480 pm_runtime_put(&client->dev);
2481 }
2482
2483 ov12d2q->streaming = on;
2484
2485 unlock_and_return:
2486 mutex_unlock(&ov12d2q->mutex);
2487
2488 return ret;
2489 }
2490
ov12d2q_s_power(struct v4l2_subdev * sd,int on)2491 static int ov12d2q_s_power(struct v4l2_subdev *sd, int on)
2492 {
2493 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2494 struct i2c_client *client = ov12d2q->client;
2495 int ret = 0;
2496
2497 mutex_lock(&ov12d2q->mutex);
2498
2499 /* If the power state is not modified - no work to do. */
2500 if (ov12d2q->power_on == !!on)
2501 goto unlock_and_return;
2502
2503 if (on) {
2504 ret = pm_runtime_get_sync(&client->dev);
2505 if (ret < 0) {
2506 pm_runtime_put_noidle(&client->dev);
2507 goto unlock_and_return;
2508 }
2509
2510 if (!ov12d2q->is_thunderboot) {
2511 ret |= ov12d2q_write_reg(ov12d2q->client,
2512 OV12D2Q_SOFTWARE_RESET_REG,
2513 OV12D2Q_REG_VALUE_08BIT,
2514 0x01);
2515 if (ret) {
2516 v4l2_err(sd, "could not set init registers\n");
2517 pm_runtime_put_noidle(&client->dev);
2518 goto unlock_and_return;
2519 }
2520 usleep_range(100, 200);
2521 }
2522
2523 ov12d2q->power_on = true;
2524 } else {
2525 pm_runtime_put(&client->dev);
2526 ov12d2q->power_on = false;
2527 }
2528
2529 unlock_and_return:
2530 mutex_unlock(&ov12d2q->mutex);
2531
2532 return ret;
2533 }
2534
2535 /* Calculate the delay in us by clock rate and clock cycles */
ov12d2q_cal_delay(u32 cycles)2536 static inline u32 ov12d2q_cal_delay(u32 cycles)
2537 {
2538 return DIV_ROUND_UP(cycles, OV12D2Q_XVCLK_FREQ / 1000 / 1000);
2539 }
2540
__ov12d2q_power_on(struct ov12d2q * ov12d2q)2541 static int __ov12d2q_power_on(struct ov12d2q *ov12d2q)
2542 {
2543 int ret;
2544 u32 delay_us;
2545 struct device *dev = &ov12d2q->client->dev;
2546
2547 if (ov12d2q->is_thunderboot)
2548 return 0;
2549
2550 if (!IS_ERR_OR_NULL(ov12d2q->pins_default)) {
2551 ret = pinctrl_select_state(ov12d2q->pinctrl,
2552 ov12d2q->pins_default);
2553 if (ret < 0)
2554 dev_err(dev, "could not set pins\n");
2555 }
2556 ret = clk_set_rate(ov12d2q->xvclk, OV12D2Q_XVCLK_FREQ);
2557 if (ret < 0)
2558 dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
2559 if (clk_get_rate(ov12d2q->xvclk) != OV12D2Q_XVCLK_FREQ)
2560 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
2561 ret = clk_prepare_enable(ov12d2q->xvclk);
2562 if (ret < 0) {
2563 dev_err(dev, "Failed to enable xvclk\n");
2564 return ret;
2565 }
2566 if (!IS_ERR(ov12d2q->reset_gpio))
2567 gpiod_direction_output(ov12d2q->reset_gpio, 1);
2568
2569 ret = regulator_bulk_enable(OV12D2Q_NUM_SUPPLIES, ov12d2q->supplies);
2570 if (ret < 0) {
2571 dev_err(dev, "Failed to enable regulators\n");
2572 goto disable_clk;
2573 }
2574
2575 if (!IS_ERR(ov12d2q->reset_gpio))
2576 gpiod_direction_output(ov12d2q->reset_gpio, 0);
2577
2578 usleep_range(500, 1000);
2579 if (!IS_ERR(ov12d2q->pwdn_gpio))
2580 gpiod_direction_output(ov12d2q->pwdn_gpio, 1);
2581 /*
2582 * There is no need to wait for the delay of RC circuit
2583 * if the reset signal is directly controlled by GPIO.
2584 */
2585 if (!IS_ERR(ov12d2q->reset_gpio))
2586 usleep_range(6000, 8000);
2587 else
2588 usleep_range(12000, 16000);
2589
2590 /* 8192 cycles prior to first SCCB transaction */
2591 delay_us = ov12d2q_cal_delay(8192);
2592 usleep_range(delay_us, delay_us * 2);
2593
2594 return 0;
2595
2596 disable_clk:
2597 clk_disable_unprepare(ov12d2q->xvclk);
2598
2599 return ret;
2600 }
2601
__ov12d2q_power_off(struct ov12d2q * ov12d2q)2602 static void __ov12d2q_power_off(struct ov12d2q *ov12d2q)
2603 {
2604 int ret;
2605 struct device *dev = &ov12d2q->client->dev;
2606
2607 if (ov12d2q->is_thunderboot) {
2608 if (ov12d2q->is_first_streamoff) {
2609 ov12d2q->is_thunderboot = false;
2610 ov12d2q->is_first_streamoff = false;
2611 } else {
2612 return;
2613 }
2614 }
2615
2616 if (!IS_ERR(ov12d2q->pwdn_gpio))
2617 gpiod_direction_output(ov12d2q->pwdn_gpio, 0);
2618
2619 clk_disable_unprepare(ov12d2q->xvclk);
2620
2621 if (!IS_ERR(ov12d2q->reset_gpio))
2622 gpiod_direction_output(ov12d2q->reset_gpio, 0);
2623 if (!IS_ERR_OR_NULL(ov12d2q->pins_sleep)) {
2624 ret = pinctrl_select_state(ov12d2q->pinctrl,
2625 ov12d2q->pins_sleep);
2626 if (ret < 0)
2627 dev_dbg(dev, "could not set pins\n");
2628 }
2629
2630 if (ov12d2q->is_thunderboot_ng) {
2631 ov12d2q->is_thunderboot_ng = false;
2632 regulator_bulk_disable(OV12D2Q_NUM_SUPPLIES, ov12d2q->supplies);
2633 }
2634 }
2635
ov12d2q_runtime_resume(struct device * dev)2636 static int ov12d2q_runtime_resume(struct device *dev)
2637 {
2638 struct i2c_client *client = to_i2c_client(dev);
2639 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2640 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2641
2642 return __ov12d2q_power_on(ov12d2q);
2643 }
2644
ov12d2q_runtime_suspend(struct device * dev)2645 static int ov12d2q_runtime_suspend(struct device *dev)
2646 {
2647 struct i2c_client *client = to_i2c_client(dev);
2648 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2649 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2650
2651 __ov12d2q_power_off(ov12d2q);
2652
2653 return 0;
2654 }
2655
2656 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
ov12d2q_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2657 static int ov12d2q_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2658 {
2659 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2660 struct v4l2_mbus_framefmt *try_fmt =
2661 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2662 const struct ov12d2q_mode *def_mode = &supported_modes[0];
2663
2664 mutex_lock(&ov12d2q->mutex);
2665 /* Initialize try_fmt */
2666 try_fmt->width = def_mode->width;
2667 try_fmt->height = def_mode->height;
2668 try_fmt->code = def_mode->bus_fmt;
2669 try_fmt->field = V4L2_FIELD_NONE;
2670
2671 mutex_unlock(&ov12d2q->mutex);
2672 /* No crop or compose */
2673
2674 return 0;
2675 }
2676 #endif
2677
ov12d2q_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2678 static int ov12d2q_enum_frame_interval(struct v4l2_subdev *sd,
2679 struct v4l2_subdev_pad_config *cfg,
2680 struct v4l2_subdev_frame_interval_enum *fie)
2681 {
2682 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
2683
2684 if (fie->index >= ov12d2q->cfg_num)
2685 return -EINVAL;
2686
2687 fie->code = supported_modes[fie->index].bus_fmt;
2688 fie->width = supported_modes[fie->index].width;
2689 fie->height = supported_modes[fie->index].height;
2690 fie->interval = supported_modes[fie->index].max_fps;
2691 fie->reserved[0] = supported_modes[fie->index].hdr_mode;
2692 return 0;
2693 }
2694
2695 static const struct dev_pm_ops ov12d2q_pm_ops = {
2696 SET_RUNTIME_PM_OPS(ov12d2q_runtime_suspend,
2697 ov12d2q_runtime_resume, NULL)
2698 };
2699
2700 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2701 static const struct v4l2_subdev_internal_ops ov12d2q_internal_ops = {
2702 .open = ov12d2q_open,
2703 };
2704 #endif
2705
2706 static const struct v4l2_subdev_core_ops ov12d2q_core_ops = {
2707 .s_power = ov12d2q_s_power,
2708 .ioctl = ov12d2q_ioctl,
2709 #ifdef CONFIG_COMPAT
2710 .compat_ioctl32 = ov12d2q_compat_ioctl32,
2711 #endif
2712 };
2713
2714 static const struct v4l2_subdev_video_ops ov12d2q_video_ops = {
2715 .s_stream = ov12d2q_s_stream,
2716 .g_frame_interval = ov12d2q_g_frame_interval,
2717 };
2718
2719 static const struct v4l2_subdev_pad_ops ov12d2q_pad_ops = {
2720 .enum_mbus_code = ov12d2q_enum_mbus_code,
2721 .enum_frame_size = ov12d2q_enum_frame_sizes,
2722 .enum_frame_interval = ov12d2q_enum_frame_interval,
2723 .get_fmt = ov12d2q_get_fmt,
2724 .set_fmt = ov12d2q_set_fmt,
2725 .get_mbus_config = ov12d2q_g_mbus_config,
2726 };
2727
2728 static const struct v4l2_subdev_ops ov12d2q_subdev_ops = {
2729 .core = &ov12d2q_core_ops,
2730 .video = &ov12d2q_video_ops,
2731 .pad = &ov12d2q_pad_ops,
2732 };
2733
ov12d2q_set_ctrl(struct v4l2_ctrl * ctrl)2734 static int ov12d2q_set_ctrl(struct v4l2_ctrl *ctrl)
2735 {
2736 struct ov12d2q *ov12d2q = container_of(ctrl->handler,
2737 struct ov12d2q, ctrl_handler);
2738 struct i2c_client *client = ov12d2q->client;
2739 s64 max;
2740 int ret = 0;
2741 u32 again, dgain;
2742 u32 val = 0, x_win = 0, y_win = 0;
2743
2744 /* Propagate change of current control to all related controls */
2745 switch (ctrl->id) {
2746 case V4L2_CID_VBLANK:
2747 /* Update max exposure while meeting expected vblanking */
2748 max = ov12d2q->cur_mode->height + ctrl->val - 16;
2749 __v4l2_ctrl_modify_range(ov12d2q->exposure,
2750 ov12d2q->exposure->minimum, max,
2751 ov12d2q->exposure->step,
2752 ov12d2q->exposure->default_value);
2753 break;
2754 }
2755
2756 if (!pm_runtime_get_if_in_use(&client->dev))
2757 return 0;
2758
2759 switch (ctrl->id) {
2760 case V4L2_CID_EXPOSURE:
2761 if (ov12d2q->cur_mode->hdr_mode != NO_HDR)
2762 goto ctrl_end;
2763 ret = ov12d2q_write_reg(ov12d2q->client,
2764 OV12D2Q_REG_EXP_L_H,
2765 OV12D2Q_REG_VALUE_16BIT,
2766 ctrl->val);
2767 dev_dbg(&client->dev, "set exposure 0x%x\n",
2768 ctrl->val);
2769 break;
2770 case V4L2_CID_ANALOGUE_GAIN:
2771 if (ov12d2q->cur_mode->hdr_mode != NO_HDR)
2772 goto ctrl_end;
2773 if (ctrl->val > 1984) {// >15.5x
2774 dgain = ctrl->val * 10 / 155;
2775 again = 1984;
2776 } else {
2777 dgain = 1024;
2778 again = ctrl->val;
2779 }
2780 ret |= ov12d2q_write_reg(ov12d2q->client,
2781 OV12D2Q_REG_AGAIN_L,
2782 OV12D2Q_REG_VALUE_16BIT,
2783 (again << 1) & 0x7ffe);
2784
2785 ret |= ov12d2q_write_reg(ov12d2q->client,
2786 OV12D2Q_REG_DGAIN_L_H_B,
2787 OV12D2Q_REG_VALUE_24BIT,
2788 (dgain << 6) & 0xfffc0);
2789
2790 dev_dbg(&client->dev, "set gain 0x%x set analog gain 0x%x digital gain 0x%x\n",
2791 ctrl->val, again, dgain);
2792 break;
2793 case V4L2_CID_VBLANK:
2794 ret = ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_VTS,
2795 OV12D2Q_REG_VALUE_16BIT,
2796 ctrl->val + ov12d2q->cur_mode->height);
2797 dev_dbg(&client->dev, "set vblank 0x%x\n",
2798 ctrl->val);
2799 break;
2800 case V4L2_CID_TEST_PATTERN:
2801 ret = ov12d2q_enable_test_pattern(ov12d2q, ctrl->val);
2802 break;
2803 case V4L2_CID_HFLIP:
2804 ret = ov12d2q_read_reg(ov12d2q->client, OV12D2Q_MIRROR_REG,
2805 OV12D2Q_REG_VALUE_08BIT,
2806 &val);
2807 if (ctrl->val)
2808 val |= MIRROR_BIT_MASK;
2809 else
2810 val &= ~MIRROR_BIT_MASK;
2811
2812 ret |= ov12d2q_read_reg(ov12d2q->client, OV12D2Q_REG_ISP_X_WIN,
2813 OV12D2Q_REG_VALUE_16BIT,
2814 &x_win);
2815
2816 if((x_win == 0x0021) && (!(val & 0x04))) {
2817 x_win = 0x0020;
2818 }else if((x_win == 0x0020) && (val & 0x04)) {
2819 x_win = 0x0021;
2820 }
2821
2822 ret |= ov12d2q_write_reg(ov12d2q->client,
2823 OV12D2Q_GROUP_UPDATE_ADDRESS,
2824 OV12D2Q_REG_VALUE_08BIT,
2825 OV12D2Q_GROUP_UPDATE_START_DATA);
2826
2827 ret |= ov12d2q_write_reg(ov12d2q->client, OV12D2Q_MIRROR_REG,
2828 OV12D2Q_REG_VALUE_08BIT,
2829 val);
2830 ret |= ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_ISP_X_WIN,
2831 OV12D2Q_REG_VALUE_16BIT,
2832 x_win);
2833
2834 ret |= ov12d2q_write_reg(ov12d2q->client,
2835 OV12D2Q_GROUP_UPDATE_ADDRESS,
2836 OV12D2Q_REG_VALUE_08BIT,
2837 OV12D2Q_GROUP_UPDATE_END_DATA);
2838 ret |= ov12d2q_write_reg(ov12d2q->client,
2839 OV12D2Q_GROUP_UPDATE_ADDRESS,
2840 OV12D2Q_REG_VALUE_08BIT,
2841 OV12D2Q_GROUP_UPDATE_LAUNCH);
2842 break;
2843 case V4L2_CID_VFLIP:
2844 ret = ov12d2q_read_reg(ov12d2q->client, OV12D2Q_FLIP_REG,
2845 OV12D2Q_REG_VALUE_08BIT,
2846 &val);
2847 if (ctrl->val)
2848 val |= FLIP_BIT_MASK;
2849 else
2850 val &= ~FLIP_BIT_MASK;
2851
2852 ret |= ov12d2q_read_reg(ov12d2q->client, OV12D2Q_REG_ISP_Y_WIN,
2853 OV12D2Q_REG_VALUE_16BIT,
2854 &y_win);
2855
2856 if ((y_win == 0x0004) && (val & 0x04)) {
2857 y_win = 0x0005;
2858 } else if ((y_win == 0x0005) && (!(val & 0x04))) {
2859 y_win = 0x0004;
2860 }
2861
2862 ret |= ov12d2q_write_reg(ov12d2q->client,
2863 OV12D2Q_GROUP_UPDATE_ADDRESS,
2864 OV12D2Q_REG_VALUE_08BIT,
2865 OV12D2Q_GROUP_UPDATE_START_DATA);
2866
2867 ret |= ov12d2q_write_reg(ov12d2q->client, OV12D2Q_FLIP_REG,
2868 OV12D2Q_REG_VALUE_08BIT,
2869 val);
2870 ret |= ov12d2q_write_reg(ov12d2q->client, OV12D2Q_REG_ISP_Y_WIN,
2871 OV12D2Q_REG_VALUE_16BIT,
2872 y_win);
2873
2874 ret |= ov12d2q_write_reg(ov12d2q->client,
2875 OV12D2Q_GROUP_UPDATE_ADDRESS,
2876 OV12D2Q_REG_VALUE_08BIT,
2877 OV12D2Q_GROUP_UPDATE_END_DATA);
2878 ret |= ov12d2q_write_reg(ov12d2q->client,
2879 OV12D2Q_GROUP_UPDATE_ADDRESS,
2880 OV12D2Q_REG_VALUE_08BIT,
2881 OV12D2Q_GROUP_UPDATE_LAUNCH);
2882 break;
2883 default:
2884 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
2885 __func__, ctrl->id, ctrl->val);
2886 break;
2887 }
2888
2889 ctrl_end:
2890 pm_runtime_put(&client->dev);
2891
2892 return ret;
2893 }
2894
2895 static const struct v4l2_ctrl_ops ov12d2q_ctrl_ops = {
2896 .s_ctrl = ov12d2q_set_ctrl,
2897 };
2898
ov12d2q_initialize_controls(struct ov12d2q * ov12d2q)2899 static int ov12d2q_initialize_controls(struct ov12d2q *ov12d2q)
2900 {
2901 const struct ov12d2q_mode *mode;
2902 struct v4l2_ctrl_handler *handler;
2903 s64 exposure_max, vblank_def;
2904 u32 h_blank;
2905 int ret;
2906 u64 dst_link_freq = 0;
2907 u64 dst_pixel_rate = 0;
2908
2909 handler = &ov12d2q->ctrl_handler;
2910 mode = ov12d2q->cur_mode;
2911 ret = v4l2_ctrl_handler_init(handler, 9);
2912 if (ret)
2913 return ret;
2914 handler->lock = &ov12d2q->mutex;
2915
2916 ov12d2q->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
2917 V4L2_CID_LINK_FREQ,
2918 0, 0, link_freq_menu_items);
2919
2920 if (ov12d2q->cur_mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
2921 dst_link_freq = 0;
2922 dst_pixel_rate = PIXEL_RATE_WITH_625M;
2923 }
2924 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
2925 ov12d2q->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2926 V4L2_CID_PIXEL_RATE,
2927 0, PIXEL_RATE_WITH_625M,
2928 1, dst_pixel_rate);
2929
2930 __v4l2_ctrl_s_ctrl(ov12d2q->link_freq,
2931 dst_link_freq);
2932
2933 h_blank = mode->hts_def - mode->width;
2934 ov12d2q->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
2935 h_blank, h_blank, 1, h_blank);
2936 if (ov12d2q->hblank)
2937 ov12d2q->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2938
2939 vblank_def = mode->vts_def - mode->height;
2940 ov12d2q->vblank = v4l2_ctrl_new_std(handler, &ov12d2q_ctrl_ops,
2941 V4L2_CID_VBLANK, vblank_def,
2942 OV12D2Q_VTS_MAX - mode->height,
2943 1, vblank_def);
2944
2945 exposure_max = mode->vts_def - 16;
2946 ov12d2q->exposure = v4l2_ctrl_new_std(handler, &ov12d2q_ctrl_ops,
2947 V4L2_CID_EXPOSURE, OV12D2Q_EXPOSURE_MIN,
2948 exposure_max, OV12D2Q_EXPOSURE_STEP,
2949 mode->exp_def);
2950
2951 ov12d2q->anal_gain = v4l2_ctrl_new_std(handler, &ov12d2q_ctrl_ops,
2952 V4L2_CID_ANALOGUE_GAIN, OV12D2Q_GAIN_MIN,
2953 OV12D2Q_GAIN_MAX, OV12D2Q_GAIN_STEP,
2954 OV12D2Q_GAIN_DEFAULT);
2955
2956 ov12d2q->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
2957 &ov12d2q_ctrl_ops, V4L2_CID_TEST_PATTERN,
2958 ARRAY_SIZE(ov12d2q_test_pattern_menu) - 1,
2959 0, 0, ov12d2q_test_pattern_menu);
2960
2961 ov12d2q->h_flip = v4l2_ctrl_new_std(handler, &ov12d2q_ctrl_ops,
2962 V4L2_CID_HFLIP, 0, 1, 1, 0);
2963
2964 ov12d2q->v_flip = v4l2_ctrl_new_std(handler, &ov12d2q_ctrl_ops,
2965 V4L2_CID_VFLIP, 0, 1, 1, 0);
2966
2967 if (handler->error) {
2968 ret = handler->error;
2969 dev_err(&ov12d2q->client->dev,
2970 "Failed to init controls(%d)\n", ret);
2971 goto err_free_handler;
2972 }
2973
2974 ov12d2q->subdev.ctrl_handler = handler;
2975
2976 return 0;
2977
2978 err_free_handler:
2979 v4l2_ctrl_handler_free(handler);
2980
2981 return ret;
2982 }
2983
ov12d2q_check_sensor_id(struct ov12d2q * ov12d2q,struct i2c_client * client)2984 static int ov12d2q_check_sensor_id(struct ov12d2q *ov12d2q,
2985 struct i2c_client *client)
2986 {
2987 struct device *dev = &ov12d2q->client->dev;
2988 u32 id = 0;
2989 int ret;
2990
2991 if (ov12d2q->is_thunderboot) {
2992 dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
2993 return 0;
2994 }
2995
2996 ret = ov12d2q_read_reg(client, OV12D2Q_REG_CHIP_ID,
2997 OV12D2Q_REG_VALUE_24BIT, &id);
2998 if (id != CHIP_ID) {
2999 dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
3000 return -ENODEV;
3001 }
3002
3003 dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
3004
3005 return 0;
3006 }
3007
ov12d2q_configure_regulators(struct ov12d2q * ov12d2q)3008 static int ov12d2q_configure_regulators(struct ov12d2q *ov12d2q)
3009 {
3010 unsigned int i;
3011
3012 for (i = 0; i < OV12D2Q_NUM_SUPPLIES; i++)
3013 ov12d2q->supplies[i].supply = ov12d2q_supply_names[i];
3014
3015 return devm_regulator_bulk_get(&ov12d2q->client->dev,
3016 OV12D2Q_NUM_SUPPLIES,
3017 ov12d2q->supplies);
3018 }
3019
ov12d2q_probe(struct i2c_client * client,const struct i2c_device_id * id)3020 static int ov12d2q_probe(struct i2c_client *client,
3021 const struct i2c_device_id *id)
3022 {
3023 struct device *dev = &client->dev;
3024 struct device_node *node = dev->of_node;
3025 struct ov12d2q *ov12d2q;
3026 struct v4l2_subdev *sd;
3027 char facing[2];
3028 int ret;
3029 u32 i, hdr_mode = 0;
3030
3031 dev_info(dev, "driver version: %02x.%02x.%02x",
3032 DRIVER_VERSION >> 16,
3033 (DRIVER_VERSION & 0xff00) >> 8,
3034 DRIVER_VERSION & 0x00ff);
3035
3036 ov12d2q = devm_kzalloc(dev, sizeof(*ov12d2q), GFP_KERNEL);
3037 if (!ov12d2q)
3038 return -ENOMEM;
3039
3040 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
3041 &ov12d2q->module_index);
3042 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
3043 &ov12d2q->module_facing);
3044 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
3045 &ov12d2q->module_name);
3046 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
3047 &ov12d2q->len_name);
3048 if (ret) {
3049 dev_err(dev, "could not get module information!\n");
3050 return -EINVAL;
3051 }
3052
3053 ov12d2q->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
3054 ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
3055 &hdr_mode);
3056 if (ret) {
3057 hdr_mode = NO_HDR;
3058 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
3059 }
3060 ov12d2q->cfg_num = ARRAY_SIZE(supported_modes);
3061 for (i = 0; i < ov12d2q->cfg_num; i++) {
3062 if (hdr_mode == supported_modes[i].hdr_mode) {
3063 ov12d2q->cur_mode = &supported_modes[i];
3064 break;
3065 }
3066 }
3067 ov12d2q->client = client;
3068
3069 ov12d2q->xvclk = devm_clk_get(dev, "xvclk");
3070 if (IS_ERR(ov12d2q->xvclk)) {
3071 dev_err(dev, "Failed to get xvclk\n");
3072 return -EINVAL;
3073 }
3074
3075 ov12d2q->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
3076 if (IS_ERR(ov12d2q->reset_gpio))
3077 dev_warn(dev, "Failed to get reset-gpios\n");
3078
3079 ov12d2q->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
3080 if (IS_ERR(ov12d2q->pwdn_gpio))
3081 dev_warn(dev, "Failed to get pwdn-gpios\n");
3082
3083 ov12d2q->pinctrl = devm_pinctrl_get(dev);
3084 if (!IS_ERR(ov12d2q->pinctrl)) {
3085 ov12d2q->pins_default =
3086 pinctrl_lookup_state(ov12d2q->pinctrl,
3087 OF_CAMERA_PINCTRL_STATE_DEFAULT);
3088 if (IS_ERR(ov12d2q->pins_default))
3089 dev_err(dev, "could not get default pinstate\n");
3090
3091 ov12d2q->pins_sleep =
3092 pinctrl_lookup_state(ov12d2q->pinctrl,
3093 OF_CAMERA_PINCTRL_STATE_SLEEP);
3094 if (IS_ERR(ov12d2q->pins_sleep))
3095 dev_err(dev, "could not get sleep pinstate\n");
3096 } else {
3097 dev_err(dev, "no pinctrl\n");
3098 }
3099
3100 ret = ov12d2q_configure_regulators(ov12d2q);
3101 if (ret) {
3102 dev_err(dev, "Failed to get power regulators\n");
3103 return ret;
3104 }
3105
3106 mutex_init(&ov12d2q->mutex);
3107
3108 sd = &ov12d2q->subdev;
3109 v4l2_i2c_subdev_init(sd, client, &ov12d2q_subdev_ops);
3110 ret = ov12d2q_initialize_controls(ov12d2q);
3111 if (ret)
3112 goto err_destroy_mutex;
3113
3114 ret = __ov12d2q_power_on(ov12d2q);
3115 if (ret)
3116 goto err_free_handler;
3117
3118 ret = ov12d2q_check_sensor_id(ov12d2q, client);
3119 if (ret)
3120 goto err_power_off;
3121
3122 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
3123 sd->internal_ops = &ov12d2q_internal_ops;
3124 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
3125 #endif
3126 #if defined(CONFIG_MEDIA_CONTROLLER)
3127 ov12d2q->pad.flags = MEDIA_PAD_FL_SOURCE;
3128 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
3129 ret = media_entity_pads_init(&sd->entity, 1, &ov12d2q->pad);
3130 if (ret < 0)
3131 goto err_power_off;
3132 #endif
3133
3134 memset(facing, 0, sizeof(facing));
3135 if (strcmp(ov12d2q->module_facing, "back") == 0)
3136 facing[0] = 'b';
3137 else
3138 facing[0] = 'f';
3139
3140 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
3141 ov12d2q->module_index, facing,
3142 OV12D2Q_NAME, dev_name(sd->dev));
3143 ret = v4l2_async_register_subdev_sensor_common(sd);
3144 if (ret) {
3145 dev_err(dev, "v4l2 async register subdev failed\n");
3146 goto err_clean_entity;
3147 }
3148
3149 pm_runtime_set_active(dev);
3150 pm_runtime_enable(dev);
3151 pm_runtime_idle(dev);
3152
3153 return 0;
3154
3155 err_clean_entity:
3156 #if defined(CONFIG_MEDIA_CONTROLLER)
3157 media_entity_cleanup(&sd->entity);
3158 #endif
3159 err_power_off:
3160 __ov12d2q_power_off(ov12d2q);
3161 err_free_handler:
3162 v4l2_ctrl_handler_free(&ov12d2q->ctrl_handler);
3163 err_destroy_mutex:
3164 mutex_destroy(&ov12d2q->mutex);
3165
3166 return ret;
3167 }
3168
ov12d2q_remove(struct i2c_client * client)3169 static int ov12d2q_remove(struct i2c_client *client)
3170 {
3171 struct v4l2_subdev *sd = i2c_get_clientdata(client);
3172 struct ov12d2q *ov12d2q = to_ov12d2q(sd);
3173
3174 v4l2_async_unregister_subdev(sd);
3175 #if defined(CONFIG_MEDIA_CONTROLLER)
3176 media_entity_cleanup(&sd->entity);
3177 #endif
3178 v4l2_ctrl_handler_free(&ov12d2q->ctrl_handler);
3179 mutex_destroy(&ov12d2q->mutex);
3180
3181 pm_runtime_disable(&client->dev);
3182 if (!pm_runtime_status_suspended(&client->dev))
3183 __ov12d2q_power_off(ov12d2q);
3184 pm_runtime_set_suspended(&client->dev);
3185
3186 return 0;
3187 }
3188
3189 #if IS_ENABLED(CONFIG_OF)
3190 static const struct of_device_id ov12d2q_of_match[] = {
3191 { .compatible = "ovti,ov12d2q" },
3192 {},
3193 };
3194 MODULE_DEVICE_TABLE(of, ov12d2q_of_match);
3195 #endif
3196
3197 static const struct i2c_device_id ov12d2q_match_id[] = {
3198 { "ovti,ov12d2q", 0 },
3199 { },
3200 };
3201
3202 static struct i2c_driver ov12d2q_i2c_driver = {
3203 .driver = {
3204 .name = OV12D2Q_NAME,
3205 .pm = &ov12d2q_pm_ops,
3206 .of_match_table = of_match_ptr(ov12d2q_of_match),
3207 },
3208 .probe = &ov12d2q_probe,
3209 .remove = &ov12d2q_remove,
3210 .id_table = ov12d2q_match_id,
3211 };
3212
3213 #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
3214 module_i2c_driver(ov12d2q_i2c_driver);
3215 #else
sensor_mod_init(void)3216 static int __init sensor_mod_init(void)
3217 {
3218 return i2c_add_driver(&ov12d2q_i2c_driver);
3219 }
3220
sensor_mod_exit(void)3221 static void __exit sensor_mod_exit(void)
3222 {
3223 i2c_del_driver(&ov12d2q_i2c_driver);
3224 }
3225
3226 device_initcall_sync(sensor_mod_init);
3227 module_exit(sensor_mod_exit);
3228 #endif
3229
3230 MODULE_DESCRIPTION("OmniVision ov12d2q sensor driver");
3231 MODULE_LICENSE("GPL v2");
3232