xref: /linux/drivers/media/i2c/ov8858.c (revision 69bfec7548f4c1595bac0e3ddfc0458a5af31f4c)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2023 Jacopo Mondi <jacopo.mondi@ideasonboard.com>
4  * Copyright (C) 2022 Nicholas Roth <nicholas@rothemail.net>
5  * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
6  */
7 
8 #include <asm/unaligned.h>
9 
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/device.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/i2c.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/property.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/slab.h>
21 
22 #include <media/media-entity.h>
23 #include <media/v4l2-async.h>
24 #include <media/v4l2-common.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-event.h>
28 #include <media/v4l2-fwnode.h>
29 #include <media/v4l2-mediabus.h>
30 #include <media/v4l2-subdev.h>
31 
32 #define OV8858_LINK_FREQ		360000000U
33 #define OV8858_XVCLK_FREQ		24000000
34 
35 #define OV8858_REG_SIZE_SHIFT		16
36 #define OV8858_REG_ADDR_MASK		0xffff
37 #define OV8858_REG_8BIT(n)		((1U << OV8858_REG_SIZE_SHIFT) | (n))
38 #define OV8858_REG_16BIT(n)		((2U << OV8858_REG_SIZE_SHIFT) | (n))
39 #define OV8858_REG_24BIT(n)		((3U << OV8858_REG_SIZE_SHIFT) | (n))
40 
41 #define OV8858_REG_SC_CTRL0100		OV8858_REG_8BIT(0x0100)
42 #define OV8858_MODE_SW_STANDBY		0x0
43 #define OV8858_MODE_STREAMING		0x1
44 
45 #define OV8858_REG_CHIP_ID		OV8858_REG_24BIT(0x300a)
46 #define OV8858_CHIP_ID			0x008858
47 
48 #define OV8858_REG_SUB_ID		OV8858_REG_8BIT(0x302a)
49 #define OV8858_R1A			0xb0
50 #define OV8858_R2A			0xb2
51 
52 #define OV8858_REG_LONG_EXPO		OV8858_REG_24BIT(0x3500)
53 #define OV8858_EXPOSURE_MIN		4
54 #define OV8858_EXPOSURE_STEP		1
55 #define OV8858_EXPOSURE_MARGIN		4
56 
57 #define OV8858_REG_LONG_GAIN		OV8858_REG_16BIT(0x3508)
58 #define OV8858_LONG_GAIN_MIN		0x0
59 #define OV8858_LONG_GAIN_MAX		0x7ff
60 #define OV8858_LONG_GAIN_STEP		1
61 #define OV8858_LONG_GAIN_DEFAULT	0x80
62 
63 #define OV8858_REG_LONG_DIGIGAIN	OV8858_REG_16BIT(0x350a)
64 #define OV8858_LONG_DIGIGAIN_H_MASK	0x3fc0
65 #define OV8858_LONG_DIGIGAIN_L_MASK	0x3f
66 #define OV8858_LONG_DIGIGAIN_H_SHIFT	2
67 #define OV8858_LONG_DIGIGAIN_MIN	0x0
68 #define OV8858_LONG_DIGIGAIN_MAX	0x3fff
69 #define OV8858_LONG_DIGIGAIN_STEP	1
70 #define OV8858_LONG_DIGIGAIN_DEFAULT	0x200
71 
72 #define OV8858_REG_VTS			OV8858_REG_16BIT(0x380e)
73 #define OV8858_VTS_MAX			0x7fff
74 
75 #define OV8858_REG_TEST_PATTERN		OV8858_REG_8BIT(0x5e00)
76 #define OV8858_TEST_PATTERN_ENABLE	0x80
77 #define OV8858_TEST_PATTERN_DISABLE	0x0
78 
79 #define REG_NULL			0xffff
80 
81 static const char * const ov8858_supply_names[] = {
82 	"avdd",		/* Analog power */
83 	"dovdd",	/* Digital I/O power */
84 	"dvdd",		/* Digital core power */
85 };
86 
87 struct regval {
88 	u16 addr;
89 	u8 val;
90 };
91 
92 struct regval_modes {
93 	const struct regval *mode_2lanes;
94 	const struct regval *mode_4lanes;
95 };
96 
97 struct ov8858_mode {
98 	u32 width;
99 	u32 height;
100 	u32 hts_def;
101 	u32 vts_def;
102 	u32 exp_def;
103 	const struct regval_modes reg_modes;
104 };
105 
106 struct ov8858 {
107 	struct clk		*xvclk;
108 	struct gpio_desc	*reset_gpio;
109 	struct gpio_desc	*pwdn_gpio;
110 	struct regulator_bulk_data supplies[ARRAY_SIZE(ov8858_supply_names)];
111 
112 	struct v4l2_subdev	subdev;
113 	struct media_pad	pad;
114 
115 	struct v4l2_ctrl_handler ctrl_handler;
116 	struct v4l2_ctrl	*exposure;
117 	struct v4l2_ctrl	*hblank;
118 	struct v4l2_ctrl	*vblank;
119 
120 	const struct regval	*global_regs;
121 
122 	unsigned int		num_lanes;
123 };
124 
125 static inline struct ov8858 *sd_to_ov8858(struct v4l2_subdev *sd)
126 {
127 	return container_of(sd, struct ov8858, subdev);
128 }
129 
130 static const struct regval ov8858_global_regs_r1a[] = {
131 	{0x0100, 0x00},
132 	{0x0100, 0x00},
133 	{0x0100, 0x00},
134 	{0x0100, 0x00},
135 	{0x0302, 0x1e},
136 	{0x0303, 0x00},
137 	{0x0304, 0x03},
138 	{0x030e, 0x00},
139 	{0x030f, 0x09},
140 	{0x0312, 0x01},
141 	{0x031e, 0x0c},
142 	{0x3600, 0x00},
143 	{0x3601, 0x00},
144 	{0x3602, 0x00},
145 	{0x3603, 0x00},
146 	{0x3604, 0x22},
147 	{0x3605, 0x30},
148 	{0x3606, 0x00},
149 	{0x3607, 0x20},
150 	{0x3608, 0x11},
151 	{0x3609, 0x28},
152 	{0x360a, 0x00},
153 	{0x360b, 0x06},
154 	{0x360c, 0xdc},
155 	{0x360d, 0x40},
156 	{0x360e, 0x0c},
157 	{0x360f, 0x20},
158 	{0x3610, 0x07},
159 	{0x3611, 0x20},
160 	{0x3612, 0x88},
161 	{0x3613, 0x80},
162 	{0x3614, 0x58},
163 	{0x3615, 0x00},
164 	{0x3616, 0x4a},
165 	{0x3617, 0xb0},
166 	{0x3618, 0x56},
167 	{0x3619, 0x70},
168 	{0x361a, 0x99},
169 	{0x361b, 0x00},
170 	{0x361c, 0x07},
171 	{0x361d, 0x00},
172 	{0x361e, 0x00},
173 	{0x361f, 0x00},
174 	{0x3638, 0xff},
175 	{0x3633, 0x0c},
176 	{0x3634, 0x0c},
177 	{0x3635, 0x0c},
178 	{0x3636, 0x0c},
179 	{0x3645, 0x13},
180 	{0x3646, 0x83},
181 	{0x364a, 0x07},
182 	{0x3015, 0x01},
183 	{0x3018, 0x32},
184 	{0x3020, 0x93},
185 	{0x3022, 0x01},
186 	{0x3031, 0x0a},
187 	{0x3034, 0x00},
188 	{0x3106, 0x01},
189 	{0x3305, 0xf1},
190 	{0x3308, 0x00},
191 	{0x3309, 0x28},
192 	{0x330a, 0x00},
193 	{0x330b, 0x20},
194 	{0x330c, 0x00},
195 	{0x330d, 0x00},
196 	{0x330e, 0x00},
197 	{0x330f, 0x40},
198 	{0x3307, 0x04},
199 	{0x3500, 0x00},
200 	{0x3501, 0x4d},
201 	{0x3502, 0x40},
202 	{0x3503, 0x00},
203 	{0x3505, 0x80},
204 	{0x3508, 0x04},
205 	{0x3509, 0x00},
206 	{0x350c, 0x00},
207 	{0x350d, 0x80},
208 	{0x3510, 0x00},
209 	{0x3511, 0x02},
210 	{0x3512, 0x00},
211 	{0x3700, 0x18},
212 	{0x3701, 0x0c},
213 	{0x3702, 0x28},
214 	{0x3703, 0x19},
215 	{0x3704, 0x14},
216 	{0x3705, 0x00},
217 	{0x3706, 0x35},
218 	{0x3707, 0x04},
219 	{0x3708, 0x24},
220 	{0x3709, 0x33},
221 	{0x370a, 0x00},
222 	{0x370b, 0xb5},
223 	{0x370c, 0x04},
224 	{0x3718, 0x12},
225 	{0x3719, 0x31},
226 	{0x3712, 0x42},
227 	{0x3714, 0x24},
228 	{0x371e, 0x19},
229 	{0x371f, 0x40},
230 	{0x3720, 0x05},
231 	{0x3721, 0x05},
232 	{0x3724, 0x06},
233 	{0x3725, 0x01},
234 	{0x3726, 0x06},
235 	{0x3728, 0x05},
236 	{0x3729, 0x02},
237 	{0x372a, 0x03},
238 	{0x372b, 0x53},
239 	{0x372c, 0xa3},
240 	{0x372d, 0x53},
241 	{0x372e, 0x06},
242 	{0x372f, 0x10},
243 	{0x3730, 0x01},
244 	{0x3731, 0x06},
245 	{0x3732, 0x14},
246 	{0x3733, 0x10},
247 	{0x3734, 0x40},
248 	{0x3736, 0x20},
249 	{0x373a, 0x05},
250 	{0x373b, 0x06},
251 	{0x373c, 0x0a},
252 	{0x373e, 0x03},
253 	{0x3755, 0x10},
254 	{0x3758, 0x00},
255 	{0x3759, 0x4c},
256 	{0x375a, 0x06},
257 	{0x375b, 0x13},
258 	{0x375c, 0x20},
259 	{0x375d, 0x02},
260 	{0x375e, 0x00},
261 	{0x375f, 0x14},
262 	{0x3768, 0x22},
263 	{0x3769, 0x44},
264 	{0x376a, 0x44},
265 	{0x3761, 0x00},
266 	{0x3762, 0x00},
267 	{0x3763, 0x00},
268 	{0x3766, 0xff},
269 	{0x376b, 0x00},
270 	{0x3772, 0x23},
271 	{0x3773, 0x02},
272 	{0x3774, 0x16},
273 	{0x3775, 0x12},
274 	{0x3776, 0x04},
275 	{0x3777, 0x00},
276 	{0x3778, 0x1b},
277 	{0x37a0, 0x44},
278 	{0x37a1, 0x3d},
279 	{0x37a2, 0x3d},
280 	{0x37a3, 0x00},
281 	{0x37a4, 0x00},
282 	{0x37a5, 0x00},
283 	{0x37a6, 0x00},
284 	{0x37a7, 0x44},
285 	{0x37a8, 0x4c},
286 	{0x37a9, 0x4c},
287 	{0x3760, 0x00},
288 	{0x376f, 0x01},
289 	{0x37aa, 0x44},
290 	{0x37ab, 0x2e},
291 	{0x37ac, 0x2e},
292 	{0x37ad, 0x33},
293 	{0x37ae, 0x0d},
294 	{0x37af, 0x0d},
295 	{0x37b0, 0x00},
296 	{0x37b1, 0x00},
297 	{0x37b2, 0x00},
298 	{0x37b3, 0x42},
299 	{0x37b4, 0x42},
300 	{0x37b5, 0x33},
301 	{0x37b6, 0x00},
302 	{0x37b7, 0x00},
303 	{0x37b8, 0x00},
304 	{0x37b9, 0xff},
305 	{0x3800, 0x00},
306 	{0x3801, 0x0c},
307 	{0x3802, 0x00},
308 	{0x3803, 0x0c},
309 	{0x3804, 0x0c},
310 	{0x3805, 0xd3},
311 	{0x3806, 0x09},
312 	{0x3807, 0xa3},
313 	{0x3808, 0x06},
314 	{0x3809, 0x60},
315 	{0x380a, 0x04},
316 	{0x380b, 0xc8},
317 	{0x380c, 0x07},
318 	{0x380d, 0x88},
319 	{0x380e, 0x04},
320 	{0x380f, 0xdc},
321 	{0x3810, 0x00},
322 	{0x3811, 0x04},
323 	{0x3813, 0x02},
324 	{0x3814, 0x03},
325 	{0x3815, 0x01},
326 	{0x3820, 0x00},
327 	{0x3821, 0x67},
328 	{0x382a, 0x03},
329 	{0x382b, 0x01},
330 	{0x3830, 0x08},
331 	{0x3836, 0x02},
332 	{0x3837, 0x18},
333 	{0x3841, 0xff},
334 	{0x3846, 0x48},
335 	{0x3d85, 0x14},
336 	{0x3f08, 0x08},
337 	{0x3f0a, 0x80},
338 	{0x4000, 0xf1},
339 	{0x4001, 0x10},
340 	{0x4005, 0x10},
341 	{0x4002, 0x27},
342 	{0x4009, 0x81},
343 	{0x400b, 0x0c},
344 	{0x401b, 0x00},
345 	{0x401d, 0x00},
346 	{0x4020, 0x00},
347 	{0x4021, 0x04},
348 	{0x4022, 0x04},
349 	{0x4023, 0xb9},
350 	{0x4024, 0x05},
351 	{0x4025, 0x2a},
352 	{0x4026, 0x05},
353 	{0x4027, 0x2b},
354 	{0x4028, 0x00},
355 	{0x4029, 0x02},
356 	{0x402a, 0x04},
357 	{0x402b, 0x04},
358 	{0x402c, 0x02},
359 	{0x402d, 0x02},
360 	{0x402e, 0x08},
361 	{0x402f, 0x02},
362 	{0x401f, 0x00},
363 	{0x4034, 0x3f},
364 	{0x403d, 0x04},
365 	{0x4300, 0xff},
366 	{0x4301, 0x00},
367 	{0x4302, 0x0f},
368 	{0x4316, 0x00},
369 	{0x4500, 0x38},
370 	{0x4503, 0x18},
371 	{0x4600, 0x00},
372 	{0x4601, 0xcb},
373 	{0x481f, 0x32},
374 	{0x4837, 0x16},
375 	{0x4850, 0x10},
376 	{0x4851, 0x32},
377 	{0x4b00, 0x2a},
378 	{0x4b0d, 0x00},
379 	{0x4d00, 0x04},
380 	{0x4d01, 0x18},
381 	{0x4d02, 0xc3},
382 	{0x4d03, 0xff},
383 	{0x4d04, 0xff},
384 	{0x4d05, 0xff},
385 	{0x5000, 0x7e},
386 	{0x5001, 0x01},
387 	{0x5002, 0x08},
388 	{0x5003, 0x20},
389 	{0x5046, 0x12},
390 	{0x5901, 0x00},
391 	{0x5e00, 0x00},
392 	{0x5e01, 0x41},
393 	{0x382d, 0x7f},
394 	{0x4825, 0x3a},
395 	{0x4826, 0x40},
396 	{0x4808, 0x25},
397 	{REG_NULL, 0x00},
398 };
399 
400 static const struct regval ov8858_global_regs_r2a_2lane[] = {
401 	/*
402 	 * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
403 	 * v00_01_00 (05/29/2014) : initial setting
404 	 * AM19 : 3617 <- 0xC0
405 	 * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
406 	 */
407 	{0x0103, 0x01}, /* software reset */
408 	{0x0100, 0x00}, /* software standby */
409 	{0x0302, 0x1e}, /* pll1_multi */
410 	{0x0303, 0x00}, /* pll1_divm */
411 	{0x0304, 0x03}, /* pll1_div_mipi */
412 	{0x030e, 0x02}, /* pll2_rdiv */
413 	{0x030f, 0x04}, /* pll2_divsp */
414 	{0x0312, 0x03}, /* pll2_pre_div0, pll2_r_divdac */
415 	{0x031e, 0x0c}, /* pll1_no_lat */
416 	{0x3600, 0x00},
417 	{0x3601, 0x00},
418 	{0x3602, 0x00},
419 	{0x3603, 0x00},
420 	{0x3604, 0x22},
421 	{0x3605, 0x20},
422 	{0x3606, 0x00},
423 	{0x3607, 0x20},
424 	{0x3608, 0x11},
425 	{0x3609, 0x28},
426 	{0x360a, 0x00},
427 	{0x360b, 0x05},
428 	{0x360c, 0xd4},
429 	{0x360d, 0x40},
430 	{0x360e, 0x0c},
431 	{0x360f, 0x20},
432 	{0x3610, 0x07},
433 	{0x3611, 0x20},
434 	{0x3612, 0x88},
435 	{0x3613, 0x80},
436 	{0x3614, 0x58},
437 	{0x3615, 0x00},
438 	{0x3616, 0x4a},
439 	{0x3617, 0x90},
440 	{0x3618, 0x5a},
441 	{0x3619, 0x70},
442 	{0x361a, 0x99},
443 	{0x361b, 0x0a},
444 	{0x361c, 0x07},
445 	{0x361d, 0x00},
446 	{0x361e, 0x00},
447 	{0x361f, 0x00},
448 	{0x3638, 0xff},
449 	{0x3633, 0x0f},
450 	{0x3634, 0x0f},
451 	{0x3635, 0x0f},
452 	{0x3636, 0x12},
453 	{0x3645, 0x13},
454 	{0x3646, 0x83},
455 	{0x364a, 0x07},
456 	{0x3015, 0x00},
457 	{0x3018, 0x32}, /* MIPI 2 lane */
458 	{0x3020, 0x93}, /* Clock switch output normal, pclk_div =/1 */
459 	{0x3022, 0x01}, /* pd_mipi enable when rst_sync */
460 	{0x3031, 0x0a}, /* MIPI 10-bit mode */
461 	{0x3034, 0x00},
462 	{0x3106, 0x01}, /* sclk_div, sclk_pre_div */
463 	{0x3305, 0xf1},
464 	{0x3308, 0x00},
465 	{0x3309, 0x28},
466 	{0x330a, 0x00},
467 	{0x330b, 0x20},
468 	{0x330c, 0x00},
469 	{0x330d, 0x00},
470 	{0x330e, 0x00},
471 	{0x330f, 0x40},
472 	{0x3307, 0x04},
473 	{0x3500, 0x00}, /* exposure H */
474 	{0x3501, 0x4d}, /* exposure M */
475 	{0x3502, 0x40}, /* exposure L */
476 	{0x3503, 0x80}, /* gain delay ?, exposure delay 1 frame, real gain */
477 	{0x3505, 0x80}, /* gain option */
478 	{0x3508, 0x02}, /* gain H */
479 	{0x3509, 0x00}, /* gain L */
480 	{0x350c, 0x00}, /* short gain H */
481 	{0x350d, 0x80}, /* short gain L */
482 	{0x3510, 0x00}, /* short exposure H */
483 	{0x3511, 0x02}, /* short exposure M */
484 	{0x3512, 0x00}, /* short exposure L */
485 	{0x3700, 0x18},
486 	{0x3701, 0x0c},
487 	{0x3702, 0x28},
488 	{0x3703, 0x19},
489 	{0x3704, 0x14},
490 	{0x3705, 0x00},
491 	{0x3706, 0x82},
492 	{0x3707, 0x04},
493 	{0x3708, 0x24},
494 	{0x3709, 0x33},
495 	{0x370a, 0x01},
496 	{0x370b, 0x82},
497 	{0x370c, 0x04},
498 	{0x3718, 0x12},
499 	{0x3719, 0x31},
500 	{0x3712, 0x42},
501 	{0x3714, 0x24},
502 	{0x371e, 0x19},
503 	{0x371f, 0x40},
504 	{0x3720, 0x05},
505 	{0x3721, 0x05},
506 	{0x3724, 0x06},
507 	{0x3725, 0x01},
508 	{0x3726, 0x06},
509 	{0x3728, 0x05},
510 	{0x3729, 0x02},
511 	{0x372a, 0x03},
512 	{0x372b, 0x53},
513 	{0x372c, 0xa3},
514 	{0x372d, 0x53},
515 	{0x372e, 0x06},
516 	{0x372f, 0x10},
517 	{0x3730, 0x01},
518 	{0x3731, 0x06},
519 	{0x3732, 0x14},
520 	{0x3733, 0x10},
521 	{0x3734, 0x40},
522 	{0x3736, 0x20},
523 	{0x373a, 0x05},
524 	{0x373b, 0x06},
525 	{0x373c, 0x0a},
526 	{0x373e, 0x03},
527 	{0x3750, 0x0a},
528 	{0x3751, 0x0e},
529 	{0x3755, 0x10},
530 	{0x3758, 0x00},
531 	{0x3759, 0x4c},
532 	{0x375a, 0x06},
533 	{0x375b, 0x13},
534 	{0x375c, 0x20},
535 	{0x375d, 0x02},
536 	{0x375e, 0x00},
537 	{0x375f, 0x14},
538 	{0x3768, 0x22},
539 	{0x3769, 0x44},
540 	{0x376a, 0x44},
541 	{0x3761, 0x00},
542 	{0x3762, 0x00},
543 	{0x3763, 0x00},
544 	{0x3766, 0xff},
545 	{0x376b, 0x00},
546 	{0x3772, 0x23},
547 	{0x3773, 0x02},
548 	{0x3774, 0x16},
549 	{0x3775, 0x12},
550 	{0x3776, 0x04},
551 	{0x3777, 0x00},
552 	{0x3778, 0x17},
553 	{0x37a0, 0x44},
554 	{0x37a1, 0x3d},
555 	{0x37a2, 0x3d},
556 	{0x37a3, 0x00},
557 	{0x37a4, 0x00},
558 	{0x37a5, 0x00},
559 	{0x37a6, 0x00},
560 	{0x37a7, 0x44},
561 	{0x37a8, 0x4c},
562 	{0x37a9, 0x4c},
563 	{0x3760, 0x00},
564 	{0x376f, 0x01},
565 	{0x37aa, 0x44},
566 	{0x37ab, 0x2e},
567 	{0x37ac, 0x2e},
568 	{0x37ad, 0x33},
569 	{0x37ae, 0x0d},
570 	{0x37af, 0x0d},
571 	{0x37b0, 0x00},
572 	{0x37b1, 0x00},
573 	{0x37b2, 0x00},
574 	{0x37b3, 0x42},
575 	{0x37b4, 0x42},
576 	{0x37b5, 0x31},
577 	{0x37b6, 0x00},
578 	{0x37b7, 0x00},
579 	{0x37b8, 0x00},
580 	{0x37b9, 0xff},
581 	{0x3800, 0x00}, /* x start H */
582 	{0x3801, 0x0c}, /* x start L */
583 	{0x3802, 0x00}, /* y start H */
584 	{0x3803, 0x0c}, /* y start L */
585 	{0x3804, 0x0c}, /* x end H */
586 	{0x3805, 0xd3}, /* x end L */
587 	{0x3806, 0x09}, /* y end H */
588 	{0x3807, 0xa3}, /* y end L */
589 	{0x3808, 0x06}, /* x output size H */
590 	{0x3809, 0x60}, /* x output size L */
591 	{0x380a, 0x04}, /* y output size H */
592 	{0x380b, 0xc8}, /* y output size L */
593 	{0x380c, 0x07}, /* HTS H */
594 	{0x380d, 0x88}, /* HTS L */
595 	{0x380e, 0x04}, /* VTS H */
596 	{0x380f, 0xdc}, /* VTS L */
597 	{0x3810, 0x00}, /* ISP x win H */
598 	{0x3811, 0x04}, /* ISP x win L */
599 	{0x3813, 0x02}, /* ISP y win L */
600 	{0x3814, 0x03}, /* x odd inc */
601 	{0x3815, 0x01}, /* x even inc */
602 	{0x3820, 0x00}, /* vflip off */
603 	{0x3821, 0x67}, /* mirror on, bin on */
604 	{0x382a, 0x03}, /* y odd inc */
605 	{0x382b, 0x01}, /* y even inc */
606 	{0x3830, 0x08},
607 	{0x3836, 0x02},
608 	{0x3837, 0x18},
609 	{0x3841, 0xff}, /* window auto size enable */
610 	{0x3846, 0x48},
611 	{0x3d85, 0x16}, /* OTP power up load data enable with BIST */
612 	{0x3d8c, 0x73}, /* OTP setting start High */
613 	{0x3d8d, 0xde}, /* OTP setting start Low */
614 	{0x3f08, 0x08},
615 	{0x3f0a, 0x00},
616 	{0x4000, 0xf1}, /* out_range_trig, format_chg_trig */
617 	{0x4001, 0x10}, /* total 128 black column */
618 	{0x4005, 0x10}, /* BLC target L */
619 	{0x4002, 0x27}, /* value used to limit BLC offset */
620 	{0x4009, 0x81}, /* final BLC offset limitation enable */
621 	{0x400b, 0x0c}, /* DCBLC on, DCBLC manual mode on */
622 	{0x401b, 0x00}, /* zero line R coefficient */
623 	{0x401d, 0x00}, /* zoro line T coefficient */
624 	{0x4020, 0x00}, /* Anchor left start H */
625 	{0x4021, 0x04}, /* Anchor left start L */
626 	{0x4022, 0x06}, /* Anchor left end H */
627 	{0x4023, 0x00}, /* Anchor left end L */
628 	{0x4024, 0x0f}, /* Anchor right start H */
629 	{0x4025, 0x2a}, /* Anchor right start L */
630 	{0x4026, 0x0f}, /* Anchor right end H */
631 	{0x4027, 0x2b}, /* Anchor right end L */
632 	{0x4028, 0x00}, /* top zero line start */
633 	{0x4029, 0x02}, /* top zero line number */
634 	{0x402a, 0x04}, /* top black line start */
635 	{0x402b, 0x04}, /* top black line number */
636 	{0x402c, 0x00}, /* bottom zero line start */
637 	{0x402d, 0x02}, /* bottom zoro line number */
638 	{0x402e, 0x04}, /* bottom black line start */
639 	{0x402f, 0x04}, /* bottom black line number */
640 	{0x401f, 0x00}, /* interpolation x/y disable, Anchor one disable */
641 	{0x4034, 0x3f},
642 	{0x403d, 0x04}, /* md_precision_en */
643 	{0x4300, 0xff}, /* clip max H */
644 	{0x4301, 0x00}, /* clip min H */
645 	{0x4302, 0x0f}, /* clip min L, clip max L */
646 	{0x4316, 0x00},
647 	{0x4500, 0x58},
648 	{0x4503, 0x18},
649 	{0x4600, 0x00},
650 	{0x4601, 0xcb},
651 	{0x481f, 0x32}, /* clk prepare min */
652 	{0x4837, 0x16}, /* global timing */
653 	{0x4850, 0x10}, /* lane 1 = 1, lane 0 = 0 */
654 	{0x4851, 0x32}, /* lane 3 = 3, lane 2 = 2 */
655 	{0x4b00, 0x2a},
656 	{0x4b0d, 0x00},
657 	{0x4d00, 0x04}, /* temperature sensor */
658 	{0x4d01, 0x18},
659 	{0x4d02, 0xc3},
660 	{0x4d03, 0xff},
661 	{0x4d04, 0xff},
662 	{0x4d05, 0xff}, /* temperature sensor */
663 	{0x5000, 0xfe}, /* lenc on, slave/master AWB gain/statistics enable */
664 	{0x5001, 0x01}, /* BLC on */
665 	{0x5002, 0x08}, /* H scale off, WBMATCH off, OTP_DPC */
666 	{0x5003, 0x20}, /* DPC_DBC buffer control enable, WB */
667 	{0x501e, 0x93}, /* enable digital gain */
668 	{0x5046, 0x12},
669 	{0x5780, 0x3e}, /* DPC */
670 	{0x5781, 0x0f},
671 	{0x5782, 0x44},
672 	{0x5783, 0x02},
673 	{0x5784, 0x01},
674 	{0x5785, 0x00},
675 	{0x5786, 0x00},
676 	{0x5787, 0x04},
677 	{0x5788, 0x02},
678 	{0x5789, 0x0f},
679 	{0x578a, 0xfd},
680 	{0x578b, 0xf5},
681 	{0x578c, 0xf5},
682 	{0x578d, 0x03},
683 	{0x578e, 0x08},
684 	{0x578f, 0x0c},
685 	{0x5790, 0x08},
686 	{0x5791, 0x04},
687 	{0x5792, 0x00},
688 	{0x5793, 0x52},
689 	{0x5794, 0xa3}, /* DPC */
690 	{0x5871, 0x0d}, /* Lenc */
691 	{0x5870, 0x18},
692 	{0x586e, 0x10},
693 	{0x586f, 0x08},
694 	{0x58f7, 0x01},
695 	{0x58f8, 0x3d}, /* Lenc */
696 	{0x5901, 0x00}, /* H skip off, V skip off */
697 	{0x5b00, 0x02}, /* OTP DPC start address */
698 	{0x5b01, 0x10}, /* OTP DPC start address */
699 	{0x5b02, 0x03}, /* OTP DPC end address */
700 	{0x5b03, 0xcf}, /* OTP DPC end address */
701 	{0x5b05, 0x6c}, /* recover method = 2b11, */
702 	{0x5e00, 0x00}, /* use 0x3ff to test pattern off */
703 	{0x5e01, 0x41}, /* window cut enable */
704 	{0x382d, 0x7f},
705 	{0x4825, 0x3a}, /* lpx_p_min */
706 	{0x4826, 0x40}, /* hs_prepare_min */
707 	{0x4808, 0x25}, /* wake up delay in 1/1024 s */
708 	{0x3763, 0x18},
709 	{0x3768, 0xcc},
710 	{0x470b, 0x28},
711 	{0x4202, 0x00},
712 	{0x400d, 0x10}, /* BLC offset trigger L */
713 	{0x4040, 0x04}, /* BLC gain th2 */
714 	{0x403e, 0x04}, /* BLC gain th1 */
715 	{0x4041, 0xc6}, /* BLC */
716 	{0x3007, 0x80},
717 	{0x400a, 0x01},
718 	{REG_NULL, 0x00},
719 };
720 
721 /*
722  * Xclk 24Mhz
723  * max_framerate 30fps
724  * mipi_datarate per lane 720Mbps
725  */
726 static const struct regval ov8858_1632x1224_regs_2lane[] = {
727 	/*
728 	 * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
729 	 * v00_01_00 (05/29/2014) : initial setting
730 	 * AM19 : 3617 <- 0xC0
731 	 * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
732 	 */
733 	{0x0100, 0x00},
734 	{0x3501, 0x4d}, /* exposure M */
735 	{0x3502, 0x40}, /* exposure L */
736 	{0x3778, 0x17},
737 	{0x3808, 0x06}, /* x output size H */
738 	{0x3809, 0x60}, /* x output size L */
739 	{0x380a, 0x04}, /* y output size H */
740 	{0x380b, 0xc8}, /* y output size L */
741 	{0x380c, 0x07}, /* HTS H */
742 	{0x380d, 0x88}, /* HTS L */
743 	{0x380e, 0x04}, /* VTS H */
744 	{0x380f, 0xdc}, /* VTS L */
745 	{0x3814, 0x03}, /* x odd inc */
746 	{0x3821, 0x67}, /* mirror on, bin on */
747 	{0x382a, 0x03}, /* y odd inc */
748 	{0x3830, 0x08},
749 	{0x3836, 0x02},
750 	{0x3f0a, 0x00},
751 	{0x4001, 0x10}, /* total 128 black column */
752 	{0x4022, 0x06}, /* Anchor left end H */
753 	{0x4023, 0x00}, /* Anchor left end L */
754 	{0x4025, 0x2a}, /* Anchor right start L */
755 	{0x4027, 0x2b}, /* Anchor right end L */
756 	{0x402b, 0x04}, /* top black line number */
757 	{0x402f, 0x04}, /* bottom black line number */
758 	{0x4500, 0x58},
759 	{0x4600, 0x00},
760 	{0x4601, 0xcb},
761 	{0x382d, 0x7f},
762 	{0x0100, 0x01},
763 	{REG_NULL, 0x00},
764 };
765 
766 /*
767  * Xclk 24Mhz
768  * max_framerate 15fps
769  * mipi_datarate per lane 720Mbps
770  */
771 static const struct regval ov8858_3264x2448_regs_2lane[] = {
772 	{0x0100, 0x00},
773 	{0x3501, 0x9a}, /* exposure M */
774 	{0x3502, 0x20}, /* exposure L */
775 	{0x3778, 0x1a},
776 	{0x3808, 0x0c}, /* x output size H */
777 	{0x3809, 0xc0}, /* x output size L */
778 	{0x380a, 0x09}, /* y output size H */
779 	{0x380b, 0x90}, /* y output size L */
780 	{0x380c, 0x07}, /* HTS H */
781 	{0x380d, 0x94}, /* HTS L */
782 	{0x380e, 0x09}, /* VTS H */
783 	{0x380f, 0xaa}, /* VTS L */
784 	{0x3814, 0x01}, /* x odd inc */
785 	{0x3821, 0x46}, /* mirror on, bin off */
786 	{0x382a, 0x01}, /* y odd inc */
787 	{0x3830, 0x06},
788 	{0x3836, 0x01},
789 	{0x3f0a, 0x00},
790 	{0x4001, 0x00}, /* total 256 black column */
791 	{0x4022, 0x0c}, /* Anchor left end H */
792 	{0x4023, 0x60}, /* Anchor left end L */
793 	{0x4025, 0x36}, /* Anchor right start L */
794 	{0x4027, 0x37}, /* Anchor right end L */
795 	{0x402b, 0x08}, /* top black line number */
796 	{0x402f, 0x08}, /* bottom black line number */
797 	{0x4500, 0x58},
798 	{0x4600, 0x01},
799 	{0x4601, 0x97},
800 	{0x382d, 0xff},
801 	{REG_NULL, 0x00},
802 };
803 
804 static const struct regval ov8858_global_regs_r2a_4lane[] = {
805 	/*
806 	 * MIPI=720Mbps, SysClk=144Mhz,Dac Clock=360Mhz.
807 	 * v00_01_00 (05/29/2014) : initial setting
808 	 * AM19 : 3617 <- 0xC0
809 	 * AM20 : change FWC_6K_EN to be default 0x3618=0x5a
810 	 */
811 	{0x0103, 0x01}, /* software reset for OVTATool only */
812 	{0x0103, 0x01}, /* software reset */
813 	{0x0100, 0x00}, /* software standby */
814 	{0x0302, 0x1e}, /* pll1_multi */
815 	{0x0303, 0x00}, /* pll1_divm */
816 	{0x0304, 0x03}, /* pll1_div_mipi */
817 	{0x030e, 0x00}, /* pll2_rdiv */
818 	{0x030f, 0x04}, /* pll2_divsp */
819 	{0x0312, 0x01}, /* pll2_pre_div0, pll2_r_divdac */
820 	{0x031e, 0x0c}, /* pll1_no_lat */
821 	{0x3600, 0x00},
822 	{0x3601, 0x00},
823 	{0x3602, 0x00},
824 	{0x3603, 0x00},
825 	{0x3604, 0x22},
826 	{0x3605, 0x20},
827 	{0x3606, 0x00},
828 	{0x3607, 0x20},
829 	{0x3608, 0x11},
830 	{0x3609, 0x28},
831 	{0x360a, 0x00},
832 	{0x360b, 0x05},
833 	{0x360c, 0xd4},
834 	{0x360d, 0x40},
835 	{0x360e, 0x0c},
836 	{0x360f, 0x20},
837 	{0x3610, 0x07},
838 	{0x3611, 0x20},
839 	{0x3612, 0x88},
840 	{0x3613, 0x80},
841 	{0x3614, 0x58},
842 	{0x3615, 0x00},
843 	{0x3616, 0x4a},
844 	{0x3617, 0x90},
845 	{0x3618, 0x5a},
846 	{0x3619, 0x70},
847 	{0x361a, 0x99},
848 	{0x361b, 0x0a},
849 	{0x361c, 0x07},
850 	{0x361d, 0x00},
851 	{0x361e, 0x00},
852 	{0x361f, 0x00},
853 	{0x3638, 0xff},
854 	{0x3633, 0x0f},
855 	{0x3634, 0x0f},
856 	{0x3635, 0x0f},
857 	{0x3636, 0x12},
858 	{0x3645, 0x13},
859 	{0x3646, 0x83},
860 	{0x364a, 0x07},
861 	{0x3015, 0x01},
862 	{0x3018, 0x72}, /* MIPI 4 lane */
863 	{0x3020, 0x93}, /* Clock switch output normal, pclk_div =/1 */
864 	{0x3022, 0x01}, /* pd_mipi enable when rst_sync */
865 	{0x3031, 0x0a}, /* MIPI 10-bit mode */
866 	{0x3034, 0x00},
867 	{0x3106, 0x01}, /* sclk_div, sclk_pre_div */
868 	{0x3305, 0xf1},
869 	{0x3308, 0x00},
870 	{0x3309, 0x28},
871 	{0x330a, 0x00},
872 	{0x330b, 0x20},
873 	{0x330c, 0x00},
874 	{0x330d, 0x00},
875 	{0x330e, 0x00},
876 	{0x330f, 0x40},
877 	{0x3307, 0x04},
878 	{0x3500, 0x00}, /* exposure H */
879 	{0x3501, 0x4d}, /* exposure M */
880 	{0x3502, 0x40}, /* exposure L */
881 	{0x3503, 0x80}, /* gain delay ?, exposure delay 1 frame, real gain */
882 	{0x3505, 0x80}, /* gain option */
883 	{0x3508, 0x02}, /* gain H */
884 	{0x3509, 0x00}, /* gain L */
885 	{0x350c, 0x00}, /* short gain H */
886 	{0x350d, 0x80}, /* short gain L */
887 	{0x3510, 0x00}, /* short exposure H */
888 	{0x3511, 0x02}, /* short exposure M */
889 	{0x3512, 0x00}, /* short exposure L */
890 	{0x3700, 0x30},
891 	{0x3701, 0x18},
892 	{0x3702, 0x50},
893 	{0x3703, 0x32},
894 	{0x3704, 0x28},
895 	{0x3705, 0x00},
896 	{0x3706, 0x82},
897 	{0x3707, 0x08},
898 	{0x3708, 0x48},
899 	{0x3709, 0x66},
900 	{0x370a, 0x01},
901 	{0x370b, 0x82},
902 	{0x370c, 0x07},
903 	{0x3718, 0x14},
904 	{0x3719, 0x31},
905 	{0x3712, 0x44},
906 	{0x3714, 0x24},
907 	{0x371e, 0x31},
908 	{0x371f, 0x7f},
909 	{0x3720, 0x0a},
910 	{0x3721, 0x0a},
911 	{0x3724, 0x0c},
912 	{0x3725, 0x02},
913 	{0x3726, 0x0c},
914 	{0x3728, 0x0a},
915 	{0x3729, 0x03},
916 	{0x372a, 0x06},
917 	{0x372b, 0xa6},
918 	{0x372c, 0xa6},
919 	{0x372d, 0xa6},
920 	{0x372e, 0x0c},
921 	{0x372f, 0x20},
922 	{0x3730, 0x02},
923 	{0x3731, 0x0c},
924 	{0x3732, 0x28},
925 	{0x3733, 0x10},
926 	{0x3734, 0x40},
927 	{0x3736, 0x30},
928 	{0x373a, 0x0a},
929 	{0x373b, 0x0b},
930 	{0x373c, 0x14},
931 	{0x373e, 0x06},
932 	{0x3750, 0x0a},
933 	{0x3751, 0x0e},
934 	{0x3755, 0x10},
935 	{0x3758, 0x00},
936 	{0x3759, 0x4c},
937 	{0x375a, 0x0c},
938 	{0x375b, 0x26},
939 	{0x375c, 0x20},
940 	{0x375d, 0x04},
941 	{0x375e, 0x00},
942 	{0x375f, 0x28},
943 	{0x3768, 0x22},
944 	{0x3769, 0x44},
945 	{0x376a, 0x44},
946 	{0x3761, 0x00},
947 	{0x3762, 0x00},
948 	{0x3763, 0x00},
949 	{0x3766, 0xff},
950 	{0x376b, 0x00},
951 	{0x3772, 0x46},
952 	{0x3773, 0x04},
953 	{0x3774, 0x2c},
954 	{0x3775, 0x13},
955 	{0x3776, 0x08},
956 	{0x3777, 0x00},
957 	{0x3778, 0x17},
958 	{0x37a0, 0x88},
959 	{0x37a1, 0x7a},
960 	{0x37a2, 0x7a},
961 	{0x37a3, 0x00},
962 	{0x37a4, 0x00},
963 	{0x37a5, 0x00},
964 	{0x37a6, 0x00},
965 	{0x37a7, 0x88},
966 	{0x37a8, 0x98},
967 	{0x37a9, 0x98},
968 	{0x3760, 0x00},
969 	{0x376f, 0x01},
970 	{0x37aa, 0x88},
971 	{0x37ab, 0x5c},
972 	{0x37ac, 0x5c},
973 	{0x37ad, 0x55},
974 	{0x37ae, 0x19},
975 	{0x37af, 0x19},
976 	{0x37b0, 0x00},
977 	{0x37b1, 0x00},
978 	{0x37b2, 0x00},
979 	{0x37b3, 0x84},
980 	{0x37b4, 0x84},
981 	{0x37b5, 0x60},
982 	{0x37b6, 0x00},
983 	{0x37b7, 0x00},
984 	{0x37b8, 0x00},
985 	{0x37b9, 0xff},
986 	{0x3800, 0x00}, /* x start H */
987 	{0x3801, 0x0c}, /* x start L */
988 	{0x3802, 0x00}, /* y start H */
989 	{0x3803, 0x0c}, /* y start L */
990 	{0x3804, 0x0c}, /* x end H */
991 	{0x3805, 0xd3}, /* x end L */
992 	{0x3806, 0x09}, /* y end H */
993 	{0x3807, 0xa3}, /* y end L */
994 	{0x3808, 0x06}, /* x output size H */
995 	{0x3809, 0x60}, /* x output size L */
996 	{0x380a, 0x04}, /* y output size H */
997 	{0x380b, 0xc8}, /* y output size L */
998 	{0x380c, 0x07}, /* HTS H */
999 	{0x380d, 0x88}, /* HTS L */
1000 	{0x380e, 0x04}, /* VTS H */
1001 	{0x380f, 0xdc}, /* VTS L */
1002 	{0x3810, 0x00}, /* ISP x win H */
1003 	{0x3811, 0x04}, /* ISP x win L */
1004 	{0x3813, 0x02}, /* ISP y win L */
1005 	{0x3814, 0x03}, /* x odd inc */
1006 	{0x3815, 0x01}, /* x even inc */
1007 	{0x3820, 0x00}, /* vflip off */
1008 	{0x3821, 0x67}, /* mirror on, bin o */
1009 	{0x382a, 0x03}, /* y odd inc */
1010 	{0x382b, 0x01}, /* y even inc */
1011 	{0x3830, 0x08},
1012 	{0x3836, 0x02},
1013 	{0x3837, 0x18},
1014 	{0x3841, 0xff}, /* window auto size enable */
1015 	{0x3846, 0x48},
1016 	{0x3d85, 0x16}, /* OTP power up load data/setting enable */
1017 	{0x3d8c, 0x73}, /* OTP setting start High */
1018 	{0x3d8d, 0xde}, /* OTP setting start Low */
1019 	{0x3f08, 0x10},
1020 	{0x3f0a, 0x00},
1021 	{0x4000, 0xf1}, /* out_range/format_chg/gain/exp_chg trig enable */
1022 	{0x4001, 0x10}, /* total 128 black column */
1023 	{0x4005, 0x10}, /* BLC target L */
1024 	{0x4002, 0x27}, /* value used to limit BLC offset */
1025 	{0x4009, 0x81}, /* final BLC offset limitation enable */
1026 	{0x400b, 0x0c}, /* DCBLC on, DCBLC manual mode on */
1027 	{0x401b, 0x00}, /* zero line R coefficient */
1028 	{0x401d, 0x00}, /* zoro line T coefficient */
1029 	{0x4020, 0x00}, /* Anchor left start H */
1030 	{0x4021, 0x04}, /* Anchor left start L */
1031 	{0x4022, 0x06}, /* Anchor left end H */
1032 	{0x4023, 0x00}, /* Anchor left end L */
1033 	{0x4024, 0x0f}, /* Anchor right start H */
1034 	{0x4025, 0x2a}, /* Anchor right start L */
1035 	{0x4026, 0x0f}, /* Anchor right end H */
1036 	{0x4027, 0x2b}, /* Anchor right end L */
1037 	{0x4028, 0x00}, /* top zero line start */
1038 	{0x4029, 0x02}, /* top zero line number */
1039 	{0x402a, 0x04}, /* top black line start */
1040 	{0x402b, 0x04}, /* top black line number */
1041 	{0x402c, 0x00}, /* bottom zero line start */
1042 	{0x402d, 0x02}, /* bottom zoro line number */
1043 	{0x402e, 0x04}, /* bottom black line start */
1044 	{0x402f, 0x04}, /* bottom black line number */
1045 	{0x401f, 0x00}, /* interpolation x/y disable, Anchor one disable */
1046 	{0x4034, 0x3f},
1047 	{0x403d, 0x04}, /* md_precision_en */
1048 	{0x4300, 0xff}, /* clip max H */
1049 	{0x4301, 0x00}, /* clip min H */
1050 	{0x4302, 0x0f}, /* clip min L, clip max L */
1051 	{0x4316, 0x00},
1052 	{0x4500, 0x58},
1053 	{0x4503, 0x18},
1054 	{0x4600, 0x00},
1055 	{0x4601, 0xcb},
1056 	{0x481f, 0x32}, /* clk prepare min */
1057 	{0x4837, 0x16}, /* global timing */
1058 	{0x4850, 0x10}, /* lane 1 = 1, lane 0 = 0 */
1059 	{0x4851, 0x32}, /* lane 3 = 3, lane 2 = 2 */
1060 	{0x4b00, 0x2a},
1061 	{0x4b0d, 0x00},
1062 	{0x4d00, 0x04}, /* temperature sensor */
1063 	{0x4d01, 0x18},
1064 	{0x4d02, 0xc3},
1065 	{0x4d03, 0xff},
1066 	{0x4d04, 0xff},
1067 	{0x4d05, 0xff}, /* temperature sensor */
1068 	{0x5000, 0xfe}, /* lenc on, slave/master AWB gain/statistics enable */
1069 	{0x5001, 0x01}, /* BLC on */
1070 	{0x5002, 0x08}, /* WBMATCH sensor's gain, H scale/WBMATCH/OTP_DPC off */
1071 	{0x5003, 0x20}, /* DPC_DBC buffer control enable, WB */
1072 	{0x501e, 0x93}, /* enable digital gain */
1073 	{0x5046, 0x12},
1074 	{0x5780, 0x3e}, /* DPC */
1075 	{0x5781, 0x0f},
1076 	{0x5782, 0x44},
1077 	{0x5783, 0x02},
1078 	{0x5784, 0x01},
1079 	{0x5785, 0x00},
1080 	{0x5786, 0x00},
1081 	{0x5787, 0x04},
1082 	{0x5788, 0x02},
1083 	{0x5789, 0x0f},
1084 	{0x578a, 0xfd},
1085 	{0x578b, 0xf5},
1086 	{0x578c, 0xf5},
1087 	{0x578d, 0x03},
1088 	{0x578e, 0x08},
1089 	{0x578f, 0x0c},
1090 	{0x5790, 0x08},
1091 	{0x5791, 0x04},
1092 	{0x5792, 0x00},
1093 	{0x5793, 0x52},
1094 	{0x5794, 0xa3}, /* DPC */
1095 	{0x5871, 0x0d}, /* Lenc */
1096 	{0x5870, 0x18},
1097 	{0x586e, 0x10},
1098 	{0x586f, 0x08},
1099 	{0x58f7, 0x01},
1100 	{0x58f8, 0x3d}, /* Lenc */
1101 	{0x5901, 0x00}, /* H skip off, V skip off */
1102 	{0x5b00, 0x02}, /* OTP DPC start address */
1103 	{0x5b01, 0x10}, /* OTP DPC start address */
1104 	{0x5b02, 0x03}, /* OTP DPC end address */
1105 	{0x5b03, 0xcf}, /* OTP DPC end address */
1106 	{0x5b05, 0x6c}, /* recover method = 2b11 */
1107 	{0x5e00, 0x00}, /* use 0x3ff to test pattern off */
1108 	{0x5e01, 0x41}, /* window cut enable */
1109 	{0x382d, 0x7f},
1110 	{0x4825, 0x3a}, /* lpx_p_min */
1111 	{0x4826, 0x40}, /* hs_prepare_min */
1112 	{0x4808, 0x25}, /* wake up delay in 1/1024 s */
1113 	{0x3763, 0x18},
1114 	{0x3768, 0xcc},
1115 	{0x470b, 0x28},
1116 	{0x4202, 0x00},
1117 	{0x400d, 0x10}, /* BLC offset trigger L */
1118 	{0x4040, 0x04}, /* BLC gain th2 */
1119 	{0x403e, 0x04}, /* BLC gain th1 */
1120 	{0x4041, 0xc6}, /* BLC */
1121 	{0x3007, 0x80},
1122 	{0x400a, 0x01},
1123 	{REG_NULL, 0x00},
1124 };
1125 
1126 /*
1127  * Xclk 24Mhz
1128  * max_framerate 60fps
1129  * mipi_datarate per lane 720Mbps
1130  */
1131 static const struct regval ov8858_1632x1224_regs_4lane[] = {
1132 	{0x0100, 0x00},
1133 	{0x3501, 0x4d}, /* exposure M */
1134 	{0x3502, 0x40}, /* exposure L */
1135 	{0x3808, 0x06}, /* x output size H */
1136 	{0x3809, 0x60}, /* x output size L */
1137 	{0x380a, 0x04}, /* y output size H */
1138 	{0x380b, 0xc8}, /* y output size L */
1139 	{0x380c, 0x07}, /* HTS H */
1140 	{0x380d, 0x88}, /* HTS L */
1141 	{0x380e, 0x04}, /* VTS H */
1142 	{0x380f, 0xdc}, /* VTS L */
1143 	{0x3814, 0x03}, /* x odd inc */
1144 	{0x3821, 0x67}, /* mirror on, bin on */
1145 	{0x382a, 0x03}, /* y odd inc */
1146 	{0x3830, 0x08},
1147 	{0x3836, 0x02},
1148 	{0x3f0a, 0x00},
1149 	{0x4001, 0x10}, /* total 128 black column */
1150 	{0x4022, 0x06}, /* Anchor left end H */
1151 	{0x4023, 0x00}, /* Anchor left end L */
1152 	{0x4025, 0x2a}, /* Anchor right start L */
1153 	{0x4027, 0x2b}, /* Anchor right end L */
1154 	{0x402b, 0x04}, /* top black line number */
1155 	{0x402f, 0x04}, /* bottom black line number */
1156 	{0x4500, 0x58},
1157 	{0x4600, 0x00},
1158 	{0x4601, 0xcb},
1159 	{0x382d, 0x7f},
1160 	{0x0100, 0x01},
1161 	{REG_NULL, 0x00},
1162 };
1163 
1164 /*
1165  * Xclk 24Mhz
1166  * max_framerate 30fps
1167  * mipi_datarate per lane 720Mbps
1168  */
1169 static const struct regval ov8858_3264x2448_regs_4lane[] = {
1170 	{0x0100, 0x00},
1171 	{0x3501, 0x9a}, /* exposure M */
1172 	{0x3502, 0x20}, /* exposure L */
1173 	{0x3808, 0x0c}, /* x output size H */
1174 	{0x3809, 0xc0}, /* x output size L */
1175 	{0x380a, 0x09}, /* y output size H */
1176 	{0x380b, 0x90}, /* y output size L */
1177 	{0x380c, 0x07}, /* HTS H */
1178 	{0x380d, 0x94}, /* HTS L */
1179 	{0x380e, 0x09}, /* VTS H */
1180 	{0x380f, 0xaa}, /* VTS L */
1181 	{0x3814, 0x01}, /* x odd inc */
1182 	{0x3821, 0x46}, /* mirror on, bin off */
1183 	{0x382a, 0x01}, /* y odd inc */
1184 	{0x3830, 0x06},
1185 	{0x3836, 0x01},
1186 	{0x3f0a, 0x00},
1187 	{0x4001, 0x00}, /* total 256 black column */
1188 	{0x4022, 0x0c}, /* Anchor left end H */
1189 	{0x4023, 0x60}, /* Anchor left end L */
1190 	{0x4025, 0x36}, /* Anchor right start L */
1191 	{0x4027, 0x37}, /* Anchor right end L */
1192 	{0x402b, 0x08}, /* top black line number */
1193 	{0x402f, 0x08}, /* interpolation x/y disable, Anchor one disable */
1194 	{0x4500, 0x58},
1195 	{0x4600, 0x01},
1196 	{0x4601, 0x97},
1197 	{0x382d, 0xff},
1198 	{REG_NULL, 0x00},
1199 };
1200 
1201 static const struct ov8858_mode ov8858_modes[] = {
1202 	{
1203 		.width = 3264,
1204 		.height = 2448,
1205 		.exp_def = 2464,
1206 		.hts_def = 1940 * 2,
1207 		.vts_def = 2472,
1208 		.reg_modes = {
1209 			.mode_2lanes = ov8858_3264x2448_regs_2lane,
1210 			.mode_4lanes = ov8858_3264x2448_regs_4lane,
1211 		},
1212 	},
1213 	{
1214 		.width = 1632,
1215 		.height = 1224,
1216 		.exp_def = 1232,
1217 		.hts_def = 1928 * 2,
1218 		.vts_def = 1244,
1219 		.reg_modes = {
1220 			.mode_2lanes = ov8858_1632x1224_regs_2lane,
1221 			.mode_4lanes = ov8858_1632x1224_regs_4lane,
1222 		},
1223 	},
1224 };
1225 
1226 static const s64 link_freq_menu_items[] = {
1227 	OV8858_LINK_FREQ
1228 };
1229 
1230 static const char * const ov8858_test_pattern_menu[] = {
1231 	"Disabled",
1232 	"Vertical Color Bar Type 1",
1233 	"Vertical Color Bar Type 2",
1234 	"Vertical Color Bar Type 3",
1235 	"Vertical Color Bar Type 4"
1236 };
1237 
1238 /* ----------------------------------------------------------------------------
1239  * HW access
1240  */
1241 
1242 static int ov8858_write(struct ov8858 *ov8858, u32 reg, u32 val, int *err)
1243 {
1244 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1245 	unsigned int len = (reg >> OV8858_REG_SIZE_SHIFT) & 3;
1246 	u16 addr = reg & OV8858_REG_ADDR_MASK;
1247 	u8 buf[6];
1248 	int ret;
1249 
1250 	if (err && *err)
1251 		return *err;
1252 
1253 	put_unaligned_be16(addr, buf);
1254 	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1255 
1256 	ret = i2c_master_send(client, buf, len + 2);
1257 	if (ret != len + 2) {
1258 		ret = ret < 0 ? ret : -EIO;
1259 		if (err)
1260 			*err = ret;
1261 
1262 		dev_err(&client->dev,
1263 			"Failed to write reg %u: %d\n", addr, ret);
1264 		return ret;
1265 	}
1266 
1267 	return 0;
1268 }
1269 
1270 static int ov8858_write_array(struct ov8858 *ov8858, const struct regval *regs)
1271 {
1272 	unsigned int i;
1273 	int ret = 0;
1274 
1275 	for (i = 0; ret == 0 && regs[i].addr != REG_NULL; ++i) {
1276 		ov8858_write(ov8858, OV8858_REG_8BIT(regs[i].addr),
1277 			     regs[i].val, &ret);
1278 	}
1279 
1280 	return ret;
1281 }
1282 
1283 static int ov8858_read(struct ov8858 *ov8858, u32 reg, u32 *val)
1284 {
1285 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1286 	__be16 reg_addr_be = cpu_to_be16(reg & OV8858_REG_ADDR_MASK);
1287 	unsigned int len = (reg >> OV8858_REG_SIZE_SHIFT) & 3;
1288 	struct i2c_msg msgs[2];
1289 	__be32 data_be = 0;
1290 	u8 *data_be_p;
1291 	int ret;
1292 
1293 	data_be_p = (u8 *)&data_be;
1294 
1295 	/* Write register address */
1296 	msgs[0].addr = client->addr;
1297 	msgs[0].flags = 0;
1298 	msgs[0].len = 2;
1299 	msgs[0].buf = (u8 *)&reg_addr_be;
1300 
1301 	/* Read data from register */
1302 	msgs[1].addr = client->addr;
1303 	msgs[1].flags = I2C_M_RD;
1304 	msgs[1].len = len;
1305 	msgs[1].buf = &data_be_p[4 - len];
1306 
1307 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1308 	if (ret != ARRAY_SIZE(msgs)) {
1309 		ret = ret < 0 ? ret : -EIO;
1310 		dev_err(&client->dev,
1311 			"Failed to read reg %u: %d\n", reg, ret);
1312 		return ret;
1313 	}
1314 
1315 	*val = be32_to_cpu(data_be);
1316 
1317 	return 0;
1318 }
1319 
1320 /* ----------------------------------------------------------------------------
1321  * Streaming
1322  */
1323 
1324 static int ov8858_start_stream(struct ov8858 *ov8858,
1325 			       struct v4l2_subdev_state *state)
1326 {
1327 	struct v4l2_mbus_framefmt *format;
1328 	const struct ov8858_mode *mode;
1329 	const struct regval *reg_list;
1330 	int ret;
1331 
1332 	ret = ov8858_write_array(ov8858, ov8858->global_regs);
1333 	if (ret)
1334 		return ret;
1335 
1336 	format = v4l2_subdev_get_pad_format(&ov8858->subdev, state, 0);
1337 	mode = v4l2_find_nearest_size(ov8858_modes, ARRAY_SIZE(ov8858_modes),
1338 				      width, height, format->width,
1339 				      format->height);
1340 
1341 	reg_list = ov8858->num_lanes == 4
1342 		 ? mode->reg_modes.mode_4lanes
1343 		 : mode->reg_modes.mode_2lanes;
1344 
1345 	ret = ov8858_write_array(ov8858, reg_list);
1346 	if (ret)
1347 		return ret;
1348 
1349 	/* 200 usec max to let PLL stabilize. */
1350 	fsleep(200);
1351 
1352 	ret = __v4l2_ctrl_handler_setup(&ov8858->ctrl_handler);
1353 	if (ret)
1354 		return ret;
1355 
1356 	ret = ov8858_write(ov8858, OV8858_REG_SC_CTRL0100,
1357 			   OV8858_MODE_STREAMING, NULL);
1358 	if (ret)
1359 		return ret;
1360 
1361 	/* t5 (fixed) = 10msec before entering streaming state */
1362 	fsleep(10000);
1363 
1364 	return 0;
1365 }
1366 
1367 static int ov8858_stop_stream(struct ov8858 *ov8858)
1368 {
1369 	return ov8858_write(ov8858, OV8858_REG_SC_CTRL0100,
1370 			    OV8858_MODE_SW_STANDBY, NULL);
1371 }
1372 
1373 static int ov8858_s_stream(struct v4l2_subdev *sd, int on)
1374 {
1375 	struct i2c_client *client = v4l2_get_subdevdata(sd);
1376 	struct ov8858 *ov8858 = sd_to_ov8858(sd);
1377 	struct v4l2_subdev_state *state;
1378 	int ret = 0;
1379 
1380 	state = v4l2_subdev_lock_and_get_active_state(sd);
1381 
1382 	if (on) {
1383 		ret = pm_runtime_resume_and_get(&client->dev);
1384 		if (ret < 0)
1385 			goto unlock_and_return;
1386 
1387 		ret = ov8858_start_stream(ov8858, state);
1388 		if (ret) {
1389 			dev_err(&client->dev, "Failed to start streaming\n");
1390 			pm_runtime_put_sync(&client->dev);
1391 			goto unlock_and_return;
1392 		}
1393 	} else {
1394 		ov8858_stop_stream(ov8858);
1395 		pm_runtime_mark_last_busy(&client->dev);
1396 		pm_runtime_put_autosuspend(&client->dev);
1397 	}
1398 
1399 unlock_and_return:
1400 	v4l2_subdev_unlock_state(state);
1401 
1402 	return ret;
1403 }
1404 
1405 static const struct v4l2_subdev_video_ops ov8858_video_ops = {
1406 	.s_stream = ov8858_s_stream,
1407 };
1408 
1409 /* ----------------------------------------------------------------------------
1410  * Pad ops
1411  */
1412 
1413 static int ov8858_set_fmt(struct v4l2_subdev *sd,
1414 			  struct v4l2_subdev_state *state,
1415 			  struct v4l2_subdev_format *fmt)
1416 {
1417 	struct ov8858 *ov8858 = sd_to_ov8858(sd);
1418 	const struct ov8858_mode *mode;
1419 	s64 h_blank, vblank_def;
1420 
1421 	mode = v4l2_find_nearest_size(ov8858_modes, ARRAY_SIZE(ov8858_modes),
1422 				      width, height, fmt->format.width,
1423 				      fmt->format.height);
1424 
1425 	fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
1426 	fmt->format.width = mode->width;
1427 	fmt->format.height = mode->height;
1428 	fmt->format.field = V4L2_FIELD_NONE;
1429 
1430 	/* Store the format in the current subdev state. */
1431 	*v4l2_subdev_get_pad_format(sd, state, 0) =  fmt->format;
1432 
1433 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
1434 		return 0;
1435 
1436 	/* Adjust control limits when a new mode is applied. */
1437 	h_blank = mode->hts_def - mode->width;
1438 	__v4l2_ctrl_modify_range(ov8858->hblank, h_blank, h_blank, 1,
1439 				 h_blank);
1440 
1441 	vblank_def = mode->vts_def - mode->height;
1442 	__v4l2_ctrl_modify_range(ov8858->vblank, vblank_def,
1443 				 OV8858_VTS_MAX - mode->height, 1,
1444 				 vblank_def);
1445 
1446 	return 0;
1447 }
1448 
1449 static int ov8858_enum_frame_sizes(struct v4l2_subdev *sd,
1450 				   struct v4l2_subdev_state *state,
1451 				   struct v4l2_subdev_frame_size_enum *fse)
1452 {
1453 	if (fse->index >= ARRAY_SIZE(ov8858_modes))
1454 		return -EINVAL;
1455 
1456 	if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
1457 		return -EINVAL;
1458 
1459 	fse->min_width  = ov8858_modes[fse->index].width;
1460 	fse->max_width  = ov8858_modes[fse->index].width;
1461 	fse->max_height = ov8858_modes[fse->index].height;
1462 	fse->min_height = ov8858_modes[fse->index].height;
1463 
1464 	return 0;
1465 }
1466 
1467 static int ov8858_enum_mbus_code(struct v4l2_subdev *sd,
1468 				 struct v4l2_subdev_state *state,
1469 				 struct v4l2_subdev_mbus_code_enum *code)
1470 {
1471 	if (code->index != 0)
1472 		return -EINVAL;
1473 
1474 	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
1475 
1476 	return 0;
1477 }
1478 
1479 static int ov8858_init_cfg(struct v4l2_subdev *sd,
1480 			   struct v4l2_subdev_state *sd_state)
1481 {
1482 	const struct ov8858_mode *def_mode = &ov8858_modes[0];
1483 	struct v4l2_subdev_format fmt = {
1484 		.which = V4L2_SUBDEV_FORMAT_TRY,
1485 		.format = {
1486 			.width = def_mode->width,
1487 			.height = def_mode->height,
1488 		},
1489 	};
1490 
1491 	ov8858_set_fmt(sd, sd_state, &fmt);
1492 
1493 	return 0;
1494 }
1495 
1496 static const struct v4l2_subdev_pad_ops ov8858_pad_ops = {
1497 	.init_cfg = ov8858_init_cfg,
1498 	.enum_mbus_code = ov8858_enum_mbus_code,
1499 	.enum_frame_size = ov8858_enum_frame_sizes,
1500 	.get_fmt = v4l2_subdev_get_fmt,
1501 	.set_fmt = ov8858_set_fmt,
1502 };
1503 
1504 static const struct v4l2_subdev_core_ops ov8858_core_ops = {
1505 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1506 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
1507 };
1508 
1509 static const struct v4l2_subdev_ops ov8858_subdev_ops = {
1510 	.core	= &ov8858_core_ops,
1511 	.video	= &ov8858_video_ops,
1512 	.pad	= &ov8858_pad_ops,
1513 };
1514 
1515 /* ----------------------------------------------------------------------------
1516  * Controls handling
1517  */
1518 
1519 static int ov8858_enable_test_pattern(struct ov8858 *ov8858, u32 pattern)
1520 {
1521 	u32 val;
1522 
1523 	if (pattern)
1524 		val = (pattern - 1) | OV8858_TEST_PATTERN_ENABLE;
1525 	else
1526 		val = OV8858_TEST_PATTERN_DISABLE;
1527 
1528 	return ov8858_write(ov8858, OV8858_REG_TEST_PATTERN, val, NULL);
1529 }
1530 
1531 static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl)
1532 {
1533 	struct ov8858 *ov8858 = container_of(ctrl->handler,
1534 					     struct ov8858, ctrl_handler);
1535 
1536 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1537 	struct v4l2_mbus_framefmt *format;
1538 	struct v4l2_subdev_state *state;
1539 	u16 digi_gain;
1540 	s64 max_exp;
1541 	int ret;
1542 
1543 	/*
1544 	 * The control handler and the subdev state use the same mutex and the
1545 	 * mutex is guaranteed to be locked:
1546 	 * - by the core when s_ctrl is called int the VIDIOC_S_CTRL call path
1547 	 * - by the driver when s_ctrl is called in the s_stream(1) call path
1548 	 */
1549 	state = v4l2_subdev_get_locked_active_state(&ov8858->subdev);
1550 	format = v4l2_subdev_get_pad_format(&ov8858->subdev, state, 0);
1551 
1552 	/* Propagate change of current control to all related controls */
1553 	switch (ctrl->id) {
1554 	case V4L2_CID_VBLANK:
1555 		/* Update max exposure while meeting expected vblanking */
1556 		max_exp = format->height + ctrl->val - OV8858_EXPOSURE_MARGIN;
1557 		__v4l2_ctrl_modify_range(ov8858->exposure,
1558 					 ov8858->exposure->minimum, max_exp,
1559 					 ov8858->exposure->step,
1560 					 ov8858->exposure->default_value);
1561 		break;
1562 	}
1563 
1564 	if (!pm_runtime_get_if_in_use(&client->dev))
1565 		return 0;
1566 
1567 	switch (ctrl->id) {
1568 	case V4L2_CID_EXPOSURE:
1569 		/* 4 least significant bits of exposure are fractional part */
1570 		ret = ov8858_write(ov8858, OV8858_REG_LONG_EXPO,
1571 				   ctrl->val << 4, NULL);
1572 		break;
1573 	case V4L2_CID_ANALOGUE_GAIN:
1574 		ret = ov8858_write(ov8858, OV8858_REG_LONG_GAIN,
1575 				   ctrl->val, NULL);
1576 		break;
1577 	case V4L2_CID_DIGITAL_GAIN:
1578 		/*
1579 		 * Digital gain is assembled as:
1580 		 * 0x350a[7:0] = dgain[13:6]
1581 		 * 0x350b[5:0] = dgain[5:0]
1582 		 * Reassemble the control value to write it in one go.
1583 		 */
1584 		digi_gain = (ctrl->val & OV8858_LONG_DIGIGAIN_L_MASK)
1585 			  | ((ctrl->val & OV8858_LONG_DIGIGAIN_H_MASK) <<
1586 			      OV8858_LONG_DIGIGAIN_H_SHIFT);
1587 		ret = ov8858_write(ov8858, OV8858_REG_LONG_DIGIGAIN,
1588 				   digi_gain, NULL);
1589 		break;
1590 	case V4L2_CID_VBLANK:
1591 		ret = ov8858_write(ov8858, OV8858_REG_VTS,
1592 				   ctrl->val + format->height, NULL);
1593 		break;
1594 	case V4L2_CID_TEST_PATTERN:
1595 		ret = ov8858_enable_test_pattern(ov8858, ctrl->val);
1596 		break;
1597 	default:
1598 		ret = -EINVAL;
1599 		dev_warn(&client->dev, "%s Unhandled id: 0x%x\n",
1600 			 __func__, ctrl->id);
1601 		break;
1602 	}
1603 
1604 	pm_runtime_put(&client->dev);
1605 
1606 	return ret;
1607 }
1608 
1609 static const struct v4l2_ctrl_ops ov8858_ctrl_ops = {
1610 	.s_ctrl = ov8858_set_ctrl,
1611 };
1612 
1613 /* ----------------------------------------------------------------------------
1614  * Power Management
1615  */
1616 
1617 static int ov8858_power_on(struct ov8858 *ov8858)
1618 {
1619 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1620 	struct device *dev = &client->dev;
1621 	unsigned long delay_us;
1622 	int ret;
1623 
1624 	if (clk_get_rate(ov8858->xvclk) != OV8858_XVCLK_FREQ)
1625 		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
1626 
1627 	ret = clk_prepare_enable(ov8858->xvclk);
1628 	if (ret < 0) {
1629 		dev_err(dev, "Failed to enable xvclk\n");
1630 		return ret;
1631 	}
1632 
1633 	ret = regulator_bulk_enable(ARRAY_SIZE(ov8858_supply_names),
1634 				    ov8858->supplies);
1635 	if (ret < 0) {
1636 		dev_err(dev, "Failed to enable regulators\n");
1637 		goto disable_clk;
1638 	}
1639 
1640 	/*
1641 	 * The chip manual only suggests 8192 cycles prior to first SCCB
1642 	 * transaction, but a double sleep between the release of gpios
1643 	 * helps with sporadic failures observed at probe time.
1644 	 */
1645 	delay_us = DIV_ROUND_UP(8192, OV8858_XVCLK_FREQ / 1000 / 1000);
1646 
1647 	gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
1648 	fsleep(delay_us);
1649 	gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0);
1650 	fsleep(delay_us);
1651 
1652 	return 0;
1653 
1654 disable_clk:
1655 	clk_disable_unprepare(ov8858->xvclk);
1656 
1657 	return ret;
1658 }
1659 
1660 static void ov8858_power_off(struct ov8858 *ov8858)
1661 {
1662 	gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1);
1663 	clk_disable_unprepare(ov8858->xvclk);
1664 	gpiod_set_value_cansleep(ov8858->reset_gpio, 1);
1665 
1666 	regulator_bulk_disable(ARRAY_SIZE(ov8858_supply_names),
1667 			       ov8858->supplies);
1668 }
1669 
1670 static int ov8858_runtime_resume(struct device *dev)
1671 {
1672 	struct i2c_client *client = to_i2c_client(dev);
1673 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1674 	struct ov8858 *ov8858 = sd_to_ov8858(sd);
1675 
1676 	return ov8858_power_on(ov8858);
1677 }
1678 
1679 static int ov8858_runtime_suspend(struct device *dev)
1680 {
1681 	struct i2c_client *client = to_i2c_client(dev);
1682 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1683 	struct ov8858 *ov8858 = sd_to_ov8858(sd);
1684 
1685 	ov8858_power_off(ov8858);
1686 
1687 	return 0;
1688 }
1689 
1690 static const struct dev_pm_ops ov8858_pm_ops = {
1691 	SET_RUNTIME_PM_OPS(ov8858_runtime_suspend,
1692 			   ov8858_runtime_resume, NULL)
1693 };
1694 
1695 /* ----------------------------------------------------------------------------
1696  * Probe and initialization
1697  */
1698 
1699 static int ov8858_init_ctrls(struct ov8858 *ov8858)
1700 {
1701 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1702 	struct v4l2_ctrl_handler *handler = &ov8858->ctrl_handler;
1703 	const struct ov8858_mode *mode = &ov8858_modes[0];
1704 	struct v4l2_fwnode_device_properties props;
1705 	s64 exposure_max, vblank_def;
1706 	unsigned int pixel_rate;
1707 	struct v4l2_ctrl *ctrl;
1708 	u32 h_blank;
1709 	int ret;
1710 
1711 	ret = v4l2_ctrl_handler_init(handler, 10);
1712 	if (ret)
1713 		return ret;
1714 
1715 	ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
1716 				      0, 0, link_freq_menu_items);
1717 	if (ctrl)
1718 		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1719 
1720 	/* pixel rate = link frequency * 2 * lanes / bpp */
1721 	pixel_rate = OV8858_LINK_FREQ * 2 * ov8858->num_lanes / 10;
1722 	v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
1723 			  0, pixel_rate, 1, pixel_rate);
1724 
1725 	h_blank = mode->hts_def - mode->width;
1726 	ov8858->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1727 					   h_blank, h_blank, 1, h_blank);
1728 	if (ov8858->hblank)
1729 		ov8858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1730 
1731 	vblank_def = mode->vts_def - mode->height;
1732 	ov8858->vblank = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
1733 					   V4L2_CID_VBLANK, vblank_def,
1734 					   OV8858_VTS_MAX - mode->height,
1735 					   1, vblank_def);
1736 
1737 	exposure_max = mode->vts_def - OV8858_EXPOSURE_MARGIN;
1738 	ov8858->exposure = v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops,
1739 					     V4L2_CID_EXPOSURE,
1740 					     OV8858_EXPOSURE_MIN,
1741 					     exposure_max, OV8858_EXPOSURE_STEP,
1742 					     mode->exp_def);
1743 
1744 	v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1745 			  OV8858_LONG_GAIN_MIN, OV8858_LONG_GAIN_MAX,
1746 			  OV8858_LONG_GAIN_STEP, OV8858_LONG_GAIN_DEFAULT);
1747 
1748 	v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1749 			  OV8858_LONG_DIGIGAIN_MIN, OV8858_LONG_DIGIGAIN_MAX,
1750 			  OV8858_LONG_DIGIGAIN_STEP,
1751 			  OV8858_LONG_DIGIGAIN_DEFAULT);
1752 
1753 	v4l2_ctrl_new_std_menu_items(handler, &ov8858_ctrl_ops,
1754 				     V4L2_CID_TEST_PATTERN,
1755 				     ARRAY_SIZE(ov8858_test_pattern_menu) - 1,
1756 				     0, 0, ov8858_test_pattern_menu);
1757 
1758 	if (handler->error) {
1759 		ret = handler->error;
1760 		goto err_free_handler;
1761 	}
1762 
1763 	ret = v4l2_fwnode_device_parse(&client->dev, &props);
1764 	if (ret)
1765 		goto err_free_handler;
1766 
1767 	ret = v4l2_ctrl_new_fwnode_properties(handler, &ov8858_ctrl_ops,
1768 					      &props);
1769 	if (ret)
1770 		goto err_free_handler;
1771 
1772 	ov8858->subdev.ctrl_handler = handler;
1773 
1774 	return 0;
1775 
1776 err_free_handler:
1777 	dev_err(&client->dev, "Failed to init controls: %d\n", ret);
1778 	v4l2_ctrl_handler_free(handler);
1779 
1780 	return ret;
1781 }
1782 
1783 static int ov8858_check_sensor_id(struct ov8858 *ov8858)
1784 {
1785 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1786 	u32 id = 0;
1787 	int ret;
1788 
1789 	ret = ov8858_read(ov8858, OV8858_REG_CHIP_ID, &id);
1790 	if (ret)
1791 		return ret;
1792 
1793 	if (id != OV8858_CHIP_ID) {
1794 		dev_err(&client->dev, "Unexpected sensor id 0x%x\n", id);
1795 		return -ENODEV;
1796 	}
1797 
1798 	ret = ov8858_read(ov8858, OV8858_REG_SUB_ID, &id);
1799 	if (ret)
1800 		return ret;
1801 
1802 	dev_info(&client->dev, "Detected OV8858 sensor, revision 0x%x\n", id);
1803 
1804 	if (id == OV8858_R2A) {
1805 		/* R2A supports 2 and 4 lanes modes. */
1806 		ov8858->global_regs = ov8858->num_lanes == 4
1807 				    ? ov8858_global_regs_r2a_4lane
1808 				    : ov8858_global_regs_r2a_2lane;
1809 	} else if (ov8858->num_lanes == 2) {
1810 		/*
1811 		 * R1A only supports 2 lanes mode and it's only partially
1812 		 * supported.
1813 		 */
1814 		ov8858->global_regs = ov8858_global_regs_r1a;
1815 		dev_warn(&client->dev, "R1A may not work well!\n");
1816 	} else {
1817 		dev_err(&client->dev,
1818 			"Unsupported number of data lanes for R1A revision.\n");
1819 		return -EINVAL;
1820 	}
1821 
1822 	return 0;
1823 }
1824 
1825 static int ov8858_configure_regulators(struct ov8858 *ov8858)
1826 {
1827 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1828 	unsigned int i;
1829 
1830 	for (i = 0; i < ARRAY_SIZE(ov8858_supply_names); i++)
1831 		ov8858->supplies[i].supply = ov8858_supply_names[i];
1832 
1833 	return devm_regulator_bulk_get(&client->dev,
1834 				       ARRAY_SIZE(ov8858_supply_names),
1835 				       ov8858->supplies);
1836 }
1837 
1838 static int ov8858_parse_of(struct ov8858 *ov8858)
1839 {
1840 	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
1841 	struct i2c_client *client = v4l2_get_subdevdata(&ov8858->subdev);
1842 	struct device *dev = &client->dev;
1843 	struct fwnode_handle *endpoint;
1844 	int ret;
1845 
1846 	endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
1847 	if (!endpoint) {
1848 		dev_err(dev, "Failed to get endpoint\n");
1849 		return -EINVAL;
1850 	}
1851 
1852 	ret = v4l2_fwnode_endpoint_parse(endpoint, &vep);
1853 	if (ret) {
1854 		dev_err(dev, "Failed to parse endpoint: %d\n", ret);
1855 		fwnode_handle_put(endpoint);
1856 		return ret;
1857 	}
1858 
1859 	ov8858->num_lanes = vep.bus.mipi_csi2.num_data_lanes;
1860 	switch (ov8858->num_lanes) {
1861 	case 4:
1862 	case 2:
1863 		break;
1864 	default:
1865 		dev_err(dev, "Unsupported number of data lanes %u\n",
1866 			ov8858->num_lanes);
1867 		fwnode_handle_put(endpoint);
1868 		return -EINVAL;
1869 	}
1870 
1871 	ov8858->subdev.fwnode = endpoint;
1872 
1873 	return 0;
1874 }
1875 
1876 static int ov8858_probe(struct i2c_client *client)
1877 {
1878 	struct device *dev = &client->dev;
1879 	struct v4l2_subdev *sd;
1880 	struct ov8858 *ov8858;
1881 	int ret;
1882 
1883 	ov8858 = devm_kzalloc(dev, sizeof(*ov8858), GFP_KERNEL);
1884 	if (!ov8858)
1885 		return -ENOMEM;
1886 
1887 	ov8858->xvclk = devm_clk_get(dev, "xvclk");
1888 	if (IS_ERR(ov8858->xvclk))
1889 		return dev_err_probe(dev, PTR_ERR(ov8858->xvclk),
1890 				     "Failed to get xvclk\n");
1891 
1892 	ov8858->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1893 						     GPIOD_OUT_HIGH);
1894 	if (IS_ERR(ov8858->reset_gpio))
1895 		return dev_err_probe(dev, PTR_ERR(ov8858->reset_gpio),
1896 				     "Failed to get reset gpio\n");
1897 
1898 	ov8858->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
1899 						    GPIOD_OUT_HIGH);
1900 	if (IS_ERR(ov8858->pwdn_gpio))
1901 		return dev_err_probe(dev, PTR_ERR(ov8858->pwdn_gpio),
1902 				     "Failed to get powerdown gpio\n");
1903 
1904 	v4l2_i2c_subdev_init(&ov8858->subdev, client, &ov8858_subdev_ops);
1905 
1906 	ret = ov8858_configure_regulators(ov8858);
1907 	if (ret)
1908 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
1909 
1910 	ret = ov8858_parse_of(ov8858);
1911 	if (ret)
1912 		return ret;
1913 
1914 	ret = ov8858_init_ctrls(ov8858);
1915 	if (ret)
1916 		goto err_put_fwnode;
1917 
1918 	sd = &ov8858->subdev;
1919 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1920 	ov8858->pad.flags = MEDIA_PAD_FL_SOURCE;
1921 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1922 	ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad);
1923 	if (ret < 0)
1924 		goto err_free_handler;
1925 
1926 	sd->state_lock = ov8858->ctrl_handler.lock;
1927 	ret = v4l2_subdev_init_finalize(sd);
1928 	if (ret < 0) {
1929 		dev_err(&client->dev, "Subdev initialization error %d\n", ret);
1930 		goto err_clean_entity;
1931 	}
1932 
1933 	ret = ov8858_power_on(ov8858);
1934 	if (ret)
1935 		goto err_clean_entity;
1936 
1937 	pm_runtime_set_active(dev);
1938 	pm_runtime_get_noresume(dev);
1939 	pm_runtime_enable(dev);
1940 
1941 	ret = ov8858_check_sensor_id(ov8858);
1942 	if (ret)
1943 		goto err_power_off;
1944 
1945 	pm_runtime_set_autosuspend_delay(dev, 1000);
1946 	pm_runtime_use_autosuspend(dev);
1947 
1948 	ret = v4l2_async_register_subdev_sensor(sd);
1949 	if (ret) {
1950 		dev_err(dev, "v4l2 async register subdev failed\n");
1951 		goto err_power_off;
1952 	}
1953 
1954 	pm_runtime_mark_last_busy(dev);
1955 	pm_runtime_put_autosuspend(dev);
1956 
1957 	return 0;
1958 
1959 err_power_off:
1960 	pm_runtime_disable(dev);
1961 	pm_runtime_put_noidle(dev);
1962 	ov8858_power_off(ov8858);
1963 err_clean_entity:
1964 	media_entity_cleanup(&sd->entity);
1965 err_free_handler:
1966 	v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
1967 err_put_fwnode:
1968 	fwnode_handle_put(ov8858->subdev.fwnode);
1969 
1970 	return ret;
1971 }
1972 
1973 static void ov8858_remove(struct i2c_client *client)
1974 {
1975 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1976 	struct ov8858 *ov8858 = sd_to_ov8858(sd);
1977 
1978 	v4l2_async_unregister_subdev(sd);
1979 	media_entity_cleanup(&sd->entity);
1980 	v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
1981 	fwnode_handle_put(ov8858->subdev.fwnode);
1982 
1983 	pm_runtime_disable(&client->dev);
1984 	if (!pm_runtime_status_suspended(&client->dev))
1985 		ov8858_power_off(ov8858);
1986 	pm_runtime_set_suspended(&client->dev);
1987 }
1988 
1989 static const struct of_device_id ov8858_of_match[] = {
1990 	{ .compatible = "ovti,ov8858" },
1991 	{ /* sentinel */ },
1992 };
1993 MODULE_DEVICE_TABLE(of, ov8858_of_match);
1994 
1995 static struct i2c_driver ov8858_i2c_driver = {
1996 	.driver = {
1997 		.name = "ov8858",
1998 		.pm = &ov8858_pm_ops,
1999 		.of_match_table = ov8858_of_match,
2000 	},
2001 	.probe_new	= &ov8858_probe,
2002 	.remove		= &ov8858_remove,
2003 };
2004 
2005 module_i2c_driver(ov8858_i2c_driver);
2006 
2007 MODULE_DESCRIPTION("OmniVision OV8858 sensor driver");
2008 MODULE_LICENSE("GPL");
2009