1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * ov8858 driver
4 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
5 * v0.1.0x00 : 1. create file.
6 * V0.0X01.0X02 fix mclk issue when probe multiple camera.
7 * V0.0X01.0X03 add enum_frame_interval function.
8 * V0.0X01.0X04 add quick stream on/off
9 * V0.0X01.0X05 add function g_mbus_config
10 * V0.0X01.0X06
11 * 1. fix g_mbus_config lane config issues.
12 * 2. and add debug info
13 * 3. add r1a version support
14 */
15
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/of.h>
24 #include <linux/of_graph.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/sysfs.h>
27 #include <linux/slab.h>
28 #include <linux/pinctrl/consumer.h>
29 #include <linux/version.h>
30 #include <linux/rk-camera-module.h>
31
32 #include <media/v4l2-async.h>
33 #include <media/media-entity.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-event.h>
38 #include <media/v4l2-fwnode.h>
39 #include <media/v4l2-image-sizes.h>
40 #include <media/v4l2-mediabus.h>
41 #include <media/v4l2-subdev.h>
42
43 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06)
44
45 #ifndef V4L2_CID_DIGITAL_GAIN
46 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
47 #endif
48 #define OV8858_PIXEL_RATE (360000000LL * 2LL * 2LL / 10LL)
49
50 #define MIPI_FREQ 360000000U
51 #define OV8858_XVCLK_FREQ 24000000
52
53 #define CHIP_ID 0x008858
54 #define OV8858_REG_CHIP_ID 0x300a
55
56 #define OV8858_REG_CTRL_MODE 0x0100
57 #define OV8858_MODE_SW_STANDBY 0x0
58 #define OV8858_MODE_STREAMING 0x1
59
60 #define OV8858_REG_EXPOSURE 0x3500
61 #define OV8858_EXPOSURE_MIN 4
62 #define OV8858_EXPOSURE_STEP 1
63 #define OV8858_VTS_MAX 0x7fff
64
65 #define OV8858_REG_GAIN_H 0x3508
66 #define OV8858_REG_GAIN_L 0x3509
67 #define OV8858_GAIN_H_MASK 0x07
68 #define OV8858_GAIN_H_SHIFT 8
69 #define OV8858_GAIN_L_MASK 0xff
70 #define OV8858_GAIN_MIN 0x80
71 #define OV8858_GAIN_MAX 0x7ff
72 #define OV8858_GAIN_STEP 1
73 #define OV8858_GAIN_DEFAULT 0x80
74
75 #define OV8858_REG_TEST_PATTERN 0x5e00
76 #define OV8858_TEST_PATTERN_ENABLE 0x80
77 #define OV8858_TEST_PATTERN_DISABLE 0x0
78
79 #define OV8858_REG_VTS 0x380e
80
81 #define REG_NULL 0xFFFF
82
83 #define OV8858_REG_VALUE_08BIT 1
84 #define OV8858_REG_VALUE_16BIT 2
85 #define OV8858_REG_VALUE_24BIT 3
86
87 #define OV8858_LANES 2
88 #define OV8858_BITS_PER_SAMPLE 10
89
90 #define OV8858_CHIP_REVISION_REG 0x302A
91 #define OV8858_R1A 0xb0
92 #define OV8858_R2A 0xb2
93
94 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
95 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
96
97 #define OV8858_NAME "ov8858"
98 #define OV8858_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR10_1X10
99
100 #define ov8858_write_1byte(client, reg, val) \
101 ov8858_write_reg((client), (reg), OV8858_REG_VALUE_08BIT, (val))
102
103 #define ov8858_read_1byte(client, reg, val) \
104 ov8858_read_reg((client), (reg), OV8858_REG_VALUE_08BIT, (val))
105
106 static const struct regval *ov8858_global_regs;
107
108 struct ov8858_otp_info_r1a {
109 int flag; // bit[7]: info, bit[6]:wb, bit[5]:vcm, bit[4]:lenc
110 int module_id;
111 int lens_id;
112 int year;
113 int month;
114 int day;
115 int rg_ratio;
116 int bg_ratio;
117 int light_rg;
118 int light_bg;
119 int lenc[110];
120 int vcm_start;
121 int vcm_end;
122 int vcm_dir;
123 };
124
125 struct ov8858_otp_info_r2a {
126 int flag; // bit[7]: info, bit[6]:wb, bit[5]:vcm, bit[4]:lenc
127 int module_id;
128 int lens_id;
129 int year;
130 int month;
131 int day;
132 int rg_ratio;
133 int bg_ratio;
134 int lenc[240];
135 int checksum;
136 int vcm_start;
137 int vcm_end;
138 int vcm_dir;
139 };
140
141 static const char * const ov8858_supply_names[] = {
142 "avdd", /* Analog power */
143 "dovdd", /* Digital I/O power */
144 "dvdd", /* Digital core power */
145 };
146
147 #define OV8858_NUM_SUPPLIES ARRAY_SIZE(ov8858_supply_names)
148
149 struct regval {
150 u16 addr;
151 u8 val;
152 };
153
154 struct ov8858_mode {
155 u32 width;
156 u32 height;
157 struct v4l2_fract max_fps;
158 u32 hts_def;
159 u32 vts_def;
160 u32 exp_def;
161 const struct regval *reg_list;
162 };
163
164 struct ov8858 {
165 struct i2c_client *client;
166 struct clk *xvclk;
167 struct gpio_desc *power_gpio;
168 struct gpio_desc *reset_gpio;
169 struct gpio_desc *pwdn_gpio;
170 struct regulator_bulk_data supplies[OV8858_NUM_SUPPLIES];
171
172 struct pinctrl *pinctrl;
173 struct pinctrl_state *pins_default;
174 struct pinctrl_state *pins_sleep;
175
176 struct v4l2_subdev subdev;
177 struct media_pad pad;
178 struct v4l2_ctrl_handler ctrl_handler;
179 struct v4l2_ctrl *exposure;
180 struct v4l2_ctrl *anal_gain;
181 struct v4l2_ctrl *digi_gain;
182 struct v4l2_ctrl *hblank;
183 struct v4l2_ctrl *vblank;
184 struct v4l2_ctrl *test_pattern;
185 struct mutex mutex;
186 bool streaming;
187 const struct ov8858_mode *cur_mode;
188 bool is_r2a;
189 unsigned int lane_num;
190 unsigned int cfg_num;
191 unsigned int pixel_rate;
192 bool power_on;
193
194 struct ov8858_otp_info_r1a *otp_r1a;
195 struct ov8858_otp_info_r2a *otp_r2a;
196 u32 module_index;
197 const char *module_facing;
198 const char *module_name;
199 const char *len_name;
200 struct rkmodule_inf module_inf;
201 struct rkmodule_awb_cfg awb_cfg;
202 struct rkmodule_lsc_cfg lsc_cfg;
203 };
204
205 #define to_ov8858(sd) container_of(sd, struct ov8858, subdev)
206
207 struct ov8858_id_name {
208 u32 id;
209 char name[RKMODULE_NAME_LEN];
210 };
211
212 static const struct ov8858_id_name ov8858_module_info[] = {
213 {0x01, "Sunny"},
214 {0x02, "Truly"},
215 {0x03, "A-kerr"},
216 {0x04, "LiteArray"},
217 {0x05, "Darling"},
218 {0x06, "Qtech"},
219 {0x07, "OFlim"},
220 {0x08, "Huaquan/Kingcom"},
221 {0x09, "Booyi"},
222 {0x0a, "Laimu"},
223 {0x0b, "WDSEN"},
224 {0x0c, "Sunrise"},
225 {0x0d, "CameraKing"},
226 {0x0e, "Sunniness/Riyong"},
227 {0x0f, "Tongju"},
228 {0x10, "Seasons/Sijichun"},
229 {0x11, "Foxconn"},
230 {0x12, "Importek"},
231 {0x13, "Altek"},
232 {0x14, "ABICO/Ability"},
233 {0x15, "Lite-on"},
234 {0x16, "Chicony"},
235 {0x17, "Primax"},
236 {0x18, "AVC"},
237 {0x19, "Suyin"},
238 {0x21, "Sharp"},
239 {0x31, "MCNEX"},
240 {0x32, "SEMCO"},
241 {0x33, "Partron"},
242 {0x41, "Reach/Zhongliancheng"},
243 {0x42, "BYD"},
244 {0x43, "OSTEC(AoShunChuang)"},
245 {0x44, "Chengli"},
246 {0x45, "Jiali"},
247 {0x46, "Chippack"},
248 {0x47, "RongSheng"},
249 {0x48, "ShineTech/ShenTai"},
250 {0x49, "Brodsands"},
251 {0x50, "Others"},
252 {0x51, "Method"},
253 {0x52, "Sunwin"},
254 {0x53, "LG"},
255 {0x54, "Goertek"},
256 {0x00, "Unknown"}
257 };
258
259 static const struct ov8858_id_name ov8858_lens_info[] = {
260 {0x10, "Largan 9565A1"},
261 {0x11, "Largan 9570A/A1"},
262 {0x12, "Largan 9569A2/A3"},
263 {0x13, "Largan 40108/A1"},
264 {0x14, "Largan 50030A1"},
265 {0x15, "Largan 40109A1"},
266 {0x16, "Largan 40100/A1"},
267 {0x17, "Largan 40112/A1"},
268 {0x30, "Sunny 3813A"},
269 {0x50, "Kantatsu R5AV08/BV"},
270 {0x51, "Kantatsu S5AE08"},
271 {0x52, "Kantatsu S5AE08"},
272 {0x78, "GSEO 8738"},
273 {0x79, "GSEO 8744"},
274 {0x7a, "GSEO 8742"},
275 {0x80, "Foxconn 8028"},
276 {0xd8, "XinXu DS-8335"},
277 {0xd9, "XinXu DS-8341"},
278 {0x00, "Unknown"}
279 };
280
281 /*
282 * Xclk 24Mhz
283 */
284 static const struct regval ov8858_global_regs_r1a_2lane[] = {
285 //@@5.1.1.1 Initialization (Global Setting)
286 //; Slave_ID=0x6c;
287 //{0x0103 ,0x01 }, software reset
288 {0x0100, 0x00},
289 {0x0100, 0x00},
290 {0x0100, 0x00},
291 {0x0100, 0x00},
292 {0x0302, 0x1e},
293 {0x0303, 0x00},
294 {0x0304, 0x03},
295 {0x030e, 0x00},
296 {0x030f, 0x09},
297 {0x0312, 0x01},
298 {0x031e, 0x0c},
299 {0x3600, 0x00},
300 {0x3601, 0x00},
301 {0x3602, 0x00},
302 {0x3603, 0x00},
303 {0x3604, 0x22},
304 {0x3605, 0x30},
305 {0x3606, 0x00},
306 {0x3607, 0x20},
307 {0x3608, 0x11},
308 {0x3609, 0x28},
309 {0x360a, 0x00},
310 {0x360b, 0x06},
311 {0x360c, 0xdc},
312 {0x360d, 0x40},
313 {0x360e, 0x0c},
314 {0x360f, 0x20},
315 {0x3610, 0x07},
316 {0x3611, 0x20},
317 {0x3612, 0x88},
318 {0x3613, 0x80},
319 {0x3614, 0x58},
320 {0x3615, 0x00},
321 {0x3616, 0x4a},
322 {0x3617, 0xb0},
323 {0x3618, 0x56},
324 {0x3619, 0x70},
325 {0x361a, 0x99},
326 {0x361b, 0x00},
327 {0x361c, 0x07},
328 {0x361d, 0x00},
329 {0x361e, 0x00},
330 {0x361f, 0x00},
331 {0x3638, 0xff},
332 {0x3633, 0x0c},
333 {0x3634, 0x0c},
334 {0x3635, 0x0c},
335 {0x3636, 0x0c},
336 {0x3645, 0x13},
337 {0x3646, 0x83},
338 {0x364a, 0x07},
339 {0x3015, 0x01},
340 {0x3018, 0x32},
341 {0x3020, 0x93},
342 {0x3022, 0x01},
343 {0x3031, 0x0a},
344 {0x3034, 0x00},
345 {0x3106, 0x01},
346 {0x3305, 0xf1},
347 {0x3308, 0x00},
348 {0x3309, 0x28},
349 {0x330a, 0x00},
350 {0x330b, 0x20},
351 {0x330c, 0x00},
352 {0x330d, 0x00},
353 {0x330e, 0x00},
354 {0x330f, 0x40},
355 {0x3307, 0x04},
356 {0x3500, 0x00},
357 {0x3501, 0x4d},
358 {0x3502, 0x40},
359 {0x3503, 0x00},
360 {0x3505, 0x80},
361 {0x3508, 0x04},
362 {0x3509, 0x00},
363 {0x350c, 0x00},
364 {0x350d, 0x80},
365 {0x3510, 0x00},
366 {0x3511, 0x02},
367 {0x3512, 0x00},
368 {0x3700, 0x18},
369 {0x3701, 0x0c},
370 {0x3702, 0x28},
371 {0x3703, 0x19},
372 {0x3704, 0x14},
373 {0x3705, 0x00},
374 {0x3706, 0x35},
375 {0x3707, 0x04},
376 {0x3708, 0x24},
377 {0x3709, 0x33},
378 {0x370a, 0x00},
379 {0x370b, 0xb5},
380 {0x370c, 0x04},
381 {0x3718, 0x12},
382 {0x3719, 0x31},
383 {0x3712, 0x42},
384 {0x3714, 0x24},
385 {0x371e, 0x19},
386 {0x371f, 0x40},
387 {0x3720, 0x05},
388 {0x3721, 0x05},
389 {0x3724, 0x06},
390 {0x3725, 0x01},
391 {0x3726, 0x06},
392 {0x3728, 0x05},
393 {0x3729, 0x02},
394 {0x372a, 0x03},
395 {0x372b, 0x53},
396 {0x372c, 0xa3},
397 {0x372d, 0x53},
398 {0x372e, 0x06},
399 {0x372f, 0x10},
400 {0x3730, 0x01},
401 {0x3731, 0x06},
402 {0x3732, 0x14},
403 {0x3733, 0x10},
404 {0x3734, 0x40},
405 {0x3736, 0x20},
406 {0x373a, 0x05},
407 {0x373b, 0x06},
408 {0x373c, 0x0a},
409 {0x373e, 0x03},
410 {0x3755, 0x10},
411 {0x3758, 0x00},
412 {0x3759, 0x4c},
413 {0x375a, 0x06},
414 {0x375b, 0x13},
415 {0x375c, 0x20},
416 {0x375d, 0x02},
417 {0x375e, 0x00},
418 {0x375f, 0x14},
419 {0x3768, 0x22},
420 {0x3769, 0x44},
421 {0x376a, 0x44},
422 {0x3761, 0x00},
423 {0x3762, 0x00},
424 {0x3763, 0x00},
425 {0x3766, 0xff},
426 {0x376b, 0x00},
427 {0x3772, 0x23},
428 {0x3773, 0x02},
429 {0x3774, 0x16},
430 {0x3775, 0x12},
431 {0x3776, 0x04},
432 {0x3777, 0x00},
433 {0x3778, 0x1b},
434 {0x37a0, 0x44},
435 {0x37a1, 0x3d},
436 {0x37a2, 0x3d},
437 {0x37a3, 0x00},
438 {0x37a4, 0x00},
439 {0x37a5, 0x00},
440 {0x37a6, 0x00},
441 {0x37a7, 0x44},
442 {0x37a8, 0x4c},
443 {0x37a9, 0x4c},
444 {0x3760, 0x00},
445 {0x376f, 0x01},
446 {0x37aa, 0x44},
447 {0x37ab, 0x2e},
448 {0x37ac, 0x2e},
449 {0x37ad, 0x33},
450 {0x37ae, 0x0d},
451 {0x37af, 0x0d},
452 {0x37b0, 0x00},
453 {0x37b1, 0x00},
454 {0x37b2, 0x00},
455 {0x37b3, 0x42},
456 {0x37b4, 0x42},
457 {0x37b5, 0x33},
458 {0x37b6, 0x00},
459 {0x37b7, 0x00},
460 {0x37b8, 0x00},
461 {0x37b9, 0xff},
462 {0x3800, 0x00},
463 {0x3801, 0x0c},
464 {0x3802, 0x00},
465 {0x3803, 0x0c},
466 {0x3804, 0x0c},
467 {0x3805, 0xd3},
468 {0x3806, 0x09},
469 {0x3807, 0xa3},
470 {0x3808, 0x06},
471 {0x3809, 0x60},
472 {0x380a, 0x04},
473 {0x380b, 0xc8},
474 {0x380c, 0x07},
475 {0x380d, 0x88},
476 {0x380e, 0x04},
477 {0x380f, 0xdc},
478 {0x3810, 0x00},
479 {0x3811, 0x04},
480 {0x3813, 0x02},
481 {0x3814, 0x03},
482 {0x3815, 0x01},
483 {0x3820, 0x00},
484 {0x3821, 0x67},
485 {0x382a, 0x03},
486 {0x382b, 0x01},
487 {0x3830, 0x08},
488 {0x3836, 0x02},
489 {0x3837, 0x18},
490 {0x3841, 0xff},
491 {0x3846, 0x48},
492 {0x3d85, 0x14},
493 {0x3f08, 0x08},
494 {0x3f0a, 0x80},
495 {0x4000, 0xf1},
496 {0x4001, 0x10},
497 {0x4005, 0x10},
498 {0x4002, 0x27},
499 {0x4009, 0x81},
500 {0x400b, 0x0c},
501 {0x401b, 0x00},
502 {0x401d, 0x00},
503 {0x4020, 0x00},
504 {0x4021, 0x04},
505 {0x4022, 0x04},
506 {0x4023, 0xb9},
507 {0x4024, 0x05},
508 {0x4025, 0x2a},
509 {0x4026, 0x05},
510 {0x4027, 0x2b},
511 {0x4028, 0x00},
512 {0x4029, 0x02},
513 {0x402a, 0x04},
514 {0x402b, 0x04},
515 {0x402c, 0x02},
516 {0x402d, 0x02},
517 {0x402e, 0x08},
518 {0x402f, 0x02},
519 {0x401f, 0x00},
520 {0x4034, 0x3f},
521 {0x403d, 0x04},
522 {0x4300, 0xff},
523 {0x4301, 0x00},
524 {0x4302, 0x0f},
525 {0x4316, 0x00},
526 {0x4500, 0x38},
527 {0x4503, 0x18},
528 {0x4600, 0x00},
529 {0x4601, 0xcb},
530 {0x481f, 0x32},
531 {0x4837, 0x16},
532 {0x4850, 0x10},
533 {0x4851, 0x32},
534 {0x4b00, 0x2a},
535 {0x4b0d, 0x00},
536 {0x4d00, 0x04},
537 {0x4d01, 0x18},
538 {0x4d02, 0xc3},
539 {0x4d03, 0xff},
540 {0x4d04, 0xff},
541 {0x4d05, 0xff},
542 {0x5000, 0x7e},
543 {0x5001, 0x01},
544 {0x5002, 0x08},
545 {0x5003, 0x20},
546 {0x5046, 0x12},
547 {0x5901, 0x00},
548 {0x5e00, 0x00},
549 {0x5e01, 0x41},
550 {0x382d, 0x7f},
551 {0x4825, 0x3a},
552 {0x4826, 0x40},
553 {0x4808, 0x25},
554 //{0x0100, 0x01},
555 {REG_NULL, 0x00},
556 };
557
558 /*
559 * Xclk 24Mhz
560 * max_framerate 30fps
561 * mipi_datarate per lane 720Mbps
562 */
563 static const struct regval ov8858_1632x1224_regs_r1a_2lane[] = {
564 {0x0100, 0x00},
565 {0x030e, 0x00}, // pll2_rdiv
566 {0x030f, 0x09}, // pll2_divsp
567 {0x0312, 0x01}, // pll2_pre_div0, pll2_r_divdac
568 {0x3015, 0x01}, //
569 {0x3501, 0x4d}, // exposure M
570 {0x3502, 0x40}, // exposure L
571 //{0x3508, 0x04}, // gain H
572 {0x3706, 0x35},
573 {0x370a, 0x00},
574 {0x370b, 0xb5},
575 {0x3778, 0x1b},
576 {0x3808, 0x06}, // x output size H
577 {0x3809, 0x60}, // x output size L
578 {0x380a, 0x04}, // y output size H
579 {0x380b, 0xc8}, // y output size L
580 {0x380c, 0x07}, // HTS H
581 {0x380d, 0x88}, // HTS L
582 {0x380e, 0x04}, // VTS H
583 {0x380f, 0xdc}, // VTS L
584 {0x3814, 0x03}, // x odd inc
585 {0x3821, 0x67}, // mirror on, bin on
586 {0x382a, 0x03}, // y odd inc
587 {0x3830, 0x08},
588 {0x3836, 0x02},
589 {0x3f0a, 0x80},
590 {0x4001, 0x10}, // total 128 black column
591 {0x4022, 0x04}, // Anchor left end H
592 {0x4023, 0xb9}, // Anchor left end L
593 {0x4024, 0x05}, // Anchor right start H
594 {0x4025, 0x2a}, // Anchor right start L
595 {0x4026, 0x05}, // Anchor right end H
596 {0x4027, 0x2b}, // Anchor right end L
597 {0x402b, 0x04}, // top black line number
598 {0x402e, 0x08}, // bottom black line start
599 {0x4500, 0x38},
600 {0x4600, 0x00},
601 {0x4601, 0xcb},
602 {0x382d, 0x7f},
603
604 {REG_NULL, 0x00},
605 };
606
607 /*
608 * Xclk 24Mhz
609 * max_framerate 15fps
610 * mipi_datarate per lane 720Mbps
611 */
612 static const struct regval ov8858_3264x2448_regs_r1a_2lane[] = {
613 {0x0100, 0x00},
614
615 {0x030e, 0x02}, // pll2_rdiv
616 {0x030f, 0x04}, // pll2_divsp
617 {0x0312, 0x03}, // pll2_pre_div0, pll2_r_divdac
618 {0x3015, 0x00},
619 {0x3501, 0x9a},
620 {0x3502, 0x20},
621 //{0x3508, 0x02},
622 {0x3706, 0x6a},
623 {0x370a, 0x01},
624 {0x370b, 0x6a},
625 {0x3778, 0x32},
626 {0x3808, 0x0c}, // x output size H
627 {0x3809, 0xc0}, // x output size L
628 {0x380a, 0x09}, // y output size H
629 {0x380b, 0x90}, // y output size L
630 {0x380c, 0x07}, // HTS H
631 {0x380d, 0x94}, // HTS L
632 {0x380e, 0x09}, // VTS H
633 {0x380f, 0xaa}, // VTS L
634 {0x3814, 0x01}, // x odd inc
635 {0x3821, 0x46}, // mirror on, bin off
636 {0x382a, 0x01}, // y odd inc
637 {0x3830, 0x06},
638 {0x3836, 0x01},
639 {0x3f0a, 0x00},
640 {0x4001, 0x00}, // total 256 black column
641 {0x4022, 0x0b}, // Anchor left end H
642 {0x4023, 0xc3}, // Anchor left end L
643 {0x4024, 0x0c}, // Anchor right start H
644 {0x4025, 0x36}, // Anchor right start L
645 {0x4026, 0x0c}, // Anchor right end H
646 {0x4027, 0x37}, // Anchor right end L
647 {0x402b, 0x08}, // top black line number
648 {0x402e, 0x0c}, // bottom black line start
649 {0x4500, 0x58},
650 {0x4600, 0x01},
651 {0x4601, 0x97},
652 {0x382d, 0xff},
653
654 {REG_NULL, 0x00},
655 };
656
657 /*
658 * Xclk 24Mhz
659 */
660 static const struct regval ov8858_global_regs_r1a_4lane[] = {
661 // MIPI=720Mbps, SysClk=72Mhz,Dac Clock=360Mhz.
662 {0x0103, 0x01}, //software reset
663 {0x0100, 0x00}, //software standby
664 {0x0100, 0x00}, //
665 {0x0100, 0x00}, //
666 {0x0100, 0x00}, //
667 {0x0302, 0x1e}, //pll1_multi
668 {0x0303, 0x00}, //pll1_divm
669 {0x0304, 0x03}, //pll1_div_mipi
670 {0x030e, 0x00}, //pll2_rdiv
671 {0x030f, 0x09}, //pll2_divsp
672 {0x0312, 0x01}, //pll2_pre_div0, pll2_r_divdac
673 {0x031e, 0x0c}, //pll1_no_lat
674 {0x3600, 0x00},
675 {0x3601, 0x00},
676 {0x3602, 0x00},
677 {0x3603, 0x00},
678 {0x3604, 0x22},
679 {0x3605, 0x30},
680 {0x3606, 0x00},
681 {0x3607, 0x20},
682 {0x3608, 0x11},
683 {0x3609, 0x28},
684 {0x360a, 0x00},
685 {0x360b, 0x06},
686 {0x360c, 0xdc},
687 {0x360d, 0x40},
688 {0x360e, 0x0c},
689 {0x360f, 0x20},
690 {0x3610, 0x07},
691 {0x3611, 0x20},
692 {0x3612, 0x88},
693 {0x3613, 0x80},
694 {0x3614, 0x58},
695 {0x3615, 0x00},
696 {0x3616, 0x4a},
697 {0x3617, 0xb0},
698 {0x3618, 0x56},
699 {0x3619, 0x70},
700 {0x361a, 0x99},
701 {0x361b, 0x00},
702 {0x361c, 0x07},
703 {0x361d, 0x00},
704 {0x361e, 0x00},
705 {0x361f, 0x00},
706 {0x3638, 0xff},
707 {0x3633, 0x0c},
708 {0x3634, 0x0c},
709 {0x3635, 0x0c},
710 {0x3636, 0x0c},
711 {0x3645, 0x13},
712 {0x3646, 0x83},
713 {0x364a, 0x07},
714 {0x3015, 0x01}, //
715 {0x3018, 0x72}, //MIPI 4 lane
716 {0x3020, 0x93}, //Clock switch output normal, pclk_div =/1
717 {0x3022, 0x01}, //pd_mipi enable when rst_sync
718 {0x3031, 0x0a}, //MIPI 10-bit mode
719 {0x3034, 0x00},
720 {0x3106, 0x01}, //sclk_div, sclk_pre_div
721 {0x3305, 0xf1},
722 {0x3308, 0x00},
723 {0x3309, 0x28},
724 {0x330a, 0x00},
725 {0x330b, 0x20},
726 {0x330c, 0x00},
727 {0x330d, 0x00},
728 {0x330e, 0x00},
729 {0x330f, 0x40},
730 {0x3307, 0x04},
731 {0x3500, 0x00}, //exposure H
732 {0x3501, 0x4d}, //exposure M
733 {0x3502, 0x40}, //exposure L
734 {0x3503, 0x00}, //gain delay 1 frame, exposure delay 1 frame, real gain
735 {0x3505, 0x80}, //gain option
736 {0x3508, 0x04}, //gain H
737 {0x3509, 0x00}, //gain L
738 {0x350c, 0x00}, //short gain H
739 {0x350d, 0x80}, //short gain L
740 {0x3510, 0x00}, //short exposure H
741 {0x3511, 0x02}, //short exposure M
742 {0x3512, 0x00}, //short exposure L
743 {0x3700, 0x18},
744 {0x3701, 0x0c},
745 {0x3702, 0x28},
746 {0x3703, 0x19},
747 {0x3704, 0x14},
748 {0x3705, 0x00},
749 {0x3706, 0x35},
750 {0x3707, 0x04},
751 {0x3708, 0x24},
752 {0x3709, 0x33},
753 {0x370a, 0x00},
754 {0x370b, 0xb5},
755 {0x370c, 0x04},
756 {0x3718, 0x12},
757 {0x3719, 0x31},
758 {0x3712, 0x42},
759 {0x3714, 0x24},
760 {0x371e, 0x19},
761 {0x371f, 0x40},
762 {0x3720, 0x05},
763 {0x3721, 0x05},
764 {0x3724, 0x06},
765 {0x3725, 0x01},
766 {0x3726, 0x06},
767 {0x3728, 0x05},
768 {0x3729, 0x02},
769 {0x372a, 0x03},
770 {0x372b, 0x53},
771 {0x372c, 0xa3},
772 {0x372d, 0x53},
773 {0x372e, 0x06},
774 {0x372f, 0x10},
775 {0x3730, 0x01},
776 {0x3731, 0x06},
777 {0x3732, 0x14},
778 {0x3733, 0x10},
779 {0x3734, 0x40},
780 {0x3736, 0x20},
781 {0x373a, 0x05},
782 {0x373b, 0x06},
783 {0x373c, 0x0a},
784 {0x373e, 0x03},
785 {0x3755, 0x10},
786 {0x3758, 0x00},
787 {0x3759, 0x4c},
788 {0x375a, 0x06},
789 {0x375b, 0x13},
790 {0x375c, 0x20},
791 {0x375d, 0x02},
792 {0x375e, 0x00},
793 {0x375f, 0x14},
794 {0x3768, 0x22},
795 {0x3769, 0x44},
796 {0x376a, 0x44},
797 {0x3761, 0x00},
798 {0x3762, 0x00},
799 {0x3763, 0x00},
800 {0x3766, 0xff},
801 {0x376b, 0x00},
802 {0x3772, 0x23},
803 {0x3773, 0x02},
804 {0x3774, 0x16},
805 {0x3775, 0x12},
806 {0x3776, 0x04},
807 {0x3777, 0x00},
808 {0x3778, 0x1b},
809 {0x37a0, 0x44},
810 {0x37a1, 0x3d},
811 {0x37a2, 0x3d},
812 {0x37a3, 0x00},
813 {0x37a4, 0x00},
814 {0x37a5, 0x00},
815 {0x37a6, 0x00},
816 {0x37a7, 0x44},
817 {0x37a8, 0x4c},
818 {0x37a9, 0x4c},
819 {0x3760, 0x00},
820 {0x376f, 0x01},
821 {0x37aa, 0x44},
822 {0x37ab, 0x2e},
823 {0x37ac, 0x2e},
824 {0x37ad, 0x33},
825 {0x37ae, 0x0d},
826 {0x37af, 0x0d},
827 {0x37b0, 0x00},
828 {0x37b1, 0x00},
829 {0x37b2, 0x00},
830 {0x37b3, 0x42},
831 {0x37b4, 0x42},
832 {0x37b5, 0x33},
833 {0x37b6, 0x00},
834 {0x37b7, 0x00},
835 {0x37b8, 0x00},
836 {0x37b9, 0xff},
837 {0x3800, 0x00}, //x start H
838 {0x3801, 0x0c}, //x start L
839 {0x3802, 0x00}, //y start H
840 {0x3803, 0x0c}, //y start L
841 {0x3804, 0x0c}, //x end H
842 {0x3805, 0xd3}, //x end L
843 {0x3806, 0x09}, //y end H
844 {0x3807, 0xa3}, //y end L
845 {0x3808, 0x06}, //x output size H
846 {0x3809, 0x60}, //x output size L
847 {0x380a, 0x04}, //y output size H
848 {0x380b, 0xc8}, //y output size L
849 {0x380c, 0x07}, //03}, //HTS H
850 {0x380d, 0x88}, //c4}, //HTS L
851 {0x380e, 0x04}, //VTS H
852 {0x380f, 0xdc}, //VTS L
853 {0x3810, 0x00}, //ISP x win H
854 {0x3811, 0x04}, //ISP x win L
855 {0x3813, 0x02}, //ISP y win L
856 {0x3814, 0x03}, //x odd inc
857 {0x3815, 0x01}, //x even inc
858 {0x3820, 0x00}, //vflip off
859 {0x3821, 0x67}, //mirror on, bin on
860 {0x382a, 0x03}, //y odd inc
861 {0x382b, 0x01}, //y even inc
862 {0x3830, 0x08},
863 {0x3836, 0x02},
864 {0x3837, 0x18},
865 {0x3841, 0xff}, //window auto size enable
866 {0x3846, 0x48},
867 {0x3d85, 0x14}, //OTP power up load data enable, setting disable
868 {0x3f08, 0x08},
869 {0x3f0a, 0x80},
870 {0x4000, 0xf1}, //out_range/format/gain/exp_chg_trig, median filter enable
871 {0x4001, 0x10}, //total 128 black column
872 {0x4005, 0x10}, //BLC target L
873 {0x4002, 0x27}, //value used to limit BLC offset
874 {0x4009, 0x81}, //final BLC offset limitation enable
875 {0x400b, 0x0c}, //DCBLC on, DCBLC manual mode on
876 {0x401b, 0x00}, //zero line R coefficient
877 {0x401d, 0x00}, //zoro line T coefficient
878 {0x4020, 0x00}, //Anchor left start H
879 {0x4021, 0x04}, //Anchor left start L
880 {0x4022, 0x04}, //Anchor left end H
881 {0x4023, 0xb9}, //Anchor left end L
882 {0x4024, 0x05}, //Anchor right start H
883 {0x4025, 0x2a}, //Anchor right start L
884 {0x4026, 0x05}, //Anchor right end H
885 {0x4027, 0x2b}, //Anchor right end L
886 {0x4028, 0x00}, //top zero line start
887 {0x4029, 0x02}, //top zero line number
888 {0x402a, 0x04}, //top black line start
889 {0x402b, 0x04}, //top black line number
890 {0x402c, 0x02}, //bottom zero line start
891 {0x402d, 0x02}, //bottom zoro line number
892 {0x402e, 0x08}, //bottom black line start
893 {0x402f, 0x02}, //bottom black line number
894 {0x401f, 0x00}, //interpolation x & y disable, Anchor one disable
895 {0x4034, 0x3f},
896 {0x403d, 0x04}, //md_precision_en
897 {0x4300, 0xff}, //clip max H
898 {0x4301, 0x00}, //clip min H
899 {0x4302, 0x0f}, //clip min L, clip max L
900 {0x4316, 0x00},
901 {0x4500, 0x38},
902 {0x4503, 0x18},
903 {0x4600, 0x00},
904 {0x4601, 0xcb},
905 {0x481f, 0x32}, //clk prepare min
906 {0x4837, 0x16}, //global timing
907 {0x4850, 0x10}, //lane 1 = 1, lane 0 = 0
908 {0x4851, 0x32}, //lane 3 = 3, lane 2 = 2
909 {0x4b00, 0x2a},
910 {0x4b0d, 0x00},
911 {0x4d00, 0x04}, //temperature sensor
912 {0x4d01, 0x18},
913 {0x4d02, 0xc3},
914 {0x4d03, 0xff},
915 {0x4d04, 0xff},
916 {0x4d05, 0xff}, //temperature sensor
917 {0x5000, 0x7e}, //slave/master AWB gain/statistics enable, BPC/WPC on
918 {0x5001, 0x01}, //BLC on
919 {0x5002, 0x08}, //H scale off, WBMATCH off, OTP_DPC off
920 {0x5003, 0x20}, //; DPC_DBC buffer control enable, WB
921 {0x5046, 0x12},
922 {0x5901, 0x00}, //H skip off, V skip off
923 {0x5e00, 0x00}, //test pattern off
924 {0x5e01, 0x41}, //window cut enable
925 {0x382d, 0x7f},
926 {0x4825, 0x3a}, //lpx_p_min
927 {0x4826, 0x40}, //hs_prepare_min
928 {0x4808, 0x25}, //wake up
929 {REG_NULL, 0x00},
930 };
931
932 /*
933 * Xclk 24Mhz
934 * max_framerate 30fps
935 * mipi_datarate per lane 720Mbps
936 */
937 static const struct regval ov8858_3264x2448_regs_r1a_4lane[] = {
938 {0x0100, 0x00},
939 {0x030f, 0x04}, //pll2_divsp
940 {0x3501, 0x9a}, //exposure M
941 {0x3502, 0x20}, //exposure L
942 //{0x3508, 0x02}, //gain H
943 {0x3700, 0x30},
944 {0x3701, 0x18},
945 {0x3702, 0x50},
946 {0x3703, 0x32},
947 {0x3704, 0x28},
948 {0x3706, 0x6a},
949 {0x3707, 0x08},
950 {0x3708, 0x48},
951 {0x3709, 0x66},
952 {0x370a, 0x01},
953 {0x370b, 0x6a},
954 {0x370c, 0x07},
955 {0x3718, 0x14},
956 {0x3712, 0x44},
957 {0x371e, 0x31},
958 {0x371f, 0x7f},
959 {0x3720, 0x0a},
960 {0x3721, 0x0a},
961 {0x3724, 0x0c},
962 {0x3725, 0x02},
963 {0x3726, 0x0c},
964 {0x3728, 0x0a},
965 {0x3729, 0x03},
966 {0x372a, 0x06},
967 {0x372b, 0xa6},
968 {0x372c, 0xa6},
969 {0x372d, 0xa6},
970 {0x372e, 0x0c},
971 {0x372f, 0x20},
972 {0x3730, 0x02},
973 {0x3731, 0x0c},
974 {0x3732, 0x28},
975 {0x3736, 0x30},
976 {0x373a, 0x0a},
977 {0x373b, 0x0b},
978 {0x373c, 0x14},
979 {0x373e, 0x06},
980 {0x375a, 0x0c},
981 {0x375b, 0x26},
982 {0x375d, 0x04},
983 {0x375f, 0x28},
984 {0x3772, 0x46},
985 {0x3773, 0x04},
986 {0x3774, 0x2c},
987 {0x3775, 0x13},
988 {0x3776, 0x08},
989 {0x3778, 0x16},
990 {0x37a0, 0x88},
991 {0x37a1, 0x7a},
992 {0x37a2, 0x7a},
993 {0x37a7, 0x88},
994 {0x37a8, 0x98},
995 {0x37a9, 0x98},
996 {0x37aa, 0x88},
997 {0x37ab, 0x5c},
998 {0x37ac, 0x5c},
999 {0x37ad, 0x55},
1000 {0x37ae, 0x19},
1001 {0x37af, 0x19},
1002 {0x37b3, 0x84},
1003 {0x37b4, 0x84},
1004 {0x37b5, 0x66},
1005 {0x3808, 0x0c}, //x output size H
1006 {0x3809, 0xc0}, //x output size L
1007 {0x380a, 0x09}, //y output size H
1008 {0x380b, 0x90}, //y output size L
1009 {0x380c, 0x07}, //HTS H
1010 {0x380d, 0x94}, //HTS L
1011 {0x380e, 0x09}, //VTS H
1012 {0x380f, 0xaa}, //VTS L
1013 {0x3814, 0x01}, //x odd inc
1014 {0x3821, 0x46}, //mirror on, bin off
1015 {0x382a, 0x01}, //y odd inc
1016 {0x3830, 0x06},
1017 {0x3836, 0x01},
1018 {0x3f08, 0x08},
1019 {0x3f0a, 0x00},
1020 {0x4001, 0x00}, //total 256 black column
1021 {0x4022, 0x0b}, //Anchor left end H
1022 {0x4023, 0xc3}, //Anchor left end L
1023 {0x4024, 0x0c}, //Anchor right start H
1024 {0x4025, 0x36}, //Anchor right start L
1025 {0x4026, 0x0c}, //Anchor right end H
1026 {0x4027, 0x37}, //Anchor right end L
1027 {0x402b, 0x08}, //top black line number
1028 {0x402e, 0x0c}, //bottom black line start
1029 {0x4500, 0x58},
1030 {0x4600, 0x01},
1031 {0x4601, 0x97},
1032 {0x382d, 0xff},
1033 {REG_NULL, 0x00},
1034 };
1035
1036 /*
1037 * Xclk 24Mhz
1038 */
1039 static const struct regval ov8858_global_regs_r2a_2lane[] = {
1040 // MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
1041 //
1042 //
1043 // v00_01_00 (05/29/2014) : initial setting
1044 //
1045 // AM19 : 3617 <- 0xC0
1046 //
1047 // AM20 : change FWC_6K_EN to be default 0x3618=0x5a
1048 {0x0103, 0x01},// software reset for OVTATool only
1049 {0x0103, 0x01},// software reset
1050 {0x0100, 0x00},// software standby
1051 {0x0302, 0x1e},// pll1_multi
1052 {0x0303, 0x00},// pll1_divm
1053 {0x0304, 0x03},// pll1_div_mipi
1054 {0x030e, 0x02},// pll2_rdiv
1055 {0x030f, 0x04},// pll2_divsp
1056 {0x0312, 0x03},// pll2_pre_div0, pll2_r_divdac
1057 {0x031e, 0x0c},// pll1_no_lat
1058 {0x3600, 0x00},
1059 {0x3601, 0x00},
1060 {0x3602, 0x00},
1061 {0x3603, 0x00},
1062 {0x3604, 0x22},
1063 {0x3605, 0x20},
1064 {0x3606, 0x00},
1065 {0x3607, 0x20},
1066 {0x3608, 0x11},
1067 {0x3609, 0x28},
1068 {0x360a, 0x00},
1069 {0x360b, 0x05},
1070 {0x360c, 0xd4},
1071 {0x360d, 0x40},
1072 {0x360e, 0x0c},
1073 {0x360f, 0x20},
1074 {0x3610, 0x07},
1075 {0x3611, 0x20},
1076 {0x3612, 0x88},
1077 {0x3613, 0x80},
1078 {0x3614, 0x58},
1079 {0x3615, 0x00},
1080 {0x3616, 0x4a},
1081 {0x3617, 0x90},
1082 {0x3618, 0x5a},
1083 {0x3619, 0x70},
1084 {0x361a, 0x99},
1085 {0x361b, 0x0a},
1086 {0x361c, 0x07},
1087 {0x361d, 0x00},
1088 {0x361e, 0x00},
1089 {0x361f, 0x00},
1090 {0x3638, 0xff},
1091 {0x3633, 0x0f},
1092 {0x3634, 0x0f},
1093 {0x3635, 0x0f},
1094 {0x3636, 0x12},
1095 {0x3645, 0x13},
1096 {0x3646, 0x83},
1097 {0x364a, 0x07},
1098 {0x3015, 0x00},
1099 {0x3018, 0x32}, // MIPI 2 lane
1100 {0x3020, 0x93}, // Clock switch output normal, pclk_div =/1
1101 {0x3022, 0x01}, // pd_mipi enable when rst_sync
1102 {0x3031, 0x0a}, // MIPI 10-bit mode
1103 {0x3034, 0x00}, //
1104 {0x3106, 0x01}, // sclk_div, sclk_pre_div
1105 {0x3305, 0xf1},
1106 {0x3308, 0x00},
1107 {0x3309, 0x28},
1108 {0x330a, 0x00},
1109 {0x330b, 0x20},
1110 {0x330c, 0x00},
1111 {0x330d, 0x00},
1112 {0x330e, 0x00},
1113 {0x330f, 0x40},
1114 {0x3307, 0x04},
1115 {0x3500, 0x00}, // exposure H
1116 {0x3501, 0x4d}, // exposure M
1117 {0x3502, 0x40}, // exposure L
1118 {0x3503, 0x80}, // gain delay ?, exposure delay 1 frame, real gain
1119 {0x3505, 0x80}, // gain option
1120 {0x3508, 0x02}, // gain H
1121 {0x3509, 0x00}, // gain L
1122 {0x350c, 0x00}, // short gain H
1123 {0x350d, 0x80}, // short gain L
1124 {0x3510, 0x00}, // short exposure H
1125 {0x3511, 0x02}, // short exposure M
1126 {0x3512, 0x00}, // short exposure L
1127 {0x3700, 0x18},
1128 {0x3701, 0x0c},
1129 {0x3702, 0x28},
1130 {0x3703, 0x19},
1131 {0x3704, 0x14},
1132 {0x3705, 0x00},
1133 {0x3706, 0x82},
1134 {0x3707, 0x04},
1135 {0x3708, 0x24},
1136 {0x3709, 0x33},
1137 {0x370a, 0x01},
1138 {0x370b, 0x82},
1139 {0x370c, 0x04},
1140 {0x3718, 0x12},
1141 {0x3719, 0x31},
1142 {0x3712, 0x42},
1143 {0x3714, 0x24},
1144 {0x371e, 0x19},
1145 {0x371f, 0x40},
1146 {0x3720, 0x05},
1147 {0x3721, 0x05},
1148 {0x3724, 0x06},
1149 {0x3725, 0x01},
1150 {0x3726, 0x06},
1151 {0x3728, 0x05},
1152 {0x3729, 0x02},
1153 {0x372a, 0x03},
1154 {0x372b, 0x53},
1155 {0x372c, 0xa3},
1156 {0x372d, 0x53},
1157 {0x372e, 0x06},
1158 {0x372f, 0x10},
1159 {0x3730, 0x01},
1160 {0x3731, 0x06},
1161 {0x3732, 0x14},
1162 {0x3733, 0x10},
1163 {0x3734, 0x40},
1164 {0x3736, 0x20},
1165 {0x373a, 0x05},
1166 {0x373b, 0x06},
1167 {0x373c, 0x0a},
1168 {0x373e, 0x03},
1169 {0x3750, 0x0a},
1170 {0x3751, 0x0e},
1171 {0x3755, 0x10},
1172 {0x3758, 0x00},
1173 {0x3759, 0x4c},
1174 {0x375a, 0x06},
1175 {0x375b, 0x13},
1176 {0x375c, 0x20},
1177 {0x375d, 0x02},
1178 {0x375e, 0x00},
1179 {0x375f, 0x14},
1180 {0x3768, 0x22},
1181 {0x3769, 0x44},
1182 {0x376a, 0x44},
1183 {0x3761, 0x00},
1184 {0x3762, 0x00},
1185 {0x3763, 0x00},
1186 {0x3766, 0xff},
1187 {0x376b, 0x00},
1188 {0x3772, 0x23},
1189 {0x3773, 0x02},
1190 {0x3774, 0x16},
1191 {0x3775, 0x12},
1192 {0x3776, 0x04},
1193 {0x3777, 0x00},
1194 {0x3778, 0x17},
1195 {0x37a0, 0x44},
1196 {0x37a1, 0x3d},
1197 {0x37a2, 0x3d},
1198 {0x37a3, 0x00},
1199 {0x37a4, 0x00},
1200 {0x37a5, 0x00},
1201 {0x37a6, 0x00},
1202 {0x37a7, 0x44},
1203 {0x37a8, 0x4c},
1204 {0x37a9, 0x4c},
1205 {0x3760, 0x00},
1206 {0x376f, 0x01},
1207 {0x37aa, 0x44},
1208 {0x37ab, 0x2e},
1209 {0x37ac, 0x2e},
1210 {0x37ad, 0x33},
1211 {0x37ae, 0x0d},
1212 {0x37af, 0x0d},
1213 {0x37b0, 0x00},
1214 {0x37b1, 0x00},
1215 {0x37b2, 0x00},
1216 {0x37b3, 0x42},
1217 {0x37b4, 0x42},
1218 {0x37b5, 0x31},
1219 {0x37b6, 0x00},
1220 {0x37b7, 0x00},
1221 {0x37b8, 0x00},
1222 {0x37b9, 0xff},
1223 {0x3800, 0x00}, // x start H
1224 {0x3801, 0x0c}, // x start L
1225 {0x3802, 0x00}, // y start H
1226 {0x3803, 0x0c}, // y start L
1227 {0x3804, 0x0c}, // x end H
1228 {0x3805, 0xd3}, // x end L
1229 {0x3806, 0x09}, // y end H
1230 {0x3807, 0xa3}, // y end L
1231 {0x3808, 0x06}, // x output size H
1232 {0x3809, 0x60}, // x output size L
1233 {0x380a, 0x04}, // y output size H
1234 {0x380b, 0xc8}, // y output size L
1235 {0x380c, 0x07}, // HTS H
1236 {0x380d, 0x88}, // HTS L
1237 {0x380e, 0x04}, // VTS H
1238 {0x380f, 0xdc}, // VTS L
1239 {0x3810, 0x00}, // ISP x win H
1240 {0x3811, 0x04}, // ISP x win L
1241 {0x3813, 0x02}, // ISP y win L
1242 {0x3814, 0x03}, // x odd inc
1243 {0x3815, 0x01}, // x even inc
1244 {0x3820, 0x00}, // vflip off
1245 {0x3821, 0x67}, // mirror on, bin on
1246 {0x382a, 0x03}, // y odd inc
1247 {0x382b, 0x01}, // y even inc
1248 {0x3830, 0x08}, //
1249 {0x3836, 0x02}, //
1250 {0x3837, 0x18}, //
1251 {0x3841, 0xff}, // window auto size enable
1252 {0x3846, 0x48}, //
1253 {0x3d85, 0x16}, // OTP power up load data enable
1254 {0x3d8c, 0x73}, // OTP setting start High
1255 {0x3d8d, 0xde}, // OTP setting start Low
1256 {0x3f08, 0x08}, //
1257 {0x3f0a, 0x00}, //
1258 {0x4000, 0xf1}, // out_range_trig, format_chg_trig
1259 {0x4001, 0x10}, // total 128 black column
1260 {0x4005, 0x10}, // BLC target L
1261 {0x4002, 0x27}, // value used to limit BLC offset
1262 {0x4009, 0x81}, // final BLC offset limitation enable
1263 {0x400b, 0x0c}, // DCBLC on, DCBLC manual mode on
1264 {0x401b, 0x00}, // zero line R coefficient
1265 {0x401d, 0x00}, // zoro line T coefficient
1266 {0x4020, 0x00}, // Anchor left start H
1267 {0x4021, 0x04}, // Anchor left start L
1268 {0x4022, 0x06}, // Anchor left end H
1269 {0x4023, 0x00}, // Anchor left end L
1270 {0x4024, 0x0f}, // Anchor right start H
1271 {0x4025, 0x2a}, // Anchor right start L
1272 {0x4026, 0x0f}, // Anchor right end H
1273 {0x4027, 0x2b}, // Anchor right end L
1274 {0x4028, 0x00}, // top zero line start
1275 {0x4029, 0x02}, // top zero line number
1276 {0x402a, 0x04}, // top black line start
1277 {0x402b, 0x04}, // top black line number
1278 {0x402c, 0x00}, // bottom zero line start
1279 {0x402d, 0x02}, // bottom zoro line number
1280 {0x402e, 0x04}, // bottom black line start
1281 {0x402f, 0x04}, // bottom black line number
1282 {0x401f, 0x00}, // interpolation x/y disable, Anchor one disable
1283 {0x4034, 0x3f}, //
1284 {0x403d, 0x04}, // md_precision_en
1285 {0x4300, 0xff}, // clip max H
1286 {0x4301, 0x00}, // clip min H
1287 {0x4302, 0x0f}, // clip min L, clip max L
1288 {0x4316, 0x00}, //
1289 {0x4500, 0x58}, //
1290 {0x4503, 0x18}, //
1291 {0x4600, 0x00}, //
1292 {0x4601, 0xcb}, //
1293 {0x481f, 0x32}, // clk prepare min
1294 {0x4837, 0x16}, // global timing
1295 {0x4850, 0x10}, // lane 1 = 1, lane 0 = 0
1296 {0x4851, 0x32}, // lane 3 = 3, lane 2 = 2
1297 {0x4b00, 0x2a}, //
1298 {0x4b0d, 0x00}, //
1299 {0x4d00, 0x04}, // temperature sensor
1300 {0x4d01, 0x18}, //
1301 {0x4d02, 0xc3}, //
1302 {0x4d03, 0xff}, //
1303 {0x4d04, 0xff}, //
1304 {0x4d05, 0xff}, // temperature sensor
1305 {0x5000, 0xfe}, // lenc on, slave/master AWB gain/statistics enable
1306 {0x5001, 0x01}, // BLC on
1307 {0x5002, 0x08}, // H scale off, WBMATCH off, OTP_DPC
1308 {0x5003, 0x20}, // DPC_DBC buffer control enable, WB
1309 {0x5046, 0x12}, //
1310 {0x5780, 0x3e}, // DPC
1311 {0x5781, 0x0f}, //
1312 {0x5782, 0x44}, //
1313 {0x5783, 0x02}, //
1314 {0x5784, 0x01}, //
1315 {0x5785, 0x00}, //
1316 {0x5786, 0x00}, //
1317 {0x5787, 0x04}, //
1318 {0x5788, 0x02}, //
1319 {0x5789, 0x0f}, //
1320 {0x578a, 0xfd}, //
1321 {0x578b, 0xf5}, //
1322 {0x578c, 0xf5}, //
1323 {0x578d, 0x03}, //
1324 {0x578e, 0x08}, //
1325 {0x578f, 0x0c}, //
1326 {0x5790, 0x08}, //
1327 {0x5791, 0x04}, //
1328 {0x5792, 0x00}, //
1329 {0x5793, 0x52}, //
1330 {0x5794, 0xa3}, // DPC
1331 {0x5871, 0x0d}, // Lenc
1332 {0x5870, 0x18}, //
1333 {0x586e, 0x10}, //
1334 {0x586f, 0x08}, //
1335 {0x58f7, 0x01}, //
1336 {0x58f8, 0x3d}, // Lenc
1337 {0x5901, 0x00}, // H skip off, V skip off
1338 {0x5b00, 0x02}, // OTP DPC start address
1339 {0x5b01, 0x10}, // OTP DPC start address
1340 {0x5b02, 0x03}, // OTP DPC end address
1341 {0x5b03, 0xcf}, // OTP DPC end address
1342 {0x5b05, 0x6c}, // recover method = 2b11,
1343 {0x5e00, 0x00}, // use 0x3ff to test pattern off
1344 {0x5e01, 0x41}, // window cut enable
1345 {0x382d, 0x7f}, //
1346 {0x4825, 0x3a}, // lpx_p_min
1347 {0x4826, 0x40}, // hs_prepare_min
1348 {0x4808, 0x25}, // wake up delay in 1/1024 s
1349 {0x3763, 0x18}, //
1350 {0x3768, 0xcc}, //
1351 {0x470b, 0x28}, //
1352 {0x4202, 0x00}, //
1353 {0x400d, 0x10}, // BLC offset trigger L
1354 {0x4040, 0x04}, // BLC gain th2
1355 {0x403e, 0x04}, // BLC gain th1
1356 {0x4041, 0xc6}, // BLC
1357 {0x3007, 0x80},
1358 {0x400a, 0x01},
1359 {REG_NULL, 0x00},
1360 };
1361
1362 /*
1363 * Xclk 24Mhz
1364 * max_framerate 30fps
1365 * mipi_datarate per lane 720Mbps
1366 */
1367 static const struct regval ov8858_1632x1224_regs_r2a_2lane[] = {
1368 // MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
1369 //
1370 // MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
1371 //
1372 //
1373 // v00_01_00 (05/29/2014) : initial setting
1374 //
1375 // AM19 : 3617 <- 0xC0
1376 //
1377 // AM20 : change FWC_6K_EN to be default 0x3618=0x5a
1378 {0x0100, 0x00},
1379 {0x3501, 0x4d}, // exposure M
1380 {0x3502, 0x40}, // exposure L
1381 {0x3778, 0x17}, //
1382 {0x3808, 0x06}, // x output size H
1383 {0x3809, 0x60}, // x output size L
1384 {0x380a, 0x04}, // y output size H
1385 {0x380b, 0xc8}, // y output size L
1386 {0x380c, 0x07}, // HTS H
1387 {0x380d, 0x88}, // HTS L
1388 {0x380e, 0x04}, // VTS H
1389 {0x380f, 0xdc}, // VTS L
1390 {0x3814, 0x03}, // x odd inc
1391 {0x3821, 0x67}, // mirror on, bin on
1392 {0x382a, 0x03}, // y odd inc
1393 {0x3830, 0x08},
1394 {0x3836, 0x02},
1395 {0x3f0a, 0x00},
1396 {0x4001, 0x10}, // total 128 black column
1397 {0x4022, 0x06}, // Anchor left end H
1398 {0x4023, 0x00}, // Anchor left end L
1399 {0x4025, 0x2a}, // Anchor right start L
1400 {0x4027, 0x2b}, // Anchor right end L
1401 {0x402b, 0x04}, // top black line number
1402 {0x402f, 0x04}, // bottom black line number
1403 {0x4500, 0x58},
1404 {0x4600, 0x00},
1405 {0x4601, 0xcb},
1406 {0x382d, 0x7f},
1407 {0x0100, 0x01},
1408 {REG_NULL, 0x00},
1409 };
1410
1411 /*
1412 * Xclk 24Mhz
1413 * max_framerate 15fps
1414 * mipi_datarate per lane 720Mbps
1415 */
1416 static const struct regval ov8858_3264x2448_regs_r2a_2lane[] = {
1417 {0x0100, 0x00},
1418 {0x3501, 0x9a},// exposure M
1419 {0x3502, 0x20},// exposure L
1420 {0x3778, 0x1a},//
1421 {0x3808, 0x0c},// x output size H
1422 {0x3809, 0xc0},// x output size L
1423 {0x380a, 0x09},// y output size H
1424 {0x380b, 0x90},// y output size L
1425 {0x380c, 0x07},// HTS H
1426 {0x380d, 0x94},// HTS L
1427 {0x380e, 0x09},// VTS H
1428 {0x380f, 0xaa},// VTS L
1429 {0x3814, 0x01},// x odd inc
1430 {0x3821, 0x46},// mirror on, bin off
1431 {0x382a, 0x01},// y odd inc
1432 {0x3830, 0x06},
1433 {0x3836, 0x01},
1434 {0x3f0a, 0x00},
1435 {0x4001, 0x00},// total 256 black column
1436 {0x4022, 0x0c},// Anchor left end H
1437 {0x4023, 0x60},// Anchor left end L
1438 {0x4025, 0x36},// Anchor right start L
1439 {0x4027, 0x37},// Anchor right end L
1440 {0x402b, 0x08},// top black line number
1441 {0x402f, 0x08},// bottom black line number
1442 {0x4500, 0x58},
1443 {0x4600, 0x01},
1444 {0x4601, 0x97},
1445 {0x382d, 0xff},
1446 {REG_NULL, 0x00},
1447 };
1448
1449 /*
1450 * Xclk 24Mhz
1451 */
1452 static const struct regval ov8858_global_regs_r2a_4lane[] = {
1453 //
1454 // MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
1455 //
1456 // v00_01_00 (05/29/2014) : initial setting
1457 //
1458 // AM19 : 3617 <- 0xC0
1459 //
1460 // AM20 : change FWC_6K_EN to be default 0x3618=0x5a
1461 {0x0103, 0x01}, // software reset for OVTATool only
1462 {0x0103, 0x01}, // software reset
1463 {0x0100, 0x00}, // software standby
1464 {0x0302, 0x1e}, // pll1_multi
1465 {0x0303, 0x00}, // pll1_divm
1466 {0x0304, 0x03}, // pll1_div_mipi
1467 {0x030e, 0x00}, // pll2_rdiv
1468 {0x030f, 0x04}, // pll2_divsp
1469 {0x0312, 0x01}, // pll2_pre_div0, pll2_r_divdac
1470 {0x031e, 0x0c}, // pll1_no_lat
1471 {0x3600, 0x00},
1472 {0x3601, 0x00},
1473 {0x3602, 0x00},
1474 {0x3603, 0x00},
1475 {0x3604, 0x22},
1476 {0x3605, 0x20},
1477 {0x3606, 0x00},
1478 {0x3607, 0x20},
1479 {0x3608, 0x11},
1480 {0x3609, 0x28},
1481 {0x360a, 0x00},
1482 {0x360b, 0x05},
1483 {0x360c, 0xd4},
1484 {0x360d, 0x40},
1485 {0x360e, 0x0c},
1486 {0x360f, 0x20},
1487 {0x3610, 0x07},
1488 {0x3611, 0x20},
1489 {0x3612, 0x88},
1490 {0x3613, 0x80},
1491 {0x3614, 0x58},
1492 {0x3615, 0x00},
1493 {0x3616, 0x4a},
1494 {0x3617, 0x90},
1495 {0x3618, 0x5a},
1496 {0x3619, 0x70},
1497 {0x361a, 0x99},
1498 {0x361b, 0x0a},
1499 {0x361c, 0x07},
1500 {0x361d, 0x00},
1501 {0x361e, 0x00},
1502 {0x361f, 0x00},
1503 {0x3638, 0xff},
1504 {0x3633, 0x0f},
1505 {0x3634, 0x0f},
1506 {0x3635, 0x0f},
1507 {0x3636, 0x12},
1508 {0x3645, 0x13},
1509 {0x3646, 0x83},
1510 {0x364a, 0x07},
1511 {0x3015, 0x01}, //
1512 {0x3018, 0x72}, // MIPI 4 lane
1513 {0x3020, 0x93}, // Clock switch output normal, pclk_div =/1
1514 {0x3022, 0x01}, // pd_mipi enable when rst_sync
1515 {0x3031, 0x0a}, // MIPI 10-bit mode
1516 {0x3034, 0x00}, //
1517 {0x3106, 0x01}, // sclk_div, sclk_pre_div
1518 {0x3305, 0xf1},
1519 {0x3308, 0x00},
1520 {0x3309, 0x28},
1521 {0x330a, 0x00},
1522 {0x330b, 0x20},
1523 {0x330c, 0x00},
1524 {0x330d, 0x00},
1525 {0x330e, 0x00},
1526 {0x330f, 0x40},
1527 {0x3307, 0x04},
1528 {0x3500, 0x00}, // exposure H
1529 {0x3501, 0x4d}, // exposure M
1530 {0x3502, 0x40}, // exposure L
1531 {0x3503, 0x80}, // gain delay ?, exposure delay 1 frame, real gain
1532 {0x3505, 0x80}, // gain option
1533 {0x3508, 0x04}, // gain H
1534 {0x3509, 0x00}, // gain L
1535 {0x350c, 0x00}, // short gain H
1536 {0x350d, 0x80}, // short gain L
1537 {0x3510, 0x00}, // short exposure H
1538 {0x3511, 0x02}, // short exposure M
1539 {0x3512, 0x00}, // short exposure L
1540 {0x3700, 0x30},
1541 {0x3701, 0x18},
1542 {0x3702, 0x50},
1543 {0x3703, 0x32},
1544 {0x3704, 0x28},
1545 {0x3705, 0x00},
1546 {0x3706, 0x82},
1547 {0x3707, 0x08},
1548 {0x3708, 0x48},
1549 {0x3709, 0x66},
1550 {0x370a, 0x01},
1551 {0x370b, 0x82},
1552 {0x370c, 0x07},
1553 {0x3718, 0x14},
1554 {0x3719, 0x31},
1555 {0x3712, 0x44},
1556 {0x3714, 0x24},
1557 {0x371e, 0x31},
1558 {0x371f, 0x7f},
1559 {0x3720, 0x0a},
1560 {0x3721, 0x0a},
1561 {0x3724, 0x0c},
1562 {0x3725, 0x02},
1563 {0x3726, 0x0c},
1564 {0x3728, 0x0a},
1565 {0x3729, 0x03},
1566 {0x372a, 0x06},
1567 {0x372b, 0xa6},
1568 {0x372c, 0xa6},
1569 {0x372d, 0xa6},
1570 {0x372e, 0x0c},
1571 {0x372f, 0x20},
1572 {0x3730, 0x02},
1573 {0x3731, 0x0c},
1574 {0x3732, 0x28},
1575 {0x3733, 0x10},
1576 {0x3734, 0x40},
1577 {0x3736, 0x30},
1578 {0x373a, 0x0a},
1579 {0x373b, 0x0b},
1580 {0x373c, 0x14},
1581 {0x373e, 0x06},
1582 {0x3750, 0x0a},
1583 {0x3751, 0x0e},
1584 {0x3755, 0x10},
1585 {0x3758, 0x00},
1586 {0x3759, 0x4c},
1587 {0x375a, 0x0c},
1588 {0x375b, 0x26},
1589 {0x375c, 0x20},
1590 {0x375d, 0x04},
1591 {0x375e, 0x00},
1592 {0x375f, 0x28},
1593 {0x3768, 0x22},
1594 {0x3769, 0x44},
1595 {0x376a, 0x44},
1596 {0x3761, 0x00},
1597 {0x3762, 0x00},
1598 {0x3763, 0x00},
1599 {0x3766, 0xff},
1600 {0x376b, 0x00},
1601 {0x3772, 0x46},
1602 {0x3773, 0x04},
1603 {0x3774, 0x2c},
1604 {0x3775, 0x13},
1605 {0x3776, 0x08},
1606 {0x3777, 0x00},
1607 {0x3778, 0x17},
1608 {0x37a0, 0x88},
1609 {0x37a1, 0x7a},
1610 {0x37a2, 0x7a},
1611 {0x37a3, 0x00},
1612 {0x37a4, 0x00},
1613 {0x37a5, 0x00},
1614 {0x37a6, 0x00},
1615 {0x37a7, 0x88},
1616 {0x37a8, 0x98},
1617 {0x37a9, 0x98},
1618 {0x3760, 0x00},
1619 {0x376f, 0x01},
1620 {0x37aa, 0x88},
1621 {0x37ab, 0x5c},
1622 {0x37ac, 0x5c},
1623 {0x37ad, 0x55},
1624 {0x37ae, 0x19},
1625 {0x37af, 0x19},
1626 {0x37b0, 0x00},
1627 {0x37b1, 0x00},
1628 {0x37b2, 0x00},
1629 {0x37b3, 0x84},
1630 {0x37b4, 0x84},
1631 {0x37b5, 0x60},
1632 {0x37b6, 0x00},
1633 {0x37b7, 0x00},
1634 {0x37b8, 0x00},
1635 {0x37b9, 0xff},
1636 {0x3800, 0x00}, // x start H
1637 {0x3801, 0x0c}, // x start L
1638 {0x3802, 0x00}, // y start H
1639 {0x3803, 0x0c}, // y start L
1640 {0x3804, 0x0c}, // x end H
1641 {0x3805, 0xd3}, // x end L
1642 {0x3806, 0x09}, // y end H
1643 {0x3807, 0xa3}, // y end L
1644 {0x3808, 0x06}, // x output size H
1645 {0x3809, 0x60}, // x output size L
1646 {0x380a, 0x04}, // y output size H
1647 {0x380b, 0xc8}, // y output size L
1648 {0x380c, 0x07}, // HTS H
1649 {0x380d, 0x88}, // HTS L
1650 {0x380e, 0x04}, // VTS H
1651 {0x380f, 0xdc}, // VTS L
1652 {0x3810, 0x00}, // ISP x win H
1653 {0x3811, 0x04}, // ISP x win L
1654 {0x3813, 0x02}, // ISP y win L
1655 {0x3814, 0x03}, // x odd inc
1656 {0x3815, 0x01}, // x even inc
1657 {0x3820, 0x00}, // vflip off
1658 {0x3821, 0x67}, // mirror on, bin o
1659 {0x382a, 0x03}, // y odd inc
1660 {0x382b, 0x01}, // y even inc
1661 {0x3830, 0x08},
1662 {0x3836, 0x02},
1663 {0x3837, 0x18},
1664 {0x3841, 0xff}, // window auto size enable
1665 {0x3846, 0x48}, //
1666 {0x3d85, 0x16}, // OTP power up load data/setting enable enable
1667 {0x3d8c, 0x73}, // OTP setting start High
1668 {0x3d8d, 0xde}, // OTP setting start Low
1669 {0x3f08, 0x10}, //
1670 {0x3f0a, 0x00}, //
1671 {0x4000, 0xf1}, // out_range/format_chg/gain/exp_chg trig enable
1672 {0x4001, 0x10}, // total 128 black column
1673 {0x4005, 0x10}, // BLC target L
1674 {0x4002, 0x27}, // value used to limit BLC offset
1675 {0x4009, 0x81}, // final BLC offset limitation enable
1676 {0x400b, 0x0c}, // DCBLC on, DCBLC manual mode on
1677 {0x401b, 0x00}, // zero line R coefficient
1678 {0x401d, 0x00}, // zoro line T coefficient
1679 {0x4020, 0x00}, // Anchor left start H
1680 {0x4021, 0x04}, // Anchor left start L
1681 {0x4022, 0x06}, // Anchor left end H
1682 {0x4023, 0x00}, // Anchor left end L
1683 {0x4024, 0x0f}, // Anchor right start H
1684 {0x4025, 0x2a}, // Anchor right start L
1685 {0x4026, 0x0f}, // Anchor right end H
1686 {0x4027, 0x2b}, // Anchor right end L
1687 {0x4028, 0x00}, // top zero line start
1688 {0x4029, 0x02}, // top zero line number
1689 {0x402a, 0x04}, // top black line start
1690 {0x402b, 0x04}, // top black line number
1691 {0x402c, 0x00}, // bottom zero line start
1692 {0x402d, 0x02}, // bottom zoro line number
1693 {0x402e, 0x04}, // bottom black line start
1694 {0x402f, 0x04}, // bottom black line number
1695 {0x401f, 0x00}, // interpolation x/y disable, Anchor one disable
1696 {0x4034, 0x3f},
1697 {0x403d, 0x04}, // md_precision_en
1698 {0x4300, 0xff}, // clip max H
1699 {0x4301, 0x00}, // clip min H
1700 {0x4302, 0x0f}, // clip min L, clip max L
1701 {0x4316, 0x00},
1702 {0x4500, 0x58},
1703 {0x4503, 0x18},
1704 {0x4600, 0x00},
1705 {0x4601, 0xcb},
1706 {0x481f, 0x32}, // clk prepare min
1707 {0x4837, 0x16}, // global timing
1708 {0x4850, 0x10}, // lane 1 = 1, lane 0 = 0
1709 {0x4851, 0x32}, // lane 3 = 3, lane 2 = 2
1710 {0x4b00, 0x2a},
1711 {0x4b0d, 0x00},
1712 {0x4d00, 0x04}, // temperature sensor
1713 {0x4d01, 0x18}, //
1714 {0x4d02, 0xc3}, //
1715 {0x4d03, 0xff}, //
1716 {0x4d04, 0xff}, //
1717 {0x4d05, 0xff}, // temperature sensor
1718 {0x5000, 0xfe}, // lenc on, slave/master AWB gain/statistics enable
1719 {0x5001, 0x01}, // BLC on
1720 {0x5002, 0x08}, // WBMATCH sensor's gain, H scale/WBMATCH/OTP_DPC off
1721 {0x5003, 0x20}, // DPC_DBC buffer control enable, WB
1722 {0x5046, 0x12}, //
1723 {0x5780, 0x3e}, // DPC
1724 {0x5781, 0x0f}, //
1725 {0x5782, 0x44}, //
1726 {0x5783, 0x02}, //
1727 {0x5784, 0x01}, //
1728 {0x5785, 0x00}, //
1729 {0x5786, 0x00}, //
1730 {0x5787, 0x04}, //
1731 {0x5788, 0x02}, //
1732 {0x5789, 0x0f}, //
1733 {0x578a, 0xfd}, //
1734 {0x578b, 0xf5}, //
1735 {0x578c, 0xf5}, //
1736 {0x578d, 0x03}, //
1737 {0x578e, 0x08}, //
1738 {0x578f, 0x0c}, //
1739 {0x5790, 0x08}, //
1740 {0x5791, 0x04}, //
1741 {0x5792, 0x00}, //
1742 {0x5793, 0x52}, //
1743 {0x5794, 0xa3}, // DPC
1744 {0x5871, 0x0d}, // Lenc
1745 {0x5870, 0x18}, //
1746 {0x586e, 0x10}, //
1747 {0x586f, 0x08}, //
1748 {0x58f7, 0x01}, //
1749 {0x58f8, 0x3d}, // Lenc
1750 {0x5901, 0x00}, // H skip off, V skip off
1751 {0x5b00, 0x02}, // OTP DPC start address
1752 {0x5b01, 0x10}, // OTP DPC start address
1753 {0x5b02, 0x03}, // OTP DPC end address
1754 {0x5b03, 0xcf}, // OTP DPC end address
1755 {0x5b05, 0x6c}, // recover method = 2b11
1756 {0x5e00, 0x00}, // use 0x3ff to test pattern off
1757 {0x5e01, 0x41}, // window cut enable
1758 {0x382d, 0x7f}, //
1759 {0x4825, 0x3a}, // lpx_p_min
1760 {0x4826, 0x40}, // hs_prepare_min
1761 {0x4808, 0x25}, // wake up delay in 1/1024 s
1762 {0x3763, 0x18},
1763 {0x3768, 0xcc},
1764 {0x470b, 0x28},
1765 {0x4202, 0x00},
1766 {0x400d, 0x10}, // BLC offset trigger L
1767 {0x4040, 0x04}, // BLC gain th2
1768 {0x403e, 0x04}, // BLC gain th1
1769 {0x4041, 0xc6}, // BLC
1770 {0x3007, 0x80},
1771 {0x400a, 0x01},
1772 {REG_NULL, 0x00},
1773 };
1774
1775 /*
1776 * Xclk 24Mhz
1777 * max_framerate 30fps
1778 * mipi_datarate per lane 720Mbps
1779 */
1780 static const struct regval ov8858_3264x2448_regs_r2a_4lane[] = {
1781 {0x0100, 0x00},
1782 {0x3501, 0x9a}, // exposure M
1783 {0x3502, 0x20}, // exposure L
1784 {0x3508, 0x02}, // gain H
1785 {0x3808, 0x0c}, // x output size H
1786 {0x3809, 0xc0}, // x output size L
1787 {0x380a, 0x09}, // y output size H
1788 {0x380b, 0x90}, // y output size L
1789 {0x380c, 0x07}, // HTS H
1790 {0x380d, 0x94}, // HTS L
1791 {0x380e, 0x0a}, // VTS H
1792 {0x380f, 0x00}, // VTS L
1793 {0x3814, 0x01}, // x odd inc
1794 {0x3821, 0x46}, // mirror on, bin off
1795 {0x382a, 0x01}, // y odd inc
1796 {0x3830, 0x06},
1797 {0x3836, 0x01},
1798 {0x3f0a, 0x00},
1799 {0x4001, 0x00}, // total 256 black column
1800 {0x4022, 0x0c}, // Anchor left end H
1801 {0x4023, 0x60}, // Anchor left end L
1802 {0x4025, 0x36}, // Anchor right start L
1803 {0x4027, 0x37}, // Anchor right end L
1804 {0x402b, 0x08}, // top black line number
1805 {0x402f, 0x08}, // interpolation x/y disable, Anchor one disable
1806 {0x4500, 0x58},
1807 {0x4600, 0x01},
1808 {0x4601, 0x97},
1809 {0x382d, 0xff},
1810 {0x030d, 0x1f},
1811 {REG_NULL, 0x00},
1812 };
1813
1814 static const struct ov8858_mode supported_modes_r1a_2lane[] = {
1815 {
1816 .width = 3264,
1817 .height = 2448,
1818 .max_fps = {
1819 .numerator = 10000,
1820 .denominator = 150000,
1821 },
1822 .exp_def = 0x09a0,
1823 .hts_def = 0x0794 * 2,
1824 .vts_def = 0x09aa,
1825 .reg_list = ov8858_3264x2448_regs_r1a_2lane,
1826 },
1827 {
1828 .width = 1632,
1829 .height = 1224,
1830 .max_fps = {
1831 .numerator = 10000,
1832 .denominator = 300000,
1833 },
1834 .exp_def = 0x04d0,
1835 .hts_def = 0x0788,
1836 .vts_def = 0x04dc,
1837 .reg_list = ov8858_1632x1224_regs_r1a_2lane,
1838 },
1839 };
1840
1841 static const struct ov8858_mode supported_modes_r1a_4lane[] = {
1842 {
1843 .width = 3264,
1844 .height = 2448,
1845 .max_fps = {
1846 .numerator = 10000,
1847 .denominator = 300000,
1848 },
1849 .exp_def = 0x09a0,
1850 .hts_def = 0x0794 * 2,
1851 .vts_def = 0x09aa,
1852 .reg_list = ov8858_3264x2448_regs_r1a_4lane,
1853 },
1854 };
1855
1856 static const struct ov8858_mode supported_modes_r2a_2lane[] = {
1857 {
1858 .width = 3264,
1859 .height = 2448,
1860 .max_fps = {
1861 .numerator = 10000,
1862 .denominator = 150000,
1863 },
1864 .exp_def = 0x09a0,
1865 .hts_def = 0x0794 * 2,
1866 .vts_def = 0x09aa,
1867 .reg_list = ov8858_3264x2448_regs_r2a_2lane,
1868 },
1869 {
1870 .width = 1632,
1871 .height = 1224,
1872 .max_fps = {
1873 .numerator = 10000,
1874 .denominator = 300000,
1875 },
1876 .exp_def = 0x04d0,
1877 .hts_def = 0x0788,
1878 .vts_def = 0x04dc,
1879 .reg_list = ov8858_1632x1224_regs_r2a_2lane,
1880 },
1881 };
1882
1883 static const struct ov8858_mode supported_modes_r2a_4lane[] = {
1884 {
1885 .width = 3264,
1886 .height = 2448,
1887 .max_fps = {
1888 .numerator = 10000,
1889 .denominator = 300000,
1890 },
1891 .exp_def = 0x09a0,
1892 .hts_def = 0x0794 * 2,
1893 .vts_def = 0x0a00,
1894 .reg_list = ov8858_3264x2448_regs_r2a_4lane,
1895 },
1896 };
1897
1898 static const struct ov8858_mode *supported_modes;
1899
1900 static const s64 link_freq_menu_items[] = {
1901 MIPI_FREQ
1902 };
1903
1904 static const char * const ov8858_test_pattern_menu[] = {
1905 "Disabled",
1906 "Vertical Color Bar Type 1",
1907 "Vertical Color Bar Type 2",
1908 "Vertical Color Bar Type 3",
1909 "Vertical Color Bar Type 4"
1910 };
1911
1912 /* Write registers up to 4 at a time */
ov8858_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)1913 static int ov8858_write_reg(struct i2c_client *client, u16 reg,
1914 u32 len, u32 val)
1915 {
1916 u32 buf_i, val_i;
1917 u8 buf[6];
1918 u8 *val_p;
1919 __be32 val_be;
1920
1921 if (len > 4)
1922 return -EINVAL;
1923
1924 buf[0] = reg >> 8;
1925 buf[1] = reg & 0xff;
1926
1927 val_be = cpu_to_be32(val);
1928 val_p = (u8 *)&val_be;
1929 buf_i = 2;
1930 val_i = 4 - len;
1931
1932 while (val_i < 4)
1933 buf[buf_i++] = val_p[val_i++];
1934
1935 if (i2c_master_send(client, buf, len + 2) != len + 2)
1936 return -EIO;
1937
1938 return 0;
1939 }
1940
ov8858_write_array(struct i2c_client * client,const struct regval * regs)1941 static int ov8858_write_array(struct i2c_client *client,
1942 const struct regval *regs)
1943 {
1944 u32 i;
1945 int ret = 0;
1946
1947 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
1948 ret = ov8858_write_reg(client, regs[i].addr,
1949 OV8858_REG_VALUE_08BIT,
1950 regs[i].val);
1951
1952 return ret;
1953 }
1954
1955 /* Read registers up to 4 at a time */
ov8858_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)1956 static int ov8858_read_reg(struct i2c_client *client, u16 reg,
1957 unsigned int len, u32 *val)
1958 {
1959 struct i2c_msg msgs[2];
1960 u8 *data_be_p;
1961 __be32 data_be = 0;
1962 __be16 reg_addr_be = cpu_to_be16(reg);
1963 int ret;
1964
1965 if (len > 4 || !len)
1966 return -EINVAL;
1967
1968 data_be_p = (u8 *)&data_be;
1969 /* Write register address */
1970 msgs[0].addr = client->addr;
1971 msgs[0].flags = 0;
1972 msgs[0].len = 2;
1973 msgs[0].buf = (u8 *)®_addr_be;
1974
1975 /* Read data from register */
1976 msgs[1].addr = client->addr;
1977 msgs[1].flags = I2C_M_RD;
1978 msgs[1].len = len;
1979 msgs[1].buf = &data_be_p[4 - len];
1980
1981 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1982 if (ret != ARRAY_SIZE(msgs))
1983 return -EIO;
1984
1985 *val = be32_to_cpu(data_be);
1986
1987 return 0;
1988 }
1989
ov8858_get_reso_dist(const struct ov8858_mode * mode,struct v4l2_mbus_framefmt * framefmt)1990 static int ov8858_get_reso_dist(const struct ov8858_mode *mode,
1991 struct v4l2_mbus_framefmt *framefmt)
1992 {
1993 return abs(mode->width - framefmt->width) +
1994 abs(mode->height - framefmt->height);
1995 }
1996
1997 static const struct ov8858_mode *
ov8858_find_best_fit(struct ov8858 * ov8858,struct v4l2_subdev_format * fmt)1998 ov8858_find_best_fit(struct ov8858 *ov8858,
1999 struct v4l2_subdev_format *fmt)
2000 {
2001 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
2002 int dist;
2003 int cur_best_fit = 0;
2004 int cur_best_fit_dist = -1;
2005 unsigned int i;
2006
2007 for (i = 0; i < ov8858->cfg_num; i++) {
2008 dist = ov8858_get_reso_dist(&supported_modes[i], framefmt);
2009 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
2010 cur_best_fit_dist = dist;
2011 cur_best_fit = i;
2012 }
2013 }
2014
2015 return &supported_modes[cur_best_fit];
2016 }
2017
ov8858_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)2018 static int ov8858_set_fmt(struct v4l2_subdev *sd,
2019 struct v4l2_subdev_pad_config *cfg,
2020 struct v4l2_subdev_format *fmt)
2021 {
2022 struct ov8858 *ov8858 = to_ov8858(sd);
2023 const struct ov8858_mode *mode;
2024 s64 h_blank, vblank_def;
2025
2026 mutex_lock(&ov8858->mutex);
2027
2028 mode = ov8858_find_best_fit(ov8858, fmt);
2029 fmt->format.code = OV8858_MEDIA_BUS_FMT;
2030 fmt->format.width = mode->width;
2031 fmt->format.height = mode->height;
2032 fmt->format.field = V4L2_FIELD_NONE;
2033 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2034 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2035 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
2036 #else
2037 mutex_unlock(&ov8858->mutex);
2038 return -ENOTTY;
2039 #endif
2040 } else {
2041 ov8858->cur_mode = mode;
2042 h_blank = mode->hts_def - mode->width;
2043 __v4l2_ctrl_modify_range(ov8858->hblank, h_blank,
2044 h_blank, 1, h_blank);
2045 vblank_def = mode->vts_def - mode->height;
2046 __v4l2_ctrl_modify_range(ov8858->vblank, vblank_def,
2047 OV8858_VTS_MAX - mode->height,
2048 1, vblank_def);
2049 }
2050
2051 mutex_unlock(&ov8858->mutex);
2052
2053 return 0;
2054 }
2055
ov8858_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)2056 static int ov8858_get_fmt(struct v4l2_subdev *sd,
2057 struct v4l2_subdev_pad_config *cfg,
2058 struct v4l2_subdev_format *fmt)
2059 {
2060 struct ov8858 *ov8858 = to_ov8858(sd);
2061 const struct ov8858_mode *mode = ov8858->cur_mode;
2062
2063 mutex_lock(&ov8858->mutex);
2064 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2065 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2066 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2067 #else
2068 mutex_unlock(&ov8858->mutex);
2069 return -ENOTTY;
2070 #endif
2071 } else {
2072 fmt->format.width = mode->width;
2073 fmt->format.height = mode->height;
2074 fmt->format.code = OV8858_MEDIA_BUS_FMT;
2075 fmt->format.field = V4L2_FIELD_NONE;
2076 }
2077 mutex_unlock(&ov8858->mutex);
2078
2079 return 0;
2080 }
2081
ov8858_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)2082 static int ov8858_enum_mbus_code(struct v4l2_subdev *sd,
2083 struct v4l2_subdev_pad_config *cfg,
2084 struct v4l2_subdev_mbus_code_enum *code)
2085 {
2086 if (code->index != 0)
2087 return -EINVAL;
2088 code->code = OV8858_MEDIA_BUS_FMT;
2089
2090 return 0;
2091 }
2092
ov8858_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)2093 static int ov8858_enum_frame_sizes(struct v4l2_subdev *sd,
2094 struct v4l2_subdev_pad_config *cfg,
2095 struct v4l2_subdev_frame_size_enum *fse)
2096 {
2097 struct ov8858 *ov8858 = to_ov8858(sd);
2098
2099 if (fse->index >= ov8858->cfg_num)
2100 return -EINVAL;
2101
2102 if (fse->code != OV8858_MEDIA_BUS_FMT)
2103 return -EINVAL;
2104
2105 fse->min_width = supported_modes[fse->index].width;
2106 fse->max_width = supported_modes[fse->index].width;
2107 fse->max_height = supported_modes[fse->index].height;
2108 fse->min_height = supported_modes[fse->index].height;
2109
2110 return 0;
2111 }
2112
ov8858_enable_test_pattern(struct ov8858 * ov8858,u32 pattern)2113 static int ov8858_enable_test_pattern(struct ov8858 *ov8858, u32 pattern)
2114 {
2115 u32 val;
2116
2117 if (pattern)
2118 val = (pattern - 1) | OV8858_TEST_PATTERN_ENABLE;
2119 else
2120 val = OV8858_TEST_PATTERN_DISABLE;
2121
2122 return ov8858_write_reg(ov8858->client,
2123 OV8858_REG_TEST_PATTERN,
2124 OV8858_REG_VALUE_08BIT,
2125 val);
2126 }
2127
ov8858_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)2128 static int ov8858_g_frame_interval(struct v4l2_subdev *sd,
2129 struct v4l2_subdev_frame_interval *fi)
2130 {
2131 struct ov8858 *ov8858 = to_ov8858(sd);
2132 const struct ov8858_mode *mode = ov8858->cur_mode;
2133
2134 fi->interval = mode->max_fps;
2135
2136 return 0;
2137 }
2138
ov8858_get_r1a_otp(struct ov8858_otp_info_r1a * otp_r1a,struct rkmodule_inf * inf)2139 static void ov8858_get_r1a_otp(struct ov8858_otp_info_r1a *otp_r1a,
2140 struct rkmodule_inf *inf)
2141 {
2142 u32 i, j;
2143 int rg, bg;
2144
2145 /* fac */
2146 if (otp_r1a->flag & 0x80) {
2147 inf->fac.flag = 1;
2148 inf->fac.year = otp_r1a->year;
2149 inf->fac.month = otp_r1a->month;
2150 inf->fac.day = otp_r1a->day;
2151
2152 for (i = 0; i < ARRAY_SIZE(ov8858_module_info) - 1; i++) {
2153 if (ov8858_module_info[i].id == otp_r1a->module_id)
2154 break;
2155 }
2156 strlcpy(inf->fac.module, ov8858_module_info[i].name,
2157 sizeof(inf->fac.module));
2158
2159 for (i = 0; i < ARRAY_SIZE(ov8858_lens_info) - 1; i++) {
2160 if (ov8858_lens_info[i].id == otp_r1a->lens_id)
2161 break;
2162 }
2163 strlcpy(inf->fac.lens, ov8858_lens_info[i].name,
2164 sizeof(inf->fac.lens));
2165 }
2166
2167 /* awb */
2168 if (otp_r1a->flag & 0x40) {
2169 if (otp_r1a->light_rg == 0)
2170 /* no light source information in OTP ,light factor = 1 */
2171 rg = otp_r1a->rg_ratio;
2172 else
2173 rg = otp_r1a->rg_ratio * (otp_r1a->light_rg + 512) / 1024;
2174
2175 if (otp_r1a->light_bg == 0)
2176 /* no light source information in OTP ,light factor = 1 */
2177 bg = otp_r1a->bg_ratio;
2178 else
2179 bg = otp_r1a->bg_ratio * (otp_r1a->light_bg + 512) / 1024;
2180
2181 inf->awb.flag = 1;
2182 inf->awb.r_value = rg;
2183 inf->awb.b_value = bg;
2184 inf->awb.gr_value = 0x200;
2185 inf->awb.gb_value = 0x200;
2186
2187 inf->awb.golden_r_value = 0;
2188 inf->awb.golden_b_value = 0;
2189 inf->awb.golden_gr_value = 0;
2190 inf->awb.golden_gb_value = 0;
2191 }
2192
2193 /* af */
2194 if (otp_r1a->flag & 0x20) {
2195 inf->af.flag = 1;
2196 inf->af.dir_cnt = 1;
2197 inf->af.af_otp[0].vcm_start = otp_r1a->vcm_start;
2198 inf->af.af_otp[0].vcm_end = otp_r1a->vcm_end;
2199 inf->af.af_otp[0].vcm_dir = otp_r1a->vcm_dir;
2200 }
2201
2202 /* lsc */
2203 if (otp_r1a->flag & 0x10) {
2204 inf->lsc.flag = 1;
2205 inf->lsc.decimal_bits = 0;
2206 inf->lsc.lsc_w = 6;
2207 inf->lsc.lsc_h = 6;
2208
2209 j = 0;
2210 for (i = 0; i < 36; i++) {
2211 inf->lsc.lsc_gr[i] = otp_r1a->lenc[j++];
2212 inf->lsc.lsc_gb[i] = inf->lsc.lsc_gr[i];
2213 }
2214 for (i = 0; i < 36; i++)
2215 inf->lsc.lsc_b[i] = otp_r1a->lenc[j++] + otp_r1a->lenc[108];
2216 for (i = 0; i < 36; i++)
2217 inf->lsc.lsc_r[i] = otp_r1a->lenc[j++] + otp_r1a->lenc[109];
2218 }
2219 }
2220
ov8858_get_r2a_otp(struct ov8858_otp_info_r2a * otp_r2a,struct rkmodule_inf * inf)2221 static void ov8858_get_r2a_otp(struct ov8858_otp_info_r2a *otp_r2a,
2222 struct rkmodule_inf *inf)
2223 {
2224 unsigned int i, j;
2225 int rg, bg;
2226
2227 /* fac / awb */
2228 if (otp_r2a->flag & 0xC0) {
2229 inf->fac.flag = 1;
2230 inf->fac.year = otp_r2a->year;
2231 inf->fac.month = otp_r2a->month;
2232 inf->fac.day = otp_r2a->day;
2233
2234 for (i = 0; i < ARRAY_SIZE(ov8858_module_info) - 1; i++) {
2235 if (ov8858_module_info[i].id == otp_r2a->module_id)
2236 break;
2237 }
2238 strlcpy(inf->fac.module, ov8858_module_info[i].name,
2239 sizeof(inf->fac.module));
2240
2241 for (i = 0; i < ARRAY_SIZE(ov8858_lens_info) - 1; i++) {
2242 if (ov8858_lens_info[i].id == otp_r2a->lens_id)
2243 break;
2244 }
2245 strlcpy(inf->fac.lens, ov8858_lens_info[i].name,
2246 sizeof(inf->fac.lens));
2247
2248 rg = otp_r2a->rg_ratio;
2249 bg = otp_r2a->bg_ratio;
2250
2251 inf->awb.flag = 1;
2252 inf->awb.r_value = rg;
2253 inf->awb.b_value = bg;
2254 inf->awb.gr_value = 0x200;
2255 inf->awb.gb_value = 0x200;
2256
2257 inf->awb.golden_r_value = 0;
2258 inf->awb.golden_b_value = 0;
2259 inf->awb.golden_gr_value = 0;
2260 inf->awb.golden_gb_value = 0;
2261 }
2262
2263 /* af */
2264 if (otp_r2a->flag & 0x20) {
2265 inf->af.flag = 1;
2266 inf->af.dir_cnt = 1;
2267 inf->af.af_otp[0].vcm_start = otp_r2a->vcm_start;
2268 inf->af.af_otp[0].vcm_end = otp_r2a->vcm_end;
2269 inf->af.af_otp[0].vcm_dir = otp_r2a->vcm_dir;
2270 }
2271
2272 /* lsc */
2273 if (otp_r2a->flag & 0x10) {
2274 inf->lsc.flag = 1;
2275 inf->lsc.decimal_bits = 0;
2276 inf->lsc.lsc_w = 8;
2277 inf->lsc.lsc_h = 10;
2278
2279 j = 0;
2280 for (i = 0; i < 80; i++) {
2281 inf->lsc.lsc_gr[i] = otp_r2a->lenc[j++];
2282 inf->lsc.lsc_gb[i] = inf->lsc.lsc_gr[i];
2283 }
2284 for (i = 0; i < 80; i++)
2285 inf->lsc.lsc_b[i] = otp_r2a->lenc[j++];
2286 for (i = 0; i < 80; i++)
2287 inf->lsc.lsc_r[i] = otp_r2a->lenc[j++];
2288 }
2289 }
2290
ov8858_get_module_inf(struct ov8858 * ov8858,struct rkmodule_inf * inf)2291 static void ov8858_get_module_inf(struct ov8858 *ov8858,
2292 struct rkmodule_inf *inf)
2293 {
2294 struct ov8858_otp_info_r1a *otp_r1a = ov8858->otp_r1a;
2295 struct ov8858_otp_info_r2a *otp_r2a = ov8858->otp_r2a;
2296
2297 strlcpy(inf->base.sensor, OV8858_NAME, sizeof(inf->base.sensor));
2298 strlcpy(inf->base.module, ov8858->module_name, sizeof(inf->base.module));
2299 strlcpy(inf->base.lens, ov8858->len_name, sizeof(inf->base.lens));
2300
2301 if (ov8858->is_r2a) {
2302 if (otp_r2a)
2303 ov8858_get_r2a_otp(otp_r2a, inf);
2304 } else {
2305 if (otp_r1a)
2306 ov8858_get_r1a_otp(otp_r1a, inf);
2307 }
2308 }
2309
ov8858_set_awb_cfg(struct ov8858 * ov8858,struct rkmodule_awb_cfg * cfg)2310 static void ov8858_set_awb_cfg(struct ov8858 *ov8858,
2311 struct rkmodule_awb_cfg *cfg)
2312 {
2313 mutex_lock(&ov8858->mutex);
2314 memcpy(&ov8858->awb_cfg, cfg, sizeof(*cfg));
2315 mutex_unlock(&ov8858->mutex);
2316 }
2317
ov8858_set_lsc_cfg(struct ov8858 * ov8858,struct rkmodule_lsc_cfg * cfg)2318 static void ov8858_set_lsc_cfg(struct ov8858 *ov8858,
2319 struct rkmodule_lsc_cfg *cfg)
2320 {
2321 mutex_lock(&ov8858->mutex);
2322 memcpy(&ov8858->lsc_cfg, cfg, sizeof(*cfg));
2323 mutex_unlock(&ov8858->mutex);
2324 }
2325
ov8858_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)2326 static long ov8858_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
2327 {
2328 struct ov8858 *ov8858 = to_ov8858(sd);
2329 long ret = 0;
2330 u32 stream = 0;
2331
2332 switch (cmd) {
2333 case RKMODULE_GET_MODULE_INFO:
2334 ov8858_get_module_inf(ov8858, (struct rkmodule_inf *)arg);
2335 break;
2336 case RKMODULE_AWB_CFG:
2337 ov8858_set_awb_cfg(ov8858, (struct rkmodule_awb_cfg *)arg);
2338 break;
2339 case RKMODULE_LSC_CFG:
2340 ov8858_set_lsc_cfg(ov8858, (struct rkmodule_lsc_cfg *)arg);
2341 break;
2342 case RKMODULE_SET_QUICK_STREAM:
2343
2344 stream = *((u32 *)arg);
2345
2346 if (stream)
2347 ret = ov8858_write_reg(ov8858->client,
2348 OV8858_REG_CTRL_MODE,
2349 OV8858_REG_VALUE_08BIT,
2350 OV8858_MODE_STREAMING);
2351 else
2352 ret = ov8858_write_reg(ov8858->client,
2353 OV8858_REG_CTRL_MODE,
2354 OV8858_REG_VALUE_08BIT,
2355 OV8858_MODE_SW_STANDBY);
2356 break;
2357 default:
2358 ret = -ENOTTY;
2359 break;
2360 }
2361
2362 return ret;
2363 }
2364
2365 #ifdef CONFIG_COMPAT
ov8858_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)2366 static long ov8858_compat_ioctl32(struct v4l2_subdev *sd,
2367 unsigned int cmd, unsigned long arg)
2368 {
2369 void __user *up = compat_ptr(arg);
2370 struct rkmodule_inf *inf;
2371 struct rkmodule_awb_cfg *awb_cfg;
2372 struct rkmodule_lsc_cfg *lsc_cfg;
2373 long ret = 0;
2374 u32 stream = 0;
2375
2376 switch (cmd) {
2377 case RKMODULE_GET_MODULE_INFO:
2378 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
2379 if (!inf) {
2380 ret = -ENOMEM;
2381 return ret;
2382 }
2383
2384 ret = ov8858_ioctl(sd, cmd, inf);
2385 if (!ret)
2386 ret = copy_to_user(up, inf, sizeof(*inf));
2387 kfree(inf);
2388 break;
2389 case RKMODULE_AWB_CFG:
2390 awb_cfg = kzalloc(sizeof(*awb_cfg), GFP_KERNEL);
2391 if (!awb_cfg) {
2392 ret = -ENOMEM;
2393 return ret;
2394 }
2395
2396 ret = copy_from_user(awb_cfg, up, sizeof(*awb_cfg));
2397 if (!ret)
2398 ret = ov8858_ioctl(sd, cmd, awb_cfg);
2399 kfree(awb_cfg);
2400 break;
2401 case RKMODULE_LSC_CFG:
2402 lsc_cfg = kzalloc(sizeof(*lsc_cfg), GFP_KERNEL);
2403 if (!lsc_cfg) {
2404 ret = -ENOMEM;
2405 return ret;
2406 }
2407
2408 ret = copy_from_user(lsc_cfg, up, sizeof(*lsc_cfg));
2409 if (!ret)
2410 ret = ov8858_ioctl(sd, cmd, lsc_cfg);
2411 kfree(lsc_cfg);
2412 break;
2413 case RKMODULE_SET_QUICK_STREAM:
2414 ret = copy_from_user(&stream, up, sizeof(u32));
2415 if (!ret)
2416 ret = ov8858_ioctl(sd, cmd, &stream);
2417 break;
2418 default:
2419 ret = -ENOTTY;
2420 break;
2421 }
2422
2423 return ret;
2424 }
2425 #endif
2426
2427 /*--------------------------------------------------------------------------*/
ov8858_apply_otp_r1a(struct ov8858 * ov8858)2428 static int ov8858_apply_otp_r1a(struct ov8858 *ov8858)
2429 {
2430 int rg, bg, R_gain, G_gain, B_gain, base_gain, temp;
2431 struct i2c_client *client = ov8858->client;
2432 struct ov8858_otp_info_r1a *otp_ptr = ov8858->otp_r1a;
2433 struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg;
2434 struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg;
2435 u32 golden_bg_ratio = 0;
2436 u32 golden_rg_ratio = 0;
2437 u32 golden_g_value = 0;
2438 u32 i;
2439
2440 if (awb_cfg->enable) {
2441 golden_g_value = (awb_cfg->golden_gb_value +
2442 awb_cfg->golden_gr_value) / 2;
2443 golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value;
2444 golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value;
2445 }
2446
2447 /* apply OTP WB Calibration */
2448 if ((otp_ptr->flag & 0x40) && golden_bg_ratio && golden_rg_ratio) {
2449 if (otp_ptr->light_rg == 0)
2450 /*
2451 * no light source information in OTP,
2452 * light factor = 1
2453 */
2454 rg = otp_ptr->rg_ratio;
2455 else
2456 rg = otp_ptr->rg_ratio *
2457 (otp_ptr->light_rg + 512) / 1024;
2458
2459 if (otp_ptr->light_bg == 0)
2460 /*
2461 * no light source information in OTP,
2462 * light factor = 1
2463 */
2464 bg = otp_ptr->bg_ratio;
2465 else
2466 bg = otp_ptr->bg_ratio *
2467 (otp_ptr->light_bg + 512) / 1024;
2468
2469 /* calculate G gain */
2470 R_gain = (golden_rg_ratio * 1000) / rg;
2471 B_gain = (golden_bg_ratio * 1000) / bg;
2472 G_gain = 1000;
2473 if (R_gain < 1000 || B_gain < 1000) {
2474 if (R_gain < B_gain)
2475 base_gain = R_gain;
2476 else
2477 base_gain = B_gain;
2478 } else {
2479 base_gain = G_gain;
2480 }
2481 R_gain = 0x400 * R_gain / (base_gain);
2482 B_gain = 0x400 * B_gain / (base_gain);
2483 G_gain = 0x400 * G_gain / (base_gain);
2484
2485 /* update sensor WB gain */
2486 if (R_gain > 0x400) {
2487 ov8858_write_1byte(client, 0x5032, R_gain >> 8);
2488 ov8858_write_1byte(client, 0x5033, R_gain & 0x00ff);
2489 }
2490 if (G_gain > 0x400) {
2491 ov8858_write_1byte(client, 0x5034, G_gain >> 8);
2492 ov8858_write_1byte(client, 0x5035, G_gain & 0x00ff);
2493 }
2494 if (B_gain > 0x400) {
2495 ov8858_write_1byte(client, 0x5036, B_gain >> 8);
2496 ov8858_write_1byte(client, 0x5037, B_gain & 0x00ff);
2497 }
2498
2499 dev_dbg(&client->dev, "apply awb gain: 0x%x, 0x%x, 0x%x\n",
2500 R_gain, G_gain, B_gain);
2501 }
2502
2503 /* apply OTP Lenc Calibration */
2504 if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) {
2505 ov8858_read_1byte(client, 0x5000, &temp);
2506 temp = 0x80 | temp;
2507 ov8858_write_1byte(client, 0x5000, temp);
2508 for (i = 0; i < ARRAY_SIZE(otp_ptr->lenc); i++) {
2509 ov8858_write_1byte(client, 0x5800 + i,
2510 otp_ptr->lenc[i]);
2511 dev_dbg(&client->dev, "apply lenc[%d]: 0x%x\n",
2512 i, otp_ptr->lenc[i]);
2513 }
2514 }
2515
2516 return 0;
2517 }
2518
ov8858_apply_otp_r2a(struct ov8858 * ov8858)2519 static int ov8858_apply_otp_r2a(struct ov8858 *ov8858)
2520 {
2521 int rg, bg, R_gain, G_gain, B_gain, base_gain, temp;
2522 struct i2c_client *client = ov8858->client;
2523 struct ov8858_otp_info_r2a *otp_ptr = ov8858->otp_r2a;
2524 struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg;
2525 struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg;
2526 u32 golden_bg_ratio = 0;
2527 u32 golden_rg_ratio = 0;
2528 u32 golden_g_value = 0;
2529 u32 i;
2530
2531 if (awb_cfg->enable) {
2532 golden_g_value = (awb_cfg->golden_gb_value +
2533 awb_cfg->golden_gr_value) / 2;
2534 golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value;
2535 golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value;
2536 }
2537
2538 /* apply OTP WB Calibration */
2539 if ((otp_ptr->flag & 0xC0) && golden_bg_ratio && golden_rg_ratio) {
2540 rg = otp_ptr->rg_ratio;
2541 bg = otp_ptr->bg_ratio;
2542 /* calculate G gain */
2543 R_gain = (golden_rg_ratio * 1000) / rg;
2544 B_gain = (golden_bg_ratio * 1000) / bg;
2545 G_gain = 1000;
2546 if (R_gain < 1000 || B_gain < 1000) {
2547 if (R_gain < B_gain)
2548 base_gain = R_gain;
2549 else
2550 base_gain = B_gain;
2551 } else {
2552 base_gain = G_gain;
2553 }
2554 R_gain = 0x400 * R_gain / (base_gain);
2555 B_gain = 0x400 * B_gain / (base_gain);
2556 G_gain = 0x400 * G_gain / (base_gain);
2557
2558 /* update sensor WB gain */
2559 if (R_gain > 0x400) {
2560 ov8858_write_1byte(client, 0x5032, R_gain >> 8);
2561 ov8858_write_1byte(client, 0x5033, R_gain & 0x00ff);
2562 }
2563 if (G_gain > 0x400) {
2564 ov8858_write_1byte(client, 0x5034, G_gain >> 8);
2565 ov8858_write_1byte(client, 0x5035, G_gain & 0x00ff);
2566 }
2567 if (B_gain > 0x400) {
2568 ov8858_write_1byte(client, 0x5036, B_gain >> 8);
2569 ov8858_write_1byte(client, 0x5037, B_gain & 0x00ff);
2570 }
2571
2572 dev_dbg(&client->dev, "apply awb gain: 0x%x, 0x%x, 0x%x\n",
2573 R_gain, G_gain, B_gain);
2574 }
2575
2576 /* apply OTP Lenc Calibration */
2577 if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) {
2578 ov8858_read_1byte(client, 0x5000, &temp);
2579 temp = 0x80 | temp;
2580 ov8858_write_1byte(client, 0x5000, temp);
2581 for (i = 0; i < ARRAY_SIZE(otp_ptr->lenc); i++) {
2582 ov8858_write_1byte(client, 0x5800 + i,
2583 otp_ptr->lenc[i]);
2584 dev_dbg(&client->dev, "apply lenc[%d]: 0x%x\n",
2585 i, otp_ptr->lenc[i]);
2586 }
2587 }
2588
2589 return 0;
2590 }
2591
ov8858_apply_otp(struct ov8858 * ov8858)2592 static int ov8858_apply_otp(struct ov8858 *ov8858)
2593 {
2594 int ret = 0;
2595
2596 if (ov8858->is_r2a && ov8858->otp_r2a)
2597 ret = ov8858_apply_otp_r2a(ov8858);
2598 else if (ov8858->otp_r1a)
2599 ret = ov8858_apply_otp_r1a(ov8858);
2600
2601 return ret;
2602 }
2603
__ov8858_start_stream(struct ov8858 * ov8858)2604 static int __ov8858_start_stream(struct ov8858 *ov8858)
2605 {
2606 int ret;
2607
2608 ret = ov8858_write_array(ov8858->client, ov8858->cur_mode->reg_list);
2609 if (ret)
2610 return ret;
2611
2612 /* In case these controls are set before streaming */
2613 mutex_unlock(&ov8858->mutex);
2614 ret = v4l2_ctrl_handler_setup(&ov8858->ctrl_handler);
2615 mutex_lock(&ov8858->mutex);
2616 if (ret)
2617 return ret;
2618
2619 ret = ov8858_apply_otp(ov8858);
2620 if (ret)
2621 return ret;
2622
2623 return ov8858_write_reg(ov8858->client,
2624 OV8858_REG_CTRL_MODE,
2625 OV8858_REG_VALUE_08BIT,
2626 OV8858_MODE_STREAMING);
2627 }
2628
__ov8858_stop_stream(struct ov8858 * ov8858)2629 static int __ov8858_stop_stream(struct ov8858 *ov8858)
2630 {
2631 return ov8858_write_reg(ov8858->client,
2632 OV8858_REG_CTRL_MODE,
2633 OV8858_REG_VALUE_08BIT,
2634 OV8858_MODE_SW_STANDBY);
2635 }
2636
ov8858_s_stream(struct v4l2_subdev * sd,int on)2637 static int ov8858_s_stream(struct v4l2_subdev *sd, int on)
2638 {
2639 struct ov8858 *ov8858 = to_ov8858(sd);
2640 struct i2c_client *client = ov8858->client;
2641 int ret = 0;
2642
2643 dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
2644 ov8858->cur_mode->width,
2645 ov8858->cur_mode->height,
2646 DIV_ROUND_CLOSEST(ov8858->cur_mode->max_fps.denominator,
2647 ov8858->cur_mode->max_fps.numerator));
2648
2649 mutex_lock(&ov8858->mutex);
2650 on = !!on;
2651 if (on == ov8858->streaming)
2652 goto unlock_and_return;
2653
2654 if (on) {
2655 ret = pm_runtime_get_sync(&client->dev);
2656 if (ret < 0) {
2657 pm_runtime_put_noidle(&client->dev);
2658 goto unlock_and_return;
2659 }
2660
2661 ret = __ov8858_start_stream(ov8858);
2662 if (ret) {
2663 v4l2_err(sd, "start stream failed while write regs\n");
2664 pm_runtime_put(&client->dev);
2665 goto unlock_and_return;
2666 }
2667 } else {
2668 __ov8858_stop_stream(ov8858);
2669 pm_runtime_put(&client->dev);
2670 }
2671
2672 ov8858->streaming = on;
2673
2674 unlock_and_return:
2675 mutex_unlock(&ov8858->mutex);
2676
2677 return ret;
2678 }
2679
ov8858_s_power(struct v4l2_subdev * sd,int on)2680 static int ov8858_s_power(struct v4l2_subdev *sd, int on)
2681 {
2682 struct ov8858 *ov8858 = to_ov8858(sd);
2683 struct i2c_client *client = ov8858->client;
2684 int ret = 0;
2685
2686 mutex_lock(&ov8858->mutex);
2687
2688 /* If the power state is not modified - no work to do. */
2689 if (ov8858->power_on == !!on)
2690 goto unlock_and_return;
2691
2692 if (on) {
2693 ret = pm_runtime_get_sync(&client->dev);
2694 if (ret < 0) {
2695 pm_runtime_put_noidle(&client->dev);
2696 goto unlock_and_return;
2697 }
2698
2699 ret = ov8858_write_array(ov8858->client, ov8858_global_regs);
2700 if (ret) {
2701 v4l2_err(sd, "could not set init registers\n");
2702 pm_runtime_put_noidle(&client->dev);
2703 goto unlock_and_return;
2704 }
2705
2706 ov8858->power_on = true;
2707 } else {
2708 pm_runtime_put(&client->dev);
2709 ov8858->power_on = false;
2710 }
2711
2712 unlock_and_return:
2713 mutex_unlock(&ov8858->mutex);
2714
2715 return ret;
2716 }
2717
2718 /* Calculate the delay in us by clock rate and clock cycles */
ov8858_cal_delay(u32 cycles)2719 static inline u32 ov8858_cal_delay(u32 cycles)
2720 {
2721 return DIV_ROUND_UP(cycles, OV8858_XVCLK_FREQ / 1000 / 1000);
2722 }
2723
__ov8858_power_on(struct ov8858 * ov8858)2724 static int __ov8858_power_on(struct ov8858 *ov8858)
2725 {
2726 int ret;
2727 u32 delay_us;
2728 struct device *dev = &ov8858->client->dev;
2729
2730 if (!IS_ERR(ov8858->power_gpio))
2731 gpiod_set_value_cansleep(ov8858->power_gpio, 1);
2732
2733 usleep_range(1000, 2000);
2734
2735 if (!IS_ERR_OR_NULL(ov8858->pins_default)) {
2736 ret = pinctrl_select_state(ov8858->pinctrl,
2737 ov8858->pins_default);
2738 if (ret < 0)
2739 dev_err(dev, "could not set pins\n");
2740 }
2741
2742 ret = clk_set_rate(ov8858->xvclk, OV8858_XVCLK_FREQ);
2743 if (ret < 0)
2744 dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
2745 if (clk_get_rate(ov8858->xvclk) != OV8858_XVCLK_FREQ)
2746 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
2747 ret = clk_prepare_enable(ov8858->xvclk);
2748 if (ret < 0) {
2749 dev_err(dev, "Failed to enable xvclk\n");
2750 return ret;
2751 }
2752
2753 if (!IS_ERR(ov8858->reset_gpio))
2754 gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
2755
2756 ret = regulator_bulk_enable(OV8858_NUM_SUPPLIES, ov8858->supplies);
2757 if (ret < 0) {
2758 dev_err(dev, "Failed to enable regulators\n");
2759 goto disable_clk;
2760 }
2761
2762 if (!IS_ERR(ov8858->reset_gpio))
2763 gpiod_set_value_cansleep(ov8858->reset_gpio, 1);
2764
2765 usleep_range(1000, 2000);
2766 if (!IS_ERR(ov8858->pwdn_gpio))
2767 gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1);
2768
2769 /* 8192 cycles prior to first SCCB transaction */
2770 delay_us = ov8858_cal_delay(8192);
2771 usleep_range(delay_us, delay_us * 2);
2772
2773 return 0;
2774
2775 disable_clk:
2776 clk_disable_unprepare(ov8858->xvclk);
2777
2778 return ret;
2779 }
2780
__ov8858_power_off(struct ov8858 * ov8858)2781 static void __ov8858_power_off(struct ov8858 *ov8858)
2782 {
2783 int ret;
2784 struct device *dev = &ov8858->client->dev;
2785
2786 if (!IS_ERR(ov8858->pwdn_gpio))
2787 gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0);
2788 clk_disable_unprepare(ov8858->xvclk);
2789 if (!IS_ERR(ov8858->reset_gpio))
2790 gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
2791 if (!IS_ERR_OR_NULL(ov8858->pins_sleep)) {
2792 ret = pinctrl_select_state(ov8858->pinctrl,
2793 ov8858->pins_sleep);
2794 if (ret < 0)
2795 dev_dbg(dev, "could not set pins\n");
2796 }
2797
2798 //if (!IS_ERR(ov8858->power_gpio))
2799 //gpiod_set_value_cansleep(ov8858->power_gpio, 0);
2800
2801 regulator_bulk_disable(OV8858_NUM_SUPPLIES, ov8858->supplies);
2802 }
2803
ov8858_runtime_resume(struct device * dev)2804 static int __maybe_unused ov8858_runtime_resume(struct device *dev)
2805 {
2806 struct i2c_client *client = to_i2c_client(dev);
2807 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2808 struct ov8858 *ov8858 = to_ov8858(sd);
2809
2810 return __ov8858_power_on(ov8858);
2811 }
2812
ov8858_runtime_suspend(struct device * dev)2813 static int __maybe_unused ov8858_runtime_suspend(struct device *dev)
2814 {
2815 struct i2c_client *client = to_i2c_client(dev);
2816 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2817 struct ov8858 *ov8858 = to_ov8858(sd);
2818
2819 __ov8858_power_off(ov8858);
2820
2821 return 0;
2822 }
2823
2824 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
ov8858_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2825 static int ov8858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2826 {
2827 struct ov8858 *ov8858 = to_ov8858(sd);
2828 struct v4l2_mbus_framefmt *try_fmt =
2829 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2830 const struct ov8858_mode *def_mode = &supported_modes[0];
2831
2832 mutex_lock(&ov8858->mutex);
2833 /* Initialize try_fmt */
2834 try_fmt->width = def_mode->width;
2835 try_fmt->height = def_mode->height;
2836 try_fmt->code = OV8858_MEDIA_BUS_FMT;
2837 try_fmt->field = V4L2_FIELD_NONE;
2838
2839 mutex_unlock(&ov8858->mutex);
2840 /* No crop or compose */
2841
2842 return 0;
2843 }
2844 #endif
2845
ov8858_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2846 static int ov8858_enum_frame_interval(struct v4l2_subdev *sd,
2847 struct v4l2_subdev_pad_config *cfg,
2848 struct v4l2_subdev_frame_interval_enum *fie)
2849 {
2850 struct ov8858 *ov8858 = to_ov8858(sd);
2851
2852 if (fie->index >= ov8858->cfg_num)
2853 return -EINVAL;
2854
2855 fie->code = OV8858_MEDIA_BUS_FMT;
2856 fie->width = supported_modes[fie->index].width;
2857 fie->height = supported_modes[fie->index].height;
2858 fie->interval = supported_modes[fie->index].max_fps;
2859 return 0;
2860 }
2861
ov8858_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)2862 static int ov8858_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
2863 struct v4l2_mbus_config *config)
2864 {
2865 struct ov8858 *sensor = to_ov8858 (sd);
2866 struct device *dev = &sensor->client->dev;
2867
2868 dev_info(dev, "%s(%d) enter!\n", __func__, __LINE__);
2869
2870 if (2 == sensor->lane_num) {
2871 config->type = V4L2_MBUS_CSI2_DPHY;
2872 config->flags = V4L2_MBUS_CSI2_2_LANE |
2873 V4L2_MBUS_CSI2_CHANNEL_0 |
2874 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
2875 } else if (4 == sensor->lane_num) {
2876 config->type = V4L2_MBUS_CSI2_DPHY;
2877 config->flags = V4L2_MBUS_CSI2_4_LANE |
2878 V4L2_MBUS_CSI2_CHANNEL_0 |
2879 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
2880 } else {
2881 dev_err(&sensor->client->dev,
2882 "unsupported lane_num(%d)\n", sensor->lane_num);
2883 }
2884 return 0;
2885 }
2886
2887 static const struct dev_pm_ops ov8858_pm_ops = {
2888 SET_RUNTIME_PM_OPS(ov8858_runtime_suspend,
2889 ov8858_runtime_resume, NULL)
2890 };
2891
2892 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2893 static const struct v4l2_subdev_internal_ops ov8858_internal_ops = {
2894 .open = ov8858_open,
2895 };
2896 #endif
2897
2898 static const struct v4l2_subdev_core_ops ov8858_core_ops = {
2899 .s_power = ov8858_s_power,
2900 .ioctl = ov8858_ioctl,
2901 #ifdef CONFIG_COMPAT
2902 .compat_ioctl32 = ov8858_compat_ioctl32,
2903 #endif
2904 };
2905
2906 static const struct v4l2_subdev_video_ops ov8858_video_ops = {
2907 .s_stream = ov8858_s_stream,
2908 .g_frame_interval = ov8858_g_frame_interval,
2909 };
2910
2911 static const struct v4l2_subdev_pad_ops ov8858_pad_ops = {
2912 .enum_mbus_code = ov8858_enum_mbus_code,
2913 .enum_frame_size = ov8858_enum_frame_sizes,
2914 .enum_frame_interval = ov8858_enum_frame_interval,
2915 .get_fmt = ov8858_get_fmt,
2916 .set_fmt = ov8858_set_fmt,
2917 .get_mbus_config = ov8858_g_mbus_config,
2918 };
2919
2920 static const struct v4l2_subdev_ops ov8858_subdev_ops = {
2921 .core = &ov8858_core_ops,
2922 .video = &ov8858_video_ops,
2923 .pad = &ov8858_pad_ops,
2924 };
2925
ov8858_set_ctrl(struct v4l2_ctrl * ctrl)2926 static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl)
2927 {
2928 struct ov8858 *ov8858 = container_of(ctrl->handler,
2929 struct ov8858, ctrl_handler);
2930 struct i2c_client *client = ov8858->client;
2931 s64 max;
2932 int ret = 0;
2933
2934 /* Propagate change of current control to all related controls */
2935 switch (ctrl->id) {
2936 case V4L2_CID_VBLANK:
2937 /* Update max exposure while meeting expected vblanking */
2938 max = ov8858->cur_mode->height + ctrl->val - 4;
2939 __v4l2_ctrl_modify_range(ov8858->exposure,
2940 ov8858->exposure->minimum, max,
2941 ov8858->exposure->step,
2942 ov8858->exposure->default_value);
2943 break;
2944 }
2945
2946 if (!pm_runtime_get_if_in_use(&client->dev))
2947 return 0;
2948
2949 switch (ctrl->id) {
2950 case V4L2_CID_EXPOSURE:
2951 /* 4 least significant bits of expsoure are fractional part */
2952 dev_dbg(&client->dev, "set exposure value 0x%x\n", ctrl->val);
2953 ret = ov8858_write_reg(ov8858->client,
2954 OV8858_REG_EXPOSURE,
2955 OV8858_REG_VALUE_24BIT,
2956 ctrl->val << 4);
2957 break;
2958 case V4L2_CID_ANALOGUE_GAIN:
2959 dev_dbg(&client->dev, "set analog gain value 0x%x\n", ctrl->val);
2960 ret = ov8858_write_reg(ov8858->client,
2961 OV8858_REG_GAIN_H,
2962 OV8858_REG_VALUE_08BIT,
2963 (ctrl->val >> OV8858_GAIN_H_SHIFT) &
2964 OV8858_GAIN_H_MASK);
2965 ret |= ov8858_write_reg(ov8858->client,
2966 OV8858_REG_GAIN_L,
2967 OV8858_REG_VALUE_08BIT,
2968 ctrl->val & OV8858_GAIN_L_MASK);
2969 break;
2970 case V4L2_CID_VBLANK:
2971 dev_dbg(&client->dev, "set vb value 0x%x\n", ctrl->val);
2972 ret = ov8858_write_reg(ov8858->client,
2973 OV8858_REG_VTS,
2974 OV8858_REG_VALUE_16BIT,
2975 ctrl->val + ov8858->cur_mode->height);
2976 break;
2977 case V4L2_CID_TEST_PATTERN:
2978 ret = ov8858_enable_test_pattern(ov8858, ctrl->val);
2979 break;
2980 default:
2981 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
2982 __func__, ctrl->id, ctrl->val);
2983 break;
2984 }
2985
2986 pm_runtime_put(&client->dev);
2987
2988 return ret;
2989 }
2990
2991 static const struct v4l2_ctrl_ops ov8858_ctrl_ops = {
2992 .s_ctrl = ov8858_set_ctrl,
2993 };
2994
ov8858_initialize_controls(struct ov8858 * ov8858)2995 static int ov8858_initialize_controls(struct ov8858 *ov8858)
2996 {
2997 const struct ov8858_mode *mode;
2998 struct v4l2_ctrl_handler *handler;
2999 struct v4l2_ctrl *ctrl;
3000 s64 exposure_max, vblank_def;
3001 u32 h_blank;
3002 int ret;
3003
3004 handler = &ov8858->ctrl_handler;
3005 mode = ov8858->cur_mode;
3006 ret = v4l2_ctrl_handler_init(handler, 8);
3007 if (ret)
3008 return ret;
3009 handler->lock = &ov8858->mutex;
3010
3011 ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
3012 0, 0, link_freq_menu_items);
3013 if (ctrl)
3014 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
3015
3016 v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
3017 0, ov8858->pixel_rate, 1, ov8858->pixel_rate);
3018
3019 h_blank = mode->hts_def - mode->width;
3020 ov8858->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
3021 h_blank, h_blank, 1, h_blank);
3022 if (ov8858->hblank)
3023 ov8858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
3024
3025 vblank_def = mode->vts_def - mode->height;
3026 ov8858->vblank = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
3027 V4L2_CID_VBLANK, vblank_def,
3028 OV8858_VTS_MAX - mode->height,
3029 1, vblank_def);
3030
3031 exposure_max = mode->vts_def - 4;
3032 ov8858->exposure = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
3033 V4L2_CID_EXPOSURE, OV8858_EXPOSURE_MIN,
3034 exposure_max, OV8858_EXPOSURE_STEP,
3035 mode->exp_def);
3036
3037 ov8858->anal_gain = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
3038 V4L2_CID_ANALOGUE_GAIN, OV8858_GAIN_MIN,
3039 OV8858_GAIN_MAX, OV8858_GAIN_STEP,
3040 OV8858_GAIN_DEFAULT);
3041
3042 ov8858->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
3043 &ov8858_ctrl_ops, V4L2_CID_TEST_PATTERN,
3044 ARRAY_SIZE(ov8858_test_pattern_menu) - 1,
3045 0, 0, ov8858_test_pattern_menu);
3046
3047 if (handler->error) {
3048 ret = handler->error;
3049 dev_err(&ov8858->client->dev,
3050 "Failed to init controls(%d)\n", ret);
3051 goto err_free_handler;
3052 }
3053
3054 ov8858->subdev.ctrl_handler = handler;
3055
3056 return 0;
3057
3058 err_free_handler:
3059 v4l2_ctrl_handler_free(handler);
3060
3061 return ret;
3062 }
3063
ov8858_otp_read_r1a(struct ov8858 * ov8858)3064 static int ov8858_otp_read_r1a(struct ov8858 *ov8858)
3065 {
3066 int otp_flag, addr, temp, i;
3067 struct ov8858_otp_info_r1a *otp_ptr;
3068 struct device *dev = &ov8858->client->dev;
3069 struct i2c_client *client = ov8858->client;
3070
3071 otp_ptr = kzalloc(sizeof(*otp_ptr), GFP_KERNEL);
3072 if (!otp_ptr)
3073 return -ENOMEM;
3074
3075 otp_flag = 0;
3076 ov8858_read_1byte(client, 0x7010, &otp_flag);
3077 if ((otp_flag & 0xc0) == 0x40)
3078 addr = 0x7011; /* base address of info group 1 */
3079 else if ((otp_flag & 0x30) == 0x10)
3080 addr = 0x7016; /* base address of info group 2 */
3081 else if ((otp_flag & 0x0c) == 0x04)
3082 addr = 0x701b; /* base address of info group 3 */
3083 else
3084 addr = 0;
3085
3086 if (addr != 0) {
3087 otp_ptr->flag = 0x80; /* valid info in OTP */
3088 ov8858_read_1byte(client, addr, &otp_ptr->module_id);
3089 ov8858_read_1byte(client, addr + 1, &otp_ptr->lens_id);
3090 ov8858_read_1byte(client, addr + 2, &otp_ptr->year);
3091 ov8858_read_1byte(client, addr + 3, &otp_ptr->month);
3092 ov8858_read_1byte(client, addr + 4, &otp_ptr->day);
3093 dev_dbg(dev, "fac info: module(0x%x) lens(0x%x) time(%d_%d_%d)!\n",
3094 otp_ptr->module_id,
3095 otp_ptr->lens_id,
3096 otp_ptr->year,
3097 otp_ptr->month,
3098 otp_ptr->day);
3099 }
3100
3101 /* OTP base information and WB calibration data */
3102 ov8858_read_1byte(client, 0x7020, &otp_flag);
3103 if ((otp_flag & 0xc0) == 0x40)
3104 addr = 0x7021; /* base address of info group 1 */
3105 else if ((otp_flag & 0x30) == 0x10)
3106 addr = 0x7026; /* base address of info group 2 */
3107 else if ((otp_flag & 0x0c) == 0x04)
3108 addr = 0x702b; /* base address of info group 3 */
3109 else
3110 addr = 0;
3111
3112 if (addr != 0) {
3113 otp_ptr->flag |= 0x40; /* valid info and AWB in OTP */
3114 ov8858_read_1byte(client, addr + 4, &temp);
3115 ov8858_read_1byte(client, addr, &otp_ptr->rg_ratio);
3116 otp_ptr->rg_ratio = (otp_ptr->rg_ratio << 2) +
3117 ((temp >> 6) & 0x03);
3118 ov8858_read_1byte(client, addr + 1, &otp_ptr->bg_ratio);
3119 otp_ptr->bg_ratio = (otp_ptr->bg_ratio << 2) +
3120 ((temp >> 4) & 0x03);
3121 ov8858_read_1byte(client, addr + 2, &otp_ptr->light_rg);
3122 otp_ptr->light_rg = (otp_ptr->light_rg << 2) +
3123 ((temp >> 2) & 0x03);
3124 ov8858_read_1byte(client, addr + 3, &otp_ptr->light_bg);
3125 otp_ptr->light_bg = (otp_ptr->light_bg << 2) +
3126 ((temp) & 0x03);
3127 dev_dbg(dev, "awb info: (0x%x, 0x%x, 0x%x, 0x%x)!\n",
3128 otp_ptr->rg_ratio, otp_ptr->bg_ratio,
3129 otp_ptr->light_rg, otp_ptr->light_bg);
3130 }
3131
3132 /* OTP VCM Calibration */
3133 ov8858_read_1byte(client, 0x7030, &otp_flag);
3134 if ((otp_flag & 0xc0) == 0x40)
3135 addr = 0x7031; /* base address of VCM Calibration group 1 */
3136 else if ((otp_flag & 0x30) == 0x10)
3137 addr = 0x7034; /* base address of VCM Calibration group 2 */
3138 else if ((otp_flag & 0x0c) == 0x04)
3139 addr = 0x7037; /* base address of VCM Calibration group 3 */
3140 else
3141 addr = 0;
3142 if (addr != 0) {
3143 otp_ptr->flag |= 0x20;
3144 ov8858_read_1byte(client, addr + 2, &temp);
3145 ov8858_read_1byte(client, addr, &otp_ptr->vcm_start);
3146 otp_ptr->vcm_start = (otp_ptr->vcm_start << 2) |
3147 ((temp >> 6) & 0x03);
3148 ov8858_read_1byte(client, addr + 1, &otp_ptr->vcm_end);
3149 otp_ptr->vcm_end = (otp_ptr->vcm_end << 2) |
3150 ((temp >> 4) & 0x03);
3151 otp_ptr->vcm_dir = (temp >> 2) & 0x03;
3152 dev_dbg(dev, "vcm_info: 0x%x, 0x%x, 0x%x!\n",
3153 otp_ptr->vcm_start,
3154 otp_ptr->vcm_end,
3155 otp_ptr->vcm_dir);
3156 }
3157
3158 /* OTP Lenc Calibration */
3159 ov8858_read_1byte(client, 0x703a, &otp_flag);
3160 if ((otp_flag & 0xc0) == 0x40)
3161 addr = 0x703b; /* base address of Lenc Calibration group 1 */
3162 else if ((otp_flag & 0x30) == 0x10)
3163 addr = 0x70a9; /* base address of Lenc Calibration group 2 */
3164 else if ((otp_flag & 0x0c) == 0x04)
3165 addr = 0x7117; /* base address of Lenc Calibration group 3 */
3166 else
3167 addr = 0;
3168 if (addr != 0) {
3169 otp_ptr->flag |= 0x10;
3170 for (i = 0; i < 110; i++) {
3171 ov8858_read_1byte(client, addr + i, &otp_ptr->lenc[i]);
3172 dev_dbg(dev, "lsc 0x%x!\n", otp_ptr->lenc[i]);
3173 }
3174 }
3175
3176 for (i = 0x7010; i <= 0x7184; i++)
3177 ov8858_write_1byte(client, i, 0); /* clear OTP buffer */
3178
3179 if (otp_ptr->flag) {
3180 ov8858->otp_r1a = otp_ptr;
3181 } else {
3182 ov8858->otp_r1a = NULL;
3183 dev_info(dev, "otp_r1a is null!\n");
3184 kfree(otp_ptr);
3185 }
3186
3187 return 0;
3188 }
3189
ov8858_otp_read_r2a(struct ov8858 * ov8858)3190 static int ov8858_otp_read_r2a(struct ov8858 *ov8858)
3191 {
3192 struct ov8858_otp_info_r2a *otp_ptr;
3193 int otp_flag, addr, temp, checksum, i;
3194 struct device *dev = &ov8858->client->dev;
3195 struct i2c_client *client = ov8858->client;
3196
3197 otp_ptr = kzalloc(sizeof(*otp_ptr), GFP_KERNEL);
3198 if (!otp_ptr)
3199 return -ENOMEM;
3200
3201 /* OTP base information and WB calibration data */
3202 otp_flag = 0;
3203 ov8858_read_1byte(client, 0x7010, &otp_flag);
3204 if ((otp_flag & 0xc0) == 0x40)
3205 addr = 0x7011; /* base address of info group 1 */
3206 else if ((otp_flag & 0x30) == 0x10)
3207 addr = 0x7019; /* base address of info group 2 */
3208 else
3209 addr = 0;
3210
3211 if (addr != 0) {
3212 otp_ptr->flag = 0xC0; /* valid info and AWB in OTP */
3213 ov8858_read_1byte(client, addr, &otp_ptr->module_id);
3214 ov8858_read_1byte(client, addr + 1, &otp_ptr->lens_id);
3215 ov8858_read_1byte(client, addr + 2, &otp_ptr->year);
3216 ov8858_read_1byte(client, addr + 3, &otp_ptr->month);
3217 ov8858_read_1byte(client, addr + 4, &otp_ptr->day);
3218 ov8858_read_1byte(client, addr + 7, &temp);
3219 ov8858_read_1byte(client, addr + 5, &otp_ptr->rg_ratio);
3220 otp_ptr->rg_ratio = (otp_ptr->rg_ratio << 2) +
3221 ((temp >> 6) & 0x03);
3222 ov8858_read_1byte(client, addr + 6, &otp_ptr->bg_ratio);
3223 otp_ptr->bg_ratio = (otp_ptr->bg_ratio << 2) +
3224 ((temp >> 4) & 0x03);
3225
3226 dev_dbg(dev, "fac info: module(0x%x) lens(0x%x) time(%d_%d_%d) !\n",
3227 otp_ptr->module_id,
3228 otp_ptr->lens_id,
3229 otp_ptr->year,
3230 otp_ptr->month,
3231 otp_ptr->day);
3232 dev_dbg(dev, "awb info: (0x%x, 0x%x)!\n",
3233 otp_ptr->rg_ratio,
3234 otp_ptr->bg_ratio);
3235 }
3236
3237 /* OTP VCM Calibration */
3238 ov8858_read_1byte(client, 0x7021, &otp_flag);
3239 if ((otp_flag & 0xc0) == 0x40)
3240 addr = 0x7022; /* base address of VCM Calibration group 1 */
3241 else if ((otp_flag & 0x30) == 0x10)
3242 addr = 0x7025; /* base address of VCM Calibration group 2 */
3243 else
3244 addr = 0;
3245
3246 if (addr != 0) {
3247 otp_ptr->flag |= 0x20;
3248 ov8858_read_1byte(client, addr + 2, &temp);
3249 ov8858_read_1byte(client, addr, &otp_ptr->vcm_start);
3250 otp_ptr->vcm_start = (otp_ptr->vcm_start << 2) |
3251 ((temp >> 6) & 0x03);
3252 ov8858_read_1byte(client, addr + 1, &otp_ptr->vcm_end);
3253 otp_ptr->vcm_end = (otp_ptr->vcm_end << 2) |
3254 ((temp >> 4) & 0x03);
3255 otp_ptr->vcm_dir = (temp >> 2) & 0x03;
3256 }
3257
3258 /* OTP Lenc Calibration */
3259 ov8858_read_1byte(client, 0x7028, &otp_flag);
3260 if ((otp_flag & 0xc0) == 0x40)
3261 addr = 0x7029; /* base address of Lenc Calibration group 1 */
3262 else if ((otp_flag & 0x30) == 0x10)
3263 addr = 0x711a; /* base address of Lenc Calibration group 2 */
3264 else
3265 addr = 0;
3266
3267 if (addr != 0) {
3268 checksum = 0;
3269 for (i = 0; i < 240; i++) {
3270 ov8858_read_1byte(client, addr + i, &otp_ptr->lenc[i]);
3271 checksum += otp_ptr->lenc[i];
3272 dev_dbg(dev, "lsc_info: 0x%x!\n", otp_ptr->lenc[i]);
3273 }
3274 checksum = (checksum) % 255 + 1;
3275 ov8858_read_1byte(client, addr + 240, &otp_ptr->checksum);
3276 if (otp_ptr->checksum == checksum)
3277 otp_ptr->flag |= 0x10;
3278 }
3279
3280 for (i = 0x7010; i <= 0x720a; i++)
3281 ov8858_write_1byte(client, i, 0); /* clear OTP buffer */
3282
3283 if (otp_ptr->flag) {
3284 ov8858->otp_r2a = otp_ptr;
3285 } else {
3286 ov8858->otp_r2a = NULL;
3287 dev_info(dev, "otp_r2a is null!\n");
3288 kfree(otp_ptr);
3289 }
3290
3291 return 0;
3292 }
3293
ov8858_otp_read(struct ov8858 * ov8858)3294 static int ov8858_otp_read(struct ov8858 *ov8858)
3295 {
3296 int temp = 0;
3297 int ret = 0;
3298 struct i2c_client *client = ov8858->client;
3299
3300 /* stream on */
3301 ov8858_write_1byte(client,
3302 OV8858_REG_CTRL_MODE,
3303 OV8858_MODE_STREAMING);
3304
3305 ov8858_read_1byte(client, 0x5002, &temp);
3306 ov8858_write_1byte(client, 0x5002, (temp & (~0x08)));
3307
3308 /* read OTP into buffer */
3309 ov8858_write_1byte(client, 0x3d84, 0xC0);
3310 ov8858_write_1byte(client, 0x3d88, 0x70); /* OTP start address */
3311 ov8858_write_1byte(client, 0x3d89, 0x10);
3312 if (ov8858->is_r2a) {
3313 ov8858_write_1byte(client, 0x3d8A, 0x72); /* OTP end address */
3314 ov8858_write_1byte(client, 0x3d8B, 0x0a);
3315 } else {
3316 ov8858_write_1byte(client, 0x3d8A, 0x71); /* OTP end address */
3317 ov8858_write_1byte(client, 0x3d8B, 0x84);
3318 }
3319 ov8858_write_1byte(client, 0x3d81, 0x01); /* load otp into buffer */
3320 usleep_range(10000, 20000);
3321
3322 if (ov8858->is_r2a)
3323 ret = ov8858_otp_read_r2a(ov8858);
3324 else
3325 ret = ov8858_otp_read_r1a(ov8858);
3326
3327 /* set 0x5002[3] to "1" */
3328 ov8858_read_1byte(client, 0x5002, &temp);
3329 ov8858_write_1byte(client, 0x5002, 0x08 | (temp & (~0x08)));
3330
3331 /* stream off */
3332 ov8858_write_1byte(client,
3333 OV8858_REG_CTRL_MODE,
3334 OV8858_MODE_SW_STANDBY);
3335
3336 return ret;
3337 }
3338
ov8858_check_sensor_id(struct ov8858 * ov8858,struct i2c_client * client)3339 static int ov8858_check_sensor_id(struct ov8858 *ov8858,
3340 struct i2c_client *client)
3341 {
3342 struct device *dev = &ov8858->client->dev;
3343 u32 id = 0;
3344 int ret;
3345
3346 ret = ov8858_read_reg(client, OV8858_REG_CHIP_ID,
3347 OV8858_REG_VALUE_24BIT, &id);
3348 if (id != CHIP_ID) {
3349 dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
3350 return -ENODEV;
3351 }
3352
3353 ret = ov8858_read_reg(client, OV8858_CHIP_REVISION_REG,
3354 OV8858_REG_VALUE_08BIT, &id);
3355 if (ret) {
3356 dev_err(dev, "Read chip revision register error\n");
3357 return -ENODEV;
3358 }
3359 dev_info(dev, "Detected OV%06x sensor, REVISION 0x%x\n", CHIP_ID, id);
3360
3361 if (id == OV8858_R2A) {
3362 if (4 == ov8858->lane_num) {
3363 ov8858_global_regs = ov8858_global_regs_r2a_4lane;
3364 ov8858->cur_mode = &supported_modes_r2a_4lane[0];
3365 supported_modes = supported_modes_r2a_4lane;
3366 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_4lane);
3367 } else {
3368 ov8858_global_regs = ov8858_global_regs_r2a_2lane;
3369 ov8858->cur_mode = &supported_modes_r2a_2lane[0];
3370 supported_modes = supported_modes_r2a_2lane;
3371 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_2lane);
3372 }
3373
3374 ov8858->is_r2a = true;
3375 } else {
3376 if (4 == ov8858->lane_num) {
3377 ov8858_global_regs = ov8858_global_regs_r1a_4lane;
3378 ov8858->cur_mode = &supported_modes_r1a_4lane[0];
3379 supported_modes = supported_modes_r1a_4lane;
3380 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r1a_4lane);
3381 } else {
3382 ov8858_global_regs = ov8858_global_regs_r1a_2lane;
3383 ov8858->cur_mode = &supported_modes_r1a_2lane[0];
3384 supported_modes = supported_modes_r1a_2lane;
3385 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r1a_2lane);
3386
3387 }
3388 ov8858->is_r2a = false;
3389 dev_info(dev, "R1A work ok now!\n");
3390 }
3391
3392 return 0;
3393 }
3394
ov8858_configure_regulators(struct ov8858 * ov8858)3395 static int ov8858_configure_regulators(struct ov8858 *ov8858)
3396 {
3397 unsigned int i;
3398
3399 for (i = 0; i < OV8858_NUM_SUPPLIES; i++)
3400 ov8858->supplies[i].supply = ov8858_supply_names[i];
3401
3402 return devm_regulator_bulk_get(&ov8858->client->dev,
3403 OV8858_NUM_SUPPLIES,
3404 ov8858->supplies);
3405 }
3406
ov8858_parse_of(struct ov8858 * ov8858)3407 static int ov8858_parse_of(struct ov8858 *ov8858)
3408 {
3409 struct device *dev = &ov8858->client->dev;
3410 struct device_node *endpoint;
3411 struct fwnode_handle *fwnode;
3412 int rval;
3413
3414 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
3415 if (!endpoint) {
3416 dev_err(dev, "Failed to get endpoint\n");
3417 return -EINVAL;
3418 }
3419 fwnode = of_fwnode_handle(endpoint);
3420 rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
3421 if (rval <= 0) {
3422 dev_warn(dev, " Get mipi lane num failed!\n");
3423 return -1;
3424 }
3425
3426 ov8858->lane_num = rval;
3427 if (4 == ov8858->lane_num) {
3428 ov8858->cur_mode = &supported_modes_r2a_4lane[0];
3429 supported_modes = supported_modes_r2a_4lane;
3430 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_4lane);
3431
3432 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
3433 ov8858->pixel_rate = MIPI_FREQ * 2U * ov8858->lane_num / 10U;
3434 dev_info(dev, "lane_num(%d) pixel_rate(%u)\n",
3435 ov8858->lane_num, ov8858->pixel_rate);
3436 } else {
3437 ov8858->cur_mode = &supported_modes_r2a_2lane[0];
3438 supported_modes = supported_modes_r2a_2lane;
3439 ov8858->cfg_num = ARRAY_SIZE(supported_modes_r2a_2lane);
3440
3441 /*pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
3442 ov8858->pixel_rate = MIPI_FREQ * 2U * (ov8858->lane_num) / 10U;
3443 dev_info(dev, "lane_num(%d) pixel_rate(%u)\n",
3444 ov8858->lane_num, ov8858->pixel_rate);
3445 }
3446 return 0;
3447 }
3448
ov8858_probe(struct i2c_client * client,const struct i2c_device_id * id)3449 static int ov8858_probe(struct i2c_client *client,
3450 const struct i2c_device_id *id)
3451 {
3452 struct device *dev = &client->dev;
3453 struct device_node *node = dev->of_node;
3454 struct ov8858 *ov8858;
3455 struct v4l2_subdev *sd;
3456 char facing[2];
3457 int ret;
3458
3459 dev_info(dev, "driver version: %02x.%02x.%02x",
3460 DRIVER_VERSION >> 16,
3461 (DRIVER_VERSION & 0xff00) >> 8,
3462 DRIVER_VERSION & 0x00ff);
3463
3464 ov8858 = devm_kzalloc(dev, sizeof(*ov8858), GFP_KERNEL);
3465 if (!ov8858)
3466 return -ENOMEM;
3467
3468 ov8858->client = client;
3469 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
3470 &ov8858->module_index);
3471 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
3472 &ov8858->module_facing);
3473 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
3474 &ov8858->module_name);
3475 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
3476 &ov8858->len_name);
3477 if (ret) {
3478 dev_err(dev,
3479 "could not get module information!\n");
3480 return -EINVAL;
3481 }
3482
3483 ov8858->xvclk = devm_clk_get(dev, "xvclk");
3484 if (IS_ERR(ov8858->xvclk)) {
3485 dev_err(dev, "Failed to get xvclk\n");
3486 return -EINVAL;
3487 }
3488
3489 ov8858->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
3490 if (IS_ERR(ov8858->power_gpio))
3491 dev_warn(dev, "Failed to get power-gpios, maybe no use\n");
3492
3493 ov8858->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
3494 if (IS_ERR(ov8858->reset_gpio))
3495 dev_warn(dev, "Failed to get reset-gpios, maybe no use\n");
3496
3497 ov8858->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
3498 if (IS_ERR(ov8858->pwdn_gpio))
3499 dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n");
3500
3501 ret = ov8858_configure_regulators(ov8858);
3502 if (ret) {
3503 dev_err(dev, "Failed to get power regulators\n");
3504 return ret;
3505 }
3506
3507 ret = ov8858_parse_of(ov8858);
3508 if (ret != 0)
3509 return -EINVAL;
3510
3511 ov8858->pinctrl = devm_pinctrl_get(dev);
3512 if (!IS_ERR(ov8858->pinctrl)) {
3513 ov8858->pins_default =
3514 pinctrl_lookup_state(ov8858->pinctrl,
3515 OF_CAMERA_PINCTRL_STATE_DEFAULT);
3516 if (IS_ERR(ov8858->pins_default))
3517 dev_err(dev, "could not get default pinstate\n");
3518
3519 ov8858->pins_sleep =
3520 pinctrl_lookup_state(ov8858->pinctrl,
3521 OF_CAMERA_PINCTRL_STATE_SLEEP);
3522 if (IS_ERR(ov8858->pins_sleep))
3523 dev_err(dev, "could not get sleep pinstate\n");
3524 }
3525
3526 mutex_init(&ov8858->mutex);
3527
3528 sd = &ov8858->subdev;
3529 v4l2_i2c_subdev_init(sd, client, &ov8858_subdev_ops);
3530 ret = ov8858_initialize_controls(ov8858);
3531 if (ret)
3532 goto err_destroy_mutex;
3533
3534 ret = __ov8858_power_on(ov8858);
3535 if (ret)
3536 goto err_free_handler;
3537
3538 ret = ov8858_check_sensor_id(ov8858, client);
3539 if (ret)
3540 goto err_power_off;
3541
3542 ov8858_otp_read(ov8858);
3543
3544 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
3545 sd->internal_ops = &ov8858_internal_ops;
3546 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
3547 V4L2_SUBDEV_FL_HAS_EVENTS;
3548 #endif
3549 #if defined(CONFIG_MEDIA_CONTROLLER)
3550 ov8858->pad.flags = MEDIA_PAD_FL_SOURCE;
3551 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
3552 ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad);
3553 if (ret < 0)
3554 goto err_power_off;
3555 #endif
3556
3557 memset(facing, 0, sizeof(facing));
3558 if (strcmp(ov8858->module_facing, "back") == 0)
3559 facing[0] = 'b';
3560 else
3561 facing[0] = 'f';
3562
3563 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
3564 ov8858->module_index, facing,
3565 OV8858_NAME, dev_name(sd->dev));
3566 ret = v4l2_async_register_subdev_sensor_common(sd);
3567 if (ret) {
3568 dev_err(dev, "v4l2 async register subdev failed\n");
3569 goto err_clean_entity;
3570 }
3571
3572 pm_runtime_set_active(dev);
3573 pm_runtime_enable(dev);
3574 pm_runtime_idle(dev);
3575
3576 return 0;
3577
3578 err_clean_entity:
3579 #if defined(CONFIG_MEDIA_CONTROLLER)
3580 media_entity_cleanup(&sd->entity);
3581 #endif
3582 err_power_off:
3583 __ov8858_power_off(ov8858);
3584 err_free_handler:
3585 v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
3586 err_destroy_mutex:
3587 mutex_destroy(&ov8858->mutex);
3588
3589 return ret;
3590 }
3591
ov8858_remove(struct i2c_client * client)3592 static int ov8858_remove(struct i2c_client *client)
3593 {
3594 struct v4l2_subdev *sd = i2c_get_clientdata(client);
3595 struct ov8858 *ov8858 = to_ov8858(sd);
3596
3597 v4l2_async_unregister_subdev(sd);
3598 #if defined(CONFIG_MEDIA_CONTROLLER)
3599 media_entity_cleanup(&sd->entity);
3600 #endif
3601 v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
3602 if (ov8858->otp_r2a)
3603 kfree(ov8858->otp_r2a);
3604 if (ov8858->otp_r1a)
3605 kfree(ov8858->otp_r1a);
3606 mutex_destroy(&ov8858->mutex);
3607
3608 pm_runtime_disable(&client->dev);
3609 if (!pm_runtime_status_suspended(&client->dev))
3610 __ov8858_power_off(ov8858);
3611 pm_runtime_set_suspended(&client->dev);
3612
3613 return 0;
3614 }
3615
3616 #if IS_ENABLED(CONFIG_OF)
3617 static const struct of_device_id ov8858_of_match[] = {
3618 { .compatible = "ovti,ov8858" },
3619 {},
3620 };
3621 MODULE_DEVICE_TABLE(of, ov8858_of_match);
3622 #endif
3623
3624 static const struct i2c_device_id ov8858_match_id[] = {
3625 { "ovti,ov8858", 0 },
3626 { },
3627 };
3628
3629 static struct i2c_driver ov8858_i2c_driver = {
3630 .driver = {
3631 .name = OV8858_NAME,
3632 .pm = &ov8858_pm_ops,
3633 .of_match_table = of_match_ptr(ov8858_of_match),
3634 },
3635 .probe = &ov8858_probe,
3636 .remove = &ov8858_remove,
3637 .id_table = ov8858_match_id,
3638 };
3639
sensor_mod_init(void)3640 static int __init sensor_mod_init(void)
3641 {
3642 return i2c_add_driver(&ov8858_i2c_driver);
3643 }
3644
sensor_mod_exit(void)3645 static void __exit sensor_mod_exit(void)
3646 {
3647 i2c_del_driver(&ov8858_i2c_driver);
3648 }
3649
3650 device_initcall_sync(sensor_mod_init);
3651 module_exit(sensor_mod_exit);
3652
3653 MODULE_DESCRIPTION("OmniVision ov8858 sensor driver");
3654 MODULE_LICENSE("GPL v2");
3655