xref: /openbmc/linux/drivers/media/i2c/ov13858.c (revision 5fcf092e0c9fb4895096c8809cf1fb9ba1349653)
1*5fcf092eSHyungwoo Yang /*
2*5fcf092eSHyungwoo Yang  * Copyright (c) 2017 Intel Corporation.
3*5fcf092eSHyungwoo Yang  *
4*5fcf092eSHyungwoo Yang  * This program is free software; you can redistribute it and/or
5*5fcf092eSHyungwoo Yang  * modify it under the terms of the GNU General Public License version
6*5fcf092eSHyungwoo Yang  * 2 as published by the Free Software Foundation.
7*5fcf092eSHyungwoo Yang  *
8*5fcf092eSHyungwoo Yang  * This program is distributed in the hope that it will be useful,
9*5fcf092eSHyungwoo Yang  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10*5fcf092eSHyungwoo Yang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11*5fcf092eSHyungwoo Yang  * GNU General Public License for more details.
12*5fcf092eSHyungwoo Yang  *
13*5fcf092eSHyungwoo Yang  */
14*5fcf092eSHyungwoo Yang 
15*5fcf092eSHyungwoo Yang #include <linux/acpi.h>
16*5fcf092eSHyungwoo Yang #include <linux/i2c.h>
17*5fcf092eSHyungwoo Yang #include <linux/module.h>
18*5fcf092eSHyungwoo Yang #include <linux/pm_runtime.h>
19*5fcf092eSHyungwoo Yang #include <media/v4l2-ctrls.h>
20*5fcf092eSHyungwoo Yang #include <media/v4l2-device.h>
21*5fcf092eSHyungwoo Yang 
22*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_08BIT		1
23*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_16BIT		2
24*5fcf092eSHyungwoo Yang #define OV13858_REG_VALUE_24BIT		3
25*5fcf092eSHyungwoo Yang 
26*5fcf092eSHyungwoo Yang #define OV13858_REG_MODE_SELECT		0x0100
27*5fcf092eSHyungwoo Yang #define OV13858_MODE_STANDBY		0x00
28*5fcf092eSHyungwoo Yang #define OV13858_MODE_STREAMING		0x01
29*5fcf092eSHyungwoo Yang 
30*5fcf092eSHyungwoo Yang #define OV13858_REG_SOFTWARE_RST	0x0103
31*5fcf092eSHyungwoo Yang #define OV13858_SOFTWARE_RST		0x01
32*5fcf092eSHyungwoo Yang 
33*5fcf092eSHyungwoo Yang /* PLL1 generates PCLK and MIPI_PHY_CLK */
34*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_0		0x0300
35*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_1		0x0301
36*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_2		0x0302
37*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_3		0x0303
38*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_4		0x0304
39*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL1_CTRL_5		0x0305
40*5fcf092eSHyungwoo Yang 
41*5fcf092eSHyungwoo Yang /* PLL2 generates DAC_CLK, SCLK and SRAM_CLK */
42*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_B		0x030b
43*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_C		0x030c
44*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_D		0x030d
45*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_E		0x030e
46*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_F		0x030f
47*5fcf092eSHyungwoo Yang #define OV13858_REG_PLL2_CTRL_12	0x0312
48*5fcf092eSHyungwoo Yang #define OV13858_REG_MIPI_SC_CTRL0	0x3016
49*5fcf092eSHyungwoo Yang #define OV13858_REG_MIPI_SC_CTRL1	0x3022
50*5fcf092eSHyungwoo Yang 
51*5fcf092eSHyungwoo Yang /* Chip ID */
52*5fcf092eSHyungwoo Yang #define OV13858_REG_CHIP_ID		0x300a
53*5fcf092eSHyungwoo Yang #define OV13858_CHIP_ID			0x00d855
54*5fcf092eSHyungwoo Yang 
55*5fcf092eSHyungwoo Yang /* V_TIMING internal */
56*5fcf092eSHyungwoo Yang #define OV13858_REG_VTS			0x380e
57*5fcf092eSHyungwoo Yang #define OV13858_VTS_30FPS		0x0c8e /* 30 fps */
58*5fcf092eSHyungwoo Yang #define OV13858_VTS_60FPS		0x0648 /* 60 fps */
59*5fcf092eSHyungwoo Yang #define OV13858_VTS_MAX			0x7fff
60*5fcf092eSHyungwoo Yang #define OV13858_VBLANK_MIN		56
61*5fcf092eSHyungwoo Yang 
62*5fcf092eSHyungwoo Yang /* HBLANK control - read only */
63*5fcf092eSHyungwoo Yang #define OV13858_PPL_540MHZ		2244
64*5fcf092eSHyungwoo Yang #define OV13858_PPL_1080MHZ		4488
65*5fcf092eSHyungwoo Yang 
66*5fcf092eSHyungwoo Yang /* Exposure control */
67*5fcf092eSHyungwoo Yang #define OV13858_REG_EXPOSURE		0x3500
68*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_MIN		4
69*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_MAX		(OV13858_VTS_MAX - 8)
70*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_STEP		1
71*5fcf092eSHyungwoo Yang #define OV13858_EXPOSURE_DEFAULT	0x640
72*5fcf092eSHyungwoo Yang 
73*5fcf092eSHyungwoo Yang /* Analog gain control */
74*5fcf092eSHyungwoo Yang #define OV13858_REG_ANALOG_GAIN		0x3508
75*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_MIN		0
76*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_MAX		0x1fff
77*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_STEP		1
78*5fcf092eSHyungwoo Yang #define OV13858_ANA_GAIN_DEFAULT	0x80
79*5fcf092eSHyungwoo Yang 
80*5fcf092eSHyungwoo Yang /* Digital gain control */
81*5fcf092eSHyungwoo Yang #define OV13858_REG_DIGITAL_GAIN	0x350a
82*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MASK		0xf3
83*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_SHIFT		2
84*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MIN		1
85*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_MAX		4
86*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_STEP		1
87*5fcf092eSHyungwoo Yang #define OV13858_DGTL_GAIN_DEFAULT	1
88*5fcf092eSHyungwoo Yang 
89*5fcf092eSHyungwoo Yang /* Test Pattern Control */
90*5fcf092eSHyungwoo Yang #define OV13858_REG_TEST_PATTERN	0x4503
91*5fcf092eSHyungwoo Yang #define OV13858_TEST_PATTERN_ENABLE	BIT(7)
92*5fcf092eSHyungwoo Yang #define OV13858_TEST_PATTERN_MASK	0xfc
93*5fcf092eSHyungwoo Yang 
94*5fcf092eSHyungwoo Yang /* Number of frames to skip */
95*5fcf092eSHyungwoo Yang #define OV13858_NUM_OF_SKIP_FRAMES	2
96*5fcf092eSHyungwoo Yang 
97*5fcf092eSHyungwoo Yang struct ov13858_reg {
98*5fcf092eSHyungwoo Yang 	u16 address;
99*5fcf092eSHyungwoo Yang 	u8 val;
100*5fcf092eSHyungwoo Yang };
101*5fcf092eSHyungwoo Yang 
102*5fcf092eSHyungwoo Yang struct ov13858_reg_list {
103*5fcf092eSHyungwoo Yang 	u32 num_of_regs;
104*5fcf092eSHyungwoo Yang 	const struct ov13858_reg *regs;
105*5fcf092eSHyungwoo Yang };
106*5fcf092eSHyungwoo Yang 
107*5fcf092eSHyungwoo Yang /* Link frequency config */
108*5fcf092eSHyungwoo Yang struct ov13858_link_freq_config {
109*5fcf092eSHyungwoo Yang 	u32 pixel_rate;
110*5fcf092eSHyungwoo Yang 	u32 pixels_per_line;
111*5fcf092eSHyungwoo Yang 
112*5fcf092eSHyungwoo Yang 	/* PLL registers for this link frequency */
113*5fcf092eSHyungwoo Yang 	struct ov13858_reg_list reg_list;
114*5fcf092eSHyungwoo Yang };
115*5fcf092eSHyungwoo Yang 
116*5fcf092eSHyungwoo Yang /* Mode : resolution and related config&values */
117*5fcf092eSHyungwoo Yang struct ov13858_mode {
118*5fcf092eSHyungwoo Yang 	/* Frame width */
119*5fcf092eSHyungwoo Yang 	u32 width;
120*5fcf092eSHyungwoo Yang 	/* Frame height */
121*5fcf092eSHyungwoo Yang 	u32 height;
122*5fcf092eSHyungwoo Yang 
123*5fcf092eSHyungwoo Yang 	/* V-timing */
124*5fcf092eSHyungwoo Yang 	u32 vts;
125*5fcf092eSHyungwoo Yang 
126*5fcf092eSHyungwoo Yang 	/* Index of Link frequency config to be used */
127*5fcf092eSHyungwoo Yang 	u32 link_freq_index;
128*5fcf092eSHyungwoo Yang 	/* Default register values */
129*5fcf092eSHyungwoo Yang 	struct ov13858_reg_list reg_list;
130*5fcf092eSHyungwoo Yang };
131*5fcf092eSHyungwoo Yang 
132*5fcf092eSHyungwoo Yang /* 4224x3136 needs 1080Mbps/lane, 4 lanes */
133*5fcf092eSHyungwoo Yang static const struct ov13858_reg mipi_data_rate_1080mbps[] = {
134*5fcf092eSHyungwoo Yang 	/* PLL1 registers */
135*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_0, 0x07},
136*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_1, 0x01},
137*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_2, 0xc2},
138*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_3, 0x00},
139*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_4, 0x00},
140*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_5, 0x01},
141*5fcf092eSHyungwoo Yang 
142*5fcf092eSHyungwoo Yang 	/* PLL2 registers */
143*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_B, 0x05},
144*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_C, 0x01},
145*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_D, 0x0e},
146*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_E, 0x05},
147*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_F, 0x01},
148*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_12, 0x01},
149*5fcf092eSHyungwoo Yang 	{OV13858_REG_MIPI_SC_CTRL0, 0x72},
150*5fcf092eSHyungwoo Yang 	{OV13858_REG_MIPI_SC_CTRL1, 0x01},
151*5fcf092eSHyungwoo Yang };
152*5fcf092eSHyungwoo Yang 
153*5fcf092eSHyungwoo Yang /*
154*5fcf092eSHyungwoo Yang  * 2112x1568, 2112x1188, 1056x784 need 540Mbps/lane,
155*5fcf092eSHyungwoo Yang  * 4 lanes
156*5fcf092eSHyungwoo Yang  */
157*5fcf092eSHyungwoo Yang static const struct ov13858_reg mipi_data_rate_540mbps[] = {
158*5fcf092eSHyungwoo Yang 	/* PLL1 registers */
159*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_0, 0x07},
160*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_1, 0x01},
161*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_2, 0xc2},
162*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_3, 0x01},
163*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_4, 0x00},
164*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL1_CTRL_5, 0x01},
165*5fcf092eSHyungwoo Yang 
166*5fcf092eSHyungwoo Yang 	/* PLL2 registers */
167*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_B, 0x05},
168*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_C, 0x01},
169*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_D, 0x0e},
170*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_E, 0x05},
171*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_F, 0x01},
172*5fcf092eSHyungwoo Yang 	{OV13858_REG_PLL2_CTRL_12, 0x01},
173*5fcf092eSHyungwoo Yang 	{OV13858_REG_MIPI_SC_CTRL0, 0x72},
174*5fcf092eSHyungwoo Yang 	{OV13858_REG_MIPI_SC_CTRL1, 0x01},
175*5fcf092eSHyungwoo Yang };
176*5fcf092eSHyungwoo Yang 
177*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_4224x3136_regs[] = {
178*5fcf092eSHyungwoo Yang 	{0x3013, 0x32},
179*5fcf092eSHyungwoo Yang 	{0x301b, 0xf0},
180*5fcf092eSHyungwoo Yang 	{0x301f, 0xd0},
181*5fcf092eSHyungwoo Yang 	{0x3106, 0x15},
182*5fcf092eSHyungwoo Yang 	{0x3107, 0x23},
183*5fcf092eSHyungwoo Yang 	{0x350a, 0x00},
184*5fcf092eSHyungwoo Yang 	{0x350e, 0x00},
185*5fcf092eSHyungwoo Yang 	{0x3510, 0x00},
186*5fcf092eSHyungwoo Yang 	{0x3511, 0x02},
187*5fcf092eSHyungwoo Yang 	{0x3512, 0x00},
188*5fcf092eSHyungwoo Yang 	{0x3600, 0x2b},
189*5fcf092eSHyungwoo Yang 	{0x3601, 0x52},
190*5fcf092eSHyungwoo Yang 	{0x3602, 0x60},
191*5fcf092eSHyungwoo Yang 	{0x3612, 0x05},
192*5fcf092eSHyungwoo Yang 	{0x3613, 0xa4},
193*5fcf092eSHyungwoo Yang 	{0x3620, 0x80},
194*5fcf092eSHyungwoo Yang 	{0x3621, 0x10},
195*5fcf092eSHyungwoo Yang 	{0x3622, 0x30},
196*5fcf092eSHyungwoo Yang 	{0x3624, 0x1c},
197*5fcf092eSHyungwoo Yang 	{0x3640, 0x10},
198*5fcf092eSHyungwoo Yang 	{0x3641, 0x70},
199*5fcf092eSHyungwoo Yang 	{0x3661, 0x80},
200*5fcf092eSHyungwoo Yang 	{0x3662, 0x12},
201*5fcf092eSHyungwoo Yang 	{0x3664, 0x73},
202*5fcf092eSHyungwoo Yang 	{0x3665, 0xa7},
203*5fcf092eSHyungwoo Yang 	{0x366e, 0xff},
204*5fcf092eSHyungwoo Yang 	{0x366f, 0xf4},
205*5fcf092eSHyungwoo Yang 	{0x3674, 0x00},
206*5fcf092eSHyungwoo Yang 	{0x3679, 0x0c},
207*5fcf092eSHyungwoo Yang 	{0x367f, 0x01},
208*5fcf092eSHyungwoo Yang 	{0x3680, 0x0c},
209*5fcf092eSHyungwoo Yang 	{0x3681, 0x50},
210*5fcf092eSHyungwoo Yang 	{0x3682, 0x50},
211*5fcf092eSHyungwoo Yang 	{0x3683, 0xa9},
212*5fcf092eSHyungwoo Yang 	{0x3684, 0xa9},
213*5fcf092eSHyungwoo Yang 	{0x3709, 0x5f},
214*5fcf092eSHyungwoo Yang 	{0x3714, 0x24},
215*5fcf092eSHyungwoo Yang 	{0x371a, 0x3e},
216*5fcf092eSHyungwoo Yang 	{0x3737, 0x04},
217*5fcf092eSHyungwoo Yang 	{0x3738, 0xcc},
218*5fcf092eSHyungwoo Yang 	{0x3739, 0x12},
219*5fcf092eSHyungwoo Yang 	{0x373d, 0x26},
220*5fcf092eSHyungwoo Yang 	{0x3764, 0x20},
221*5fcf092eSHyungwoo Yang 	{0x3765, 0x20},
222*5fcf092eSHyungwoo Yang 	{0x37a1, 0x36},
223*5fcf092eSHyungwoo Yang 	{0x37a8, 0x3b},
224*5fcf092eSHyungwoo Yang 	{0x37ab, 0x31},
225*5fcf092eSHyungwoo Yang 	{0x37c2, 0x04},
226*5fcf092eSHyungwoo Yang 	{0x37c3, 0xf1},
227*5fcf092eSHyungwoo Yang 	{0x37c5, 0x00},
228*5fcf092eSHyungwoo Yang 	{0x37d8, 0x03},
229*5fcf092eSHyungwoo Yang 	{0x37d9, 0x0c},
230*5fcf092eSHyungwoo Yang 	{0x37da, 0xc2},
231*5fcf092eSHyungwoo Yang 	{0x37dc, 0x02},
232*5fcf092eSHyungwoo Yang 	{0x37e0, 0x00},
233*5fcf092eSHyungwoo Yang 	{0x37e1, 0x0a},
234*5fcf092eSHyungwoo Yang 	{0x37e2, 0x14},
235*5fcf092eSHyungwoo Yang 	{0x37e3, 0x04},
236*5fcf092eSHyungwoo Yang 	{0x37e4, 0x2a},
237*5fcf092eSHyungwoo Yang 	{0x37e5, 0x03},
238*5fcf092eSHyungwoo Yang 	{0x37e6, 0x04},
239*5fcf092eSHyungwoo Yang 	{0x3800, 0x00},
240*5fcf092eSHyungwoo Yang 	{0x3801, 0x00},
241*5fcf092eSHyungwoo Yang 	{0x3802, 0x00},
242*5fcf092eSHyungwoo Yang 	{0x3803, 0x00},
243*5fcf092eSHyungwoo Yang 	{0x3804, 0x10},
244*5fcf092eSHyungwoo Yang 	{0x3805, 0x9f},
245*5fcf092eSHyungwoo Yang 	{0x3806, 0x0c},
246*5fcf092eSHyungwoo Yang 	{0x3807, 0x5f},
247*5fcf092eSHyungwoo Yang 	{0x3808, 0x10},
248*5fcf092eSHyungwoo Yang 	{0x3809, 0x80},
249*5fcf092eSHyungwoo Yang 	{0x380a, 0x0c},
250*5fcf092eSHyungwoo Yang 	{0x380b, 0x40},
251*5fcf092eSHyungwoo Yang 	{0x380c, 0x04},
252*5fcf092eSHyungwoo Yang 	{0x380d, 0x62},
253*5fcf092eSHyungwoo Yang 	{0x380e, 0x0c},
254*5fcf092eSHyungwoo Yang 	{0x380f, 0x8e},
255*5fcf092eSHyungwoo Yang 	{0x3811, 0x04},
256*5fcf092eSHyungwoo Yang 	{0x3813, 0x05},
257*5fcf092eSHyungwoo Yang 	{0x3814, 0x01},
258*5fcf092eSHyungwoo Yang 	{0x3815, 0x01},
259*5fcf092eSHyungwoo Yang 	{0x3816, 0x01},
260*5fcf092eSHyungwoo Yang 	{0x3817, 0x01},
261*5fcf092eSHyungwoo Yang 	{0x3820, 0xa8},
262*5fcf092eSHyungwoo Yang 	{0x3821, 0x00},
263*5fcf092eSHyungwoo Yang 	{0x3822, 0xc2},
264*5fcf092eSHyungwoo Yang 	{0x3823, 0x18},
265*5fcf092eSHyungwoo Yang 	{0x3826, 0x11},
266*5fcf092eSHyungwoo Yang 	{0x3827, 0x1c},
267*5fcf092eSHyungwoo Yang 	{0x3829, 0x03},
268*5fcf092eSHyungwoo Yang 	{0x3832, 0x00},
269*5fcf092eSHyungwoo Yang 	{0x3c80, 0x00},
270*5fcf092eSHyungwoo Yang 	{0x3c87, 0x01},
271*5fcf092eSHyungwoo Yang 	{0x3c8c, 0x19},
272*5fcf092eSHyungwoo Yang 	{0x3c8d, 0x1c},
273*5fcf092eSHyungwoo Yang 	{0x3c90, 0x00},
274*5fcf092eSHyungwoo Yang 	{0x3c91, 0x00},
275*5fcf092eSHyungwoo Yang 	{0x3c92, 0x00},
276*5fcf092eSHyungwoo Yang 	{0x3c93, 0x00},
277*5fcf092eSHyungwoo Yang 	{0x3c94, 0x40},
278*5fcf092eSHyungwoo Yang 	{0x3c95, 0x54},
279*5fcf092eSHyungwoo Yang 	{0x3c96, 0x34},
280*5fcf092eSHyungwoo Yang 	{0x3c97, 0x04},
281*5fcf092eSHyungwoo Yang 	{0x3c98, 0x00},
282*5fcf092eSHyungwoo Yang 	{0x3d8c, 0x73},
283*5fcf092eSHyungwoo Yang 	{0x3d8d, 0xc0},
284*5fcf092eSHyungwoo Yang 	{0x3f00, 0x0b},
285*5fcf092eSHyungwoo Yang 	{0x3f03, 0x00},
286*5fcf092eSHyungwoo Yang 	{0x4001, 0xe0},
287*5fcf092eSHyungwoo Yang 	{0x4008, 0x00},
288*5fcf092eSHyungwoo Yang 	{0x4009, 0x0f},
289*5fcf092eSHyungwoo Yang 	{0x4011, 0xf0},
290*5fcf092eSHyungwoo Yang 	{0x4017, 0x08},
291*5fcf092eSHyungwoo Yang 	{0x4050, 0x04},
292*5fcf092eSHyungwoo Yang 	{0x4051, 0x0b},
293*5fcf092eSHyungwoo Yang 	{0x4052, 0x00},
294*5fcf092eSHyungwoo Yang 	{0x4053, 0x80},
295*5fcf092eSHyungwoo Yang 	{0x4054, 0x00},
296*5fcf092eSHyungwoo Yang 	{0x4055, 0x80},
297*5fcf092eSHyungwoo Yang 	{0x4056, 0x00},
298*5fcf092eSHyungwoo Yang 	{0x4057, 0x80},
299*5fcf092eSHyungwoo Yang 	{0x4058, 0x00},
300*5fcf092eSHyungwoo Yang 	{0x4059, 0x80},
301*5fcf092eSHyungwoo Yang 	{0x405e, 0x20},
302*5fcf092eSHyungwoo Yang 	{0x4500, 0x07},
303*5fcf092eSHyungwoo Yang 	{0x4503, 0x00},
304*5fcf092eSHyungwoo Yang 	{0x450a, 0x04},
305*5fcf092eSHyungwoo Yang 	{0x4809, 0x04},
306*5fcf092eSHyungwoo Yang 	{0x480c, 0x12},
307*5fcf092eSHyungwoo Yang 	{0x481f, 0x30},
308*5fcf092eSHyungwoo Yang 	{0x4833, 0x10},
309*5fcf092eSHyungwoo Yang 	{0x4837, 0x0e},
310*5fcf092eSHyungwoo Yang 	{0x4902, 0x01},
311*5fcf092eSHyungwoo Yang 	{0x4d00, 0x03},
312*5fcf092eSHyungwoo Yang 	{0x4d01, 0xc9},
313*5fcf092eSHyungwoo Yang 	{0x4d02, 0xbc},
314*5fcf092eSHyungwoo Yang 	{0x4d03, 0xd7},
315*5fcf092eSHyungwoo Yang 	{0x4d04, 0xf0},
316*5fcf092eSHyungwoo Yang 	{0x4d05, 0xa2},
317*5fcf092eSHyungwoo Yang 	{0x5000, 0xfd},
318*5fcf092eSHyungwoo Yang 	{0x5001, 0x01},
319*5fcf092eSHyungwoo Yang 	{0x5040, 0x39},
320*5fcf092eSHyungwoo Yang 	{0x5041, 0x10},
321*5fcf092eSHyungwoo Yang 	{0x5042, 0x10},
322*5fcf092eSHyungwoo Yang 	{0x5043, 0x84},
323*5fcf092eSHyungwoo Yang 	{0x5044, 0x62},
324*5fcf092eSHyungwoo Yang 	{0x5180, 0x00},
325*5fcf092eSHyungwoo Yang 	{0x5181, 0x10},
326*5fcf092eSHyungwoo Yang 	{0x5182, 0x02},
327*5fcf092eSHyungwoo Yang 	{0x5183, 0x0f},
328*5fcf092eSHyungwoo Yang 	{0x5200, 0x1b},
329*5fcf092eSHyungwoo Yang 	{0x520b, 0x07},
330*5fcf092eSHyungwoo Yang 	{0x520c, 0x0f},
331*5fcf092eSHyungwoo Yang 	{0x5300, 0x04},
332*5fcf092eSHyungwoo Yang 	{0x5301, 0x0c},
333*5fcf092eSHyungwoo Yang 	{0x5302, 0x0c},
334*5fcf092eSHyungwoo Yang 	{0x5303, 0x0f},
335*5fcf092eSHyungwoo Yang 	{0x5304, 0x00},
336*5fcf092eSHyungwoo Yang 	{0x5305, 0x70},
337*5fcf092eSHyungwoo Yang 	{0x5306, 0x00},
338*5fcf092eSHyungwoo Yang 	{0x5307, 0x80},
339*5fcf092eSHyungwoo Yang 	{0x5308, 0x00},
340*5fcf092eSHyungwoo Yang 	{0x5309, 0xa5},
341*5fcf092eSHyungwoo Yang 	{0x530a, 0x00},
342*5fcf092eSHyungwoo Yang 	{0x530b, 0xd3},
343*5fcf092eSHyungwoo Yang 	{0x530c, 0x00},
344*5fcf092eSHyungwoo Yang 	{0x530d, 0xf0},
345*5fcf092eSHyungwoo Yang 	{0x530e, 0x01},
346*5fcf092eSHyungwoo Yang 	{0x530f, 0x10},
347*5fcf092eSHyungwoo Yang 	{0x5310, 0x01},
348*5fcf092eSHyungwoo Yang 	{0x5311, 0x20},
349*5fcf092eSHyungwoo Yang 	{0x5312, 0x01},
350*5fcf092eSHyungwoo Yang 	{0x5313, 0x20},
351*5fcf092eSHyungwoo Yang 	{0x5314, 0x01},
352*5fcf092eSHyungwoo Yang 	{0x5315, 0x20},
353*5fcf092eSHyungwoo Yang 	{0x5316, 0x08},
354*5fcf092eSHyungwoo Yang 	{0x5317, 0x08},
355*5fcf092eSHyungwoo Yang 	{0x5318, 0x10},
356*5fcf092eSHyungwoo Yang 	{0x5319, 0x88},
357*5fcf092eSHyungwoo Yang 	{0x531a, 0x88},
358*5fcf092eSHyungwoo Yang 	{0x531b, 0xa9},
359*5fcf092eSHyungwoo Yang 	{0x531c, 0xaa},
360*5fcf092eSHyungwoo Yang 	{0x531d, 0x0a},
361*5fcf092eSHyungwoo Yang 	{0x5405, 0x02},
362*5fcf092eSHyungwoo Yang 	{0x5406, 0x67},
363*5fcf092eSHyungwoo Yang 	{0x5407, 0x01},
364*5fcf092eSHyungwoo Yang 	{0x5408, 0x4a},
365*5fcf092eSHyungwoo Yang };
366*5fcf092eSHyungwoo Yang 
367*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_2112x1568_regs[] = {
368*5fcf092eSHyungwoo Yang 	{0x3013, 0x32},
369*5fcf092eSHyungwoo Yang 	{0x301b, 0xf0},
370*5fcf092eSHyungwoo Yang 	{0x301f, 0xd0},
371*5fcf092eSHyungwoo Yang 	{0x3106, 0x15},
372*5fcf092eSHyungwoo Yang 	{0x3107, 0x23},
373*5fcf092eSHyungwoo Yang 	{0x350a, 0x00},
374*5fcf092eSHyungwoo Yang 	{0x350e, 0x00},
375*5fcf092eSHyungwoo Yang 	{0x3510, 0x00},
376*5fcf092eSHyungwoo Yang 	{0x3511, 0x02},
377*5fcf092eSHyungwoo Yang 	{0x3512, 0x00},
378*5fcf092eSHyungwoo Yang 	{0x3600, 0x2b},
379*5fcf092eSHyungwoo Yang 	{0x3601, 0x52},
380*5fcf092eSHyungwoo Yang 	{0x3602, 0x60},
381*5fcf092eSHyungwoo Yang 	{0x3612, 0x05},
382*5fcf092eSHyungwoo Yang 	{0x3613, 0xa4},
383*5fcf092eSHyungwoo Yang 	{0x3620, 0x80},
384*5fcf092eSHyungwoo Yang 	{0x3621, 0x10},
385*5fcf092eSHyungwoo Yang 	{0x3622, 0x30},
386*5fcf092eSHyungwoo Yang 	{0x3624, 0x1c},
387*5fcf092eSHyungwoo Yang 	{0x3640, 0x10},
388*5fcf092eSHyungwoo Yang 	{0x3641, 0x70},
389*5fcf092eSHyungwoo Yang 	{0x3661, 0x80},
390*5fcf092eSHyungwoo Yang 	{0x3662, 0x10},
391*5fcf092eSHyungwoo Yang 	{0x3664, 0x73},
392*5fcf092eSHyungwoo Yang 	{0x3665, 0xa7},
393*5fcf092eSHyungwoo Yang 	{0x366e, 0xff},
394*5fcf092eSHyungwoo Yang 	{0x366f, 0xf4},
395*5fcf092eSHyungwoo Yang 	{0x3674, 0x00},
396*5fcf092eSHyungwoo Yang 	{0x3679, 0x0c},
397*5fcf092eSHyungwoo Yang 	{0x367f, 0x01},
398*5fcf092eSHyungwoo Yang 	{0x3680, 0x0c},
399*5fcf092eSHyungwoo Yang 	{0x3681, 0x50},
400*5fcf092eSHyungwoo Yang 	{0x3682, 0x50},
401*5fcf092eSHyungwoo Yang 	{0x3683, 0xa9},
402*5fcf092eSHyungwoo Yang 	{0x3684, 0xa9},
403*5fcf092eSHyungwoo Yang 	{0x3709, 0x5f},
404*5fcf092eSHyungwoo Yang 	{0x3714, 0x28},
405*5fcf092eSHyungwoo Yang 	{0x371a, 0x3e},
406*5fcf092eSHyungwoo Yang 	{0x3737, 0x08},
407*5fcf092eSHyungwoo Yang 	{0x3738, 0xcc},
408*5fcf092eSHyungwoo Yang 	{0x3739, 0x20},
409*5fcf092eSHyungwoo Yang 	{0x373d, 0x26},
410*5fcf092eSHyungwoo Yang 	{0x3764, 0x20},
411*5fcf092eSHyungwoo Yang 	{0x3765, 0x20},
412*5fcf092eSHyungwoo Yang 	{0x37a1, 0x36},
413*5fcf092eSHyungwoo Yang 	{0x37a8, 0x3b},
414*5fcf092eSHyungwoo Yang 	{0x37ab, 0x31},
415*5fcf092eSHyungwoo Yang 	{0x37c2, 0x14},
416*5fcf092eSHyungwoo Yang 	{0x37c3, 0xf1},
417*5fcf092eSHyungwoo Yang 	{0x37c5, 0x00},
418*5fcf092eSHyungwoo Yang 	{0x37d8, 0x03},
419*5fcf092eSHyungwoo Yang 	{0x37d9, 0x0c},
420*5fcf092eSHyungwoo Yang 	{0x37da, 0xc2},
421*5fcf092eSHyungwoo Yang 	{0x37dc, 0x02},
422*5fcf092eSHyungwoo Yang 	{0x37e0, 0x00},
423*5fcf092eSHyungwoo Yang 	{0x37e1, 0x0a},
424*5fcf092eSHyungwoo Yang 	{0x37e2, 0x14},
425*5fcf092eSHyungwoo Yang 	{0x37e3, 0x08},
426*5fcf092eSHyungwoo Yang 	{0x37e4, 0x38},
427*5fcf092eSHyungwoo Yang 	{0x37e5, 0x03},
428*5fcf092eSHyungwoo Yang 	{0x37e6, 0x08},
429*5fcf092eSHyungwoo Yang 	{0x3800, 0x00},
430*5fcf092eSHyungwoo Yang 	{0x3801, 0x00},
431*5fcf092eSHyungwoo Yang 	{0x3802, 0x00},
432*5fcf092eSHyungwoo Yang 	{0x3803, 0x00},
433*5fcf092eSHyungwoo Yang 	{0x3804, 0x10},
434*5fcf092eSHyungwoo Yang 	{0x3805, 0x9f},
435*5fcf092eSHyungwoo Yang 	{0x3806, 0x0c},
436*5fcf092eSHyungwoo Yang 	{0x3807, 0x5f},
437*5fcf092eSHyungwoo Yang 	{0x3808, 0x08},
438*5fcf092eSHyungwoo Yang 	{0x3809, 0x40},
439*5fcf092eSHyungwoo Yang 	{0x380a, 0x06},
440*5fcf092eSHyungwoo Yang 	{0x380b, 0x20},
441*5fcf092eSHyungwoo Yang 	{0x380c, 0x04},
442*5fcf092eSHyungwoo Yang 	{0x380d, 0x62},
443*5fcf092eSHyungwoo Yang 	{0x380e, 0x0c},
444*5fcf092eSHyungwoo Yang 	{0x380f, 0x8e},
445*5fcf092eSHyungwoo Yang 	{0x3811, 0x04},
446*5fcf092eSHyungwoo Yang 	{0x3813, 0x05},
447*5fcf092eSHyungwoo Yang 	{0x3814, 0x03},
448*5fcf092eSHyungwoo Yang 	{0x3815, 0x01},
449*5fcf092eSHyungwoo Yang 	{0x3816, 0x03},
450*5fcf092eSHyungwoo Yang 	{0x3817, 0x01},
451*5fcf092eSHyungwoo Yang 	{0x3820, 0xab},
452*5fcf092eSHyungwoo Yang 	{0x3821, 0x00},
453*5fcf092eSHyungwoo Yang 	{0x3822, 0xc2},
454*5fcf092eSHyungwoo Yang 	{0x3823, 0x18},
455*5fcf092eSHyungwoo Yang 	{0x3826, 0x04},
456*5fcf092eSHyungwoo Yang 	{0x3827, 0x90},
457*5fcf092eSHyungwoo Yang 	{0x3829, 0x07},
458*5fcf092eSHyungwoo Yang 	{0x3832, 0x00},
459*5fcf092eSHyungwoo Yang 	{0x3c80, 0x00},
460*5fcf092eSHyungwoo Yang 	{0x3c87, 0x01},
461*5fcf092eSHyungwoo Yang 	{0x3c8c, 0x19},
462*5fcf092eSHyungwoo Yang 	{0x3c8d, 0x1c},
463*5fcf092eSHyungwoo Yang 	{0x3c90, 0x00},
464*5fcf092eSHyungwoo Yang 	{0x3c91, 0x00},
465*5fcf092eSHyungwoo Yang 	{0x3c92, 0x00},
466*5fcf092eSHyungwoo Yang 	{0x3c93, 0x00},
467*5fcf092eSHyungwoo Yang 	{0x3c94, 0x40},
468*5fcf092eSHyungwoo Yang 	{0x3c95, 0x54},
469*5fcf092eSHyungwoo Yang 	{0x3c96, 0x34},
470*5fcf092eSHyungwoo Yang 	{0x3c97, 0x04},
471*5fcf092eSHyungwoo Yang 	{0x3c98, 0x00},
472*5fcf092eSHyungwoo Yang 	{0x3d8c, 0x73},
473*5fcf092eSHyungwoo Yang 	{0x3d8d, 0xc0},
474*5fcf092eSHyungwoo Yang 	{0x3f00, 0x0b},
475*5fcf092eSHyungwoo Yang 	{0x3f03, 0x00},
476*5fcf092eSHyungwoo Yang 	{0x4001, 0xe0},
477*5fcf092eSHyungwoo Yang 	{0x4008, 0x00},
478*5fcf092eSHyungwoo Yang 	{0x4009, 0x0d},
479*5fcf092eSHyungwoo Yang 	{0x4011, 0xf0},
480*5fcf092eSHyungwoo Yang 	{0x4017, 0x08},
481*5fcf092eSHyungwoo Yang 	{0x4050, 0x04},
482*5fcf092eSHyungwoo Yang 	{0x4051, 0x0b},
483*5fcf092eSHyungwoo Yang 	{0x4052, 0x00},
484*5fcf092eSHyungwoo Yang 	{0x4053, 0x80},
485*5fcf092eSHyungwoo Yang 	{0x4054, 0x00},
486*5fcf092eSHyungwoo Yang 	{0x4055, 0x80},
487*5fcf092eSHyungwoo Yang 	{0x4056, 0x00},
488*5fcf092eSHyungwoo Yang 	{0x4057, 0x80},
489*5fcf092eSHyungwoo Yang 	{0x4058, 0x00},
490*5fcf092eSHyungwoo Yang 	{0x4059, 0x80},
491*5fcf092eSHyungwoo Yang 	{0x405e, 0x20},
492*5fcf092eSHyungwoo Yang 	{0x4500, 0x07},
493*5fcf092eSHyungwoo Yang 	{0x4503, 0x00},
494*5fcf092eSHyungwoo Yang 	{0x450a, 0x04},
495*5fcf092eSHyungwoo Yang 	{0x4809, 0x04},
496*5fcf092eSHyungwoo Yang 	{0x480c, 0x12},
497*5fcf092eSHyungwoo Yang 	{0x481f, 0x30},
498*5fcf092eSHyungwoo Yang 	{0x4833, 0x10},
499*5fcf092eSHyungwoo Yang 	{0x4837, 0x1c},
500*5fcf092eSHyungwoo Yang 	{0x4902, 0x01},
501*5fcf092eSHyungwoo Yang 	{0x4d00, 0x03},
502*5fcf092eSHyungwoo Yang 	{0x4d01, 0xc9},
503*5fcf092eSHyungwoo Yang 	{0x4d02, 0xbc},
504*5fcf092eSHyungwoo Yang 	{0x4d03, 0xd7},
505*5fcf092eSHyungwoo Yang 	{0x4d04, 0xf0},
506*5fcf092eSHyungwoo Yang 	{0x4d05, 0xa2},
507*5fcf092eSHyungwoo Yang 	{0x5000, 0xfd},
508*5fcf092eSHyungwoo Yang 	{0x5001, 0x01},
509*5fcf092eSHyungwoo Yang 	{0x5040, 0x39},
510*5fcf092eSHyungwoo Yang 	{0x5041, 0x10},
511*5fcf092eSHyungwoo Yang 	{0x5042, 0x10},
512*5fcf092eSHyungwoo Yang 	{0x5043, 0x84},
513*5fcf092eSHyungwoo Yang 	{0x5044, 0x62},
514*5fcf092eSHyungwoo Yang 	{0x5180, 0x00},
515*5fcf092eSHyungwoo Yang 	{0x5181, 0x10},
516*5fcf092eSHyungwoo Yang 	{0x5182, 0x02},
517*5fcf092eSHyungwoo Yang 	{0x5183, 0x0f},
518*5fcf092eSHyungwoo Yang 	{0x5200, 0x1b},
519*5fcf092eSHyungwoo Yang 	{0x520b, 0x07},
520*5fcf092eSHyungwoo Yang 	{0x520c, 0x0f},
521*5fcf092eSHyungwoo Yang 	{0x5300, 0x04},
522*5fcf092eSHyungwoo Yang 	{0x5301, 0x0c},
523*5fcf092eSHyungwoo Yang 	{0x5302, 0x0c},
524*5fcf092eSHyungwoo Yang 	{0x5303, 0x0f},
525*5fcf092eSHyungwoo Yang 	{0x5304, 0x00},
526*5fcf092eSHyungwoo Yang 	{0x5305, 0x70},
527*5fcf092eSHyungwoo Yang 	{0x5306, 0x00},
528*5fcf092eSHyungwoo Yang 	{0x5307, 0x80},
529*5fcf092eSHyungwoo Yang 	{0x5308, 0x00},
530*5fcf092eSHyungwoo Yang 	{0x5309, 0xa5},
531*5fcf092eSHyungwoo Yang 	{0x530a, 0x00},
532*5fcf092eSHyungwoo Yang 	{0x530b, 0xd3},
533*5fcf092eSHyungwoo Yang 	{0x530c, 0x00},
534*5fcf092eSHyungwoo Yang 	{0x530d, 0xf0},
535*5fcf092eSHyungwoo Yang 	{0x530e, 0x01},
536*5fcf092eSHyungwoo Yang 	{0x530f, 0x10},
537*5fcf092eSHyungwoo Yang 	{0x5310, 0x01},
538*5fcf092eSHyungwoo Yang 	{0x5311, 0x20},
539*5fcf092eSHyungwoo Yang 	{0x5312, 0x01},
540*5fcf092eSHyungwoo Yang 	{0x5313, 0x20},
541*5fcf092eSHyungwoo Yang 	{0x5314, 0x01},
542*5fcf092eSHyungwoo Yang 	{0x5315, 0x20},
543*5fcf092eSHyungwoo Yang 	{0x5316, 0x08},
544*5fcf092eSHyungwoo Yang 	{0x5317, 0x08},
545*5fcf092eSHyungwoo Yang 	{0x5318, 0x10},
546*5fcf092eSHyungwoo Yang 	{0x5319, 0x88},
547*5fcf092eSHyungwoo Yang 	{0x531a, 0x88},
548*5fcf092eSHyungwoo Yang 	{0x531b, 0xa9},
549*5fcf092eSHyungwoo Yang 	{0x531c, 0xaa},
550*5fcf092eSHyungwoo Yang 	{0x531d, 0x0a},
551*5fcf092eSHyungwoo Yang 	{0x5405, 0x02},
552*5fcf092eSHyungwoo Yang 	{0x5406, 0x67},
553*5fcf092eSHyungwoo Yang 	{0x5407, 0x01},
554*5fcf092eSHyungwoo Yang 	{0x5408, 0x4a},
555*5fcf092eSHyungwoo Yang };
556*5fcf092eSHyungwoo Yang 
557*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_2112x1188_regs[] = {
558*5fcf092eSHyungwoo Yang 	{0x3013, 0x32},
559*5fcf092eSHyungwoo Yang 	{0x301b, 0xf0},
560*5fcf092eSHyungwoo Yang 	{0x301f, 0xd0},
561*5fcf092eSHyungwoo Yang 	{0x3106, 0x15},
562*5fcf092eSHyungwoo Yang 	{0x3107, 0x23},
563*5fcf092eSHyungwoo Yang 	{0x350a, 0x00},
564*5fcf092eSHyungwoo Yang 	{0x350e, 0x00},
565*5fcf092eSHyungwoo Yang 	{0x3510, 0x00},
566*5fcf092eSHyungwoo Yang 	{0x3511, 0x02},
567*5fcf092eSHyungwoo Yang 	{0x3512, 0x00},
568*5fcf092eSHyungwoo Yang 	{0x3600, 0x2b},
569*5fcf092eSHyungwoo Yang 	{0x3601, 0x52},
570*5fcf092eSHyungwoo Yang 	{0x3602, 0x60},
571*5fcf092eSHyungwoo Yang 	{0x3612, 0x05},
572*5fcf092eSHyungwoo Yang 	{0x3613, 0xa4},
573*5fcf092eSHyungwoo Yang 	{0x3620, 0x80},
574*5fcf092eSHyungwoo Yang 	{0x3621, 0x10},
575*5fcf092eSHyungwoo Yang 	{0x3622, 0x30},
576*5fcf092eSHyungwoo Yang 	{0x3624, 0x1c},
577*5fcf092eSHyungwoo Yang 	{0x3640, 0x10},
578*5fcf092eSHyungwoo Yang 	{0x3641, 0x70},
579*5fcf092eSHyungwoo Yang 	{0x3661, 0x80},
580*5fcf092eSHyungwoo Yang 	{0x3662, 0x10},
581*5fcf092eSHyungwoo Yang 	{0x3664, 0x73},
582*5fcf092eSHyungwoo Yang 	{0x3665, 0xa7},
583*5fcf092eSHyungwoo Yang 	{0x366e, 0xff},
584*5fcf092eSHyungwoo Yang 	{0x366f, 0xf4},
585*5fcf092eSHyungwoo Yang 	{0x3674, 0x00},
586*5fcf092eSHyungwoo Yang 	{0x3679, 0x0c},
587*5fcf092eSHyungwoo Yang 	{0x367f, 0x01},
588*5fcf092eSHyungwoo Yang 	{0x3680, 0x0c},
589*5fcf092eSHyungwoo Yang 	{0x3681, 0x50},
590*5fcf092eSHyungwoo Yang 	{0x3682, 0x50},
591*5fcf092eSHyungwoo Yang 	{0x3683, 0xa9},
592*5fcf092eSHyungwoo Yang 	{0x3684, 0xa9},
593*5fcf092eSHyungwoo Yang 	{0x3709, 0x5f},
594*5fcf092eSHyungwoo Yang 	{0x3714, 0x28},
595*5fcf092eSHyungwoo Yang 	{0x371a, 0x3e},
596*5fcf092eSHyungwoo Yang 	{0x3737, 0x08},
597*5fcf092eSHyungwoo Yang 	{0x3738, 0xcc},
598*5fcf092eSHyungwoo Yang 	{0x3739, 0x20},
599*5fcf092eSHyungwoo Yang 	{0x373d, 0x26},
600*5fcf092eSHyungwoo Yang 	{0x3764, 0x20},
601*5fcf092eSHyungwoo Yang 	{0x3765, 0x20},
602*5fcf092eSHyungwoo Yang 	{0x37a1, 0x36},
603*5fcf092eSHyungwoo Yang 	{0x37a8, 0x3b},
604*5fcf092eSHyungwoo Yang 	{0x37ab, 0x31},
605*5fcf092eSHyungwoo Yang 	{0x37c2, 0x14},
606*5fcf092eSHyungwoo Yang 	{0x37c3, 0xf1},
607*5fcf092eSHyungwoo Yang 	{0x37c5, 0x00},
608*5fcf092eSHyungwoo Yang 	{0x37d8, 0x03},
609*5fcf092eSHyungwoo Yang 	{0x37d9, 0x0c},
610*5fcf092eSHyungwoo Yang 	{0x37da, 0xc2},
611*5fcf092eSHyungwoo Yang 	{0x37dc, 0x02},
612*5fcf092eSHyungwoo Yang 	{0x37e0, 0x00},
613*5fcf092eSHyungwoo Yang 	{0x37e1, 0x0a},
614*5fcf092eSHyungwoo Yang 	{0x37e2, 0x14},
615*5fcf092eSHyungwoo Yang 	{0x37e3, 0x08},
616*5fcf092eSHyungwoo Yang 	{0x37e4, 0x38},
617*5fcf092eSHyungwoo Yang 	{0x37e5, 0x03},
618*5fcf092eSHyungwoo Yang 	{0x37e6, 0x08},
619*5fcf092eSHyungwoo Yang 	{0x3800, 0x00},
620*5fcf092eSHyungwoo Yang 	{0x3801, 0x00},
621*5fcf092eSHyungwoo Yang 	{0x3802, 0x01},
622*5fcf092eSHyungwoo Yang 	{0x3803, 0x84},
623*5fcf092eSHyungwoo Yang 	{0x3804, 0x10},
624*5fcf092eSHyungwoo Yang 	{0x3805, 0x9f},
625*5fcf092eSHyungwoo Yang 	{0x3806, 0x0a},
626*5fcf092eSHyungwoo Yang 	{0x3807, 0xd3},
627*5fcf092eSHyungwoo Yang 	{0x3808, 0x08},
628*5fcf092eSHyungwoo Yang 	{0x3809, 0x40},
629*5fcf092eSHyungwoo Yang 	{0x380a, 0x04},
630*5fcf092eSHyungwoo Yang 	{0x380b, 0xa4},
631*5fcf092eSHyungwoo Yang 	{0x380c, 0x04},
632*5fcf092eSHyungwoo Yang 	{0x380d, 0x62},
633*5fcf092eSHyungwoo Yang 	{0x380e, 0x0c},
634*5fcf092eSHyungwoo Yang 	{0x380f, 0x8e},
635*5fcf092eSHyungwoo Yang 	{0x3811, 0x08},
636*5fcf092eSHyungwoo Yang 	{0x3813, 0x03},
637*5fcf092eSHyungwoo Yang 	{0x3814, 0x03},
638*5fcf092eSHyungwoo Yang 	{0x3815, 0x01},
639*5fcf092eSHyungwoo Yang 	{0x3816, 0x03},
640*5fcf092eSHyungwoo Yang 	{0x3817, 0x01},
641*5fcf092eSHyungwoo Yang 	{0x3820, 0xab},
642*5fcf092eSHyungwoo Yang 	{0x3821, 0x00},
643*5fcf092eSHyungwoo Yang 	{0x3822, 0xc2},
644*5fcf092eSHyungwoo Yang 	{0x3823, 0x18},
645*5fcf092eSHyungwoo Yang 	{0x3826, 0x04},
646*5fcf092eSHyungwoo Yang 	{0x3827, 0x90},
647*5fcf092eSHyungwoo Yang 	{0x3829, 0x07},
648*5fcf092eSHyungwoo Yang 	{0x3832, 0x00},
649*5fcf092eSHyungwoo Yang 	{0x3c80, 0x00},
650*5fcf092eSHyungwoo Yang 	{0x3c87, 0x01},
651*5fcf092eSHyungwoo Yang 	{0x3c8c, 0x19},
652*5fcf092eSHyungwoo Yang 	{0x3c8d, 0x1c},
653*5fcf092eSHyungwoo Yang 	{0x3c90, 0x00},
654*5fcf092eSHyungwoo Yang 	{0x3c91, 0x00},
655*5fcf092eSHyungwoo Yang 	{0x3c92, 0x00},
656*5fcf092eSHyungwoo Yang 	{0x3c93, 0x00},
657*5fcf092eSHyungwoo Yang 	{0x3c94, 0x40},
658*5fcf092eSHyungwoo Yang 	{0x3c95, 0x54},
659*5fcf092eSHyungwoo Yang 	{0x3c96, 0x34},
660*5fcf092eSHyungwoo Yang 	{0x3c97, 0x04},
661*5fcf092eSHyungwoo Yang 	{0x3c98, 0x00},
662*5fcf092eSHyungwoo Yang 	{0x3d8c, 0x73},
663*5fcf092eSHyungwoo Yang 	{0x3d8d, 0xc0},
664*5fcf092eSHyungwoo Yang 	{0x3f00, 0x0b},
665*5fcf092eSHyungwoo Yang 	{0x3f03, 0x00},
666*5fcf092eSHyungwoo Yang 	{0x4001, 0xe0},
667*5fcf092eSHyungwoo Yang 	{0x4008, 0x00},
668*5fcf092eSHyungwoo Yang 	{0x4009, 0x0d},
669*5fcf092eSHyungwoo Yang 	{0x4011, 0xf0},
670*5fcf092eSHyungwoo Yang 	{0x4017, 0x08},
671*5fcf092eSHyungwoo Yang 	{0x4050, 0x04},
672*5fcf092eSHyungwoo Yang 	{0x4051, 0x0b},
673*5fcf092eSHyungwoo Yang 	{0x4052, 0x00},
674*5fcf092eSHyungwoo Yang 	{0x4053, 0x80},
675*5fcf092eSHyungwoo Yang 	{0x4054, 0x00},
676*5fcf092eSHyungwoo Yang 	{0x4055, 0x80},
677*5fcf092eSHyungwoo Yang 	{0x4056, 0x00},
678*5fcf092eSHyungwoo Yang 	{0x4057, 0x80},
679*5fcf092eSHyungwoo Yang 	{0x4058, 0x00},
680*5fcf092eSHyungwoo Yang 	{0x4059, 0x80},
681*5fcf092eSHyungwoo Yang 	{0x405e, 0x20},
682*5fcf092eSHyungwoo Yang 	{0x4500, 0x07},
683*5fcf092eSHyungwoo Yang 	{0x4503, 0x00},
684*5fcf092eSHyungwoo Yang 	{0x450a, 0x04},
685*5fcf092eSHyungwoo Yang 	{0x4809, 0x04},
686*5fcf092eSHyungwoo Yang 	{0x480c, 0x12},
687*5fcf092eSHyungwoo Yang 	{0x481f, 0x30},
688*5fcf092eSHyungwoo Yang 	{0x4833, 0x10},
689*5fcf092eSHyungwoo Yang 	{0x4837, 0x1c},
690*5fcf092eSHyungwoo Yang 	{0x4902, 0x01},
691*5fcf092eSHyungwoo Yang 	{0x4d00, 0x03},
692*5fcf092eSHyungwoo Yang 	{0x4d01, 0xc9},
693*5fcf092eSHyungwoo Yang 	{0x4d02, 0xbc},
694*5fcf092eSHyungwoo Yang 	{0x4d03, 0xd7},
695*5fcf092eSHyungwoo Yang 	{0x4d04, 0xf0},
696*5fcf092eSHyungwoo Yang 	{0x4d05, 0xa2},
697*5fcf092eSHyungwoo Yang 	{0x5000, 0xfd},
698*5fcf092eSHyungwoo Yang 	{0x5001, 0x01},
699*5fcf092eSHyungwoo Yang 	{0x5040, 0x39},
700*5fcf092eSHyungwoo Yang 	{0x5041, 0x10},
701*5fcf092eSHyungwoo Yang 	{0x5042, 0x10},
702*5fcf092eSHyungwoo Yang 	{0x5043, 0x84},
703*5fcf092eSHyungwoo Yang 	{0x5044, 0x62},
704*5fcf092eSHyungwoo Yang 	{0x5180, 0x00},
705*5fcf092eSHyungwoo Yang 	{0x5181, 0x10},
706*5fcf092eSHyungwoo Yang 	{0x5182, 0x02},
707*5fcf092eSHyungwoo Yang 	{0x5183, 0x0f},
708*5fcf092eSHyungwoo Yang 	{0x5200, 0x1b},
709*5fcf092eSHyungwoo Yang 	{0x520b, 0x07},
710*5fcf092eSHyungwoo Yang 	{0x520c, 0x0f},
711*5fcf092eSHyungwoo Yang 	{0x5300, 0x04},
712*5fcf092eSHyungwoo Yang 	{0x5301, 0x0c},
713*5fcf092eSHyungwoo Yang 	{0x5302, 0x0c},
714*5fcf092eSHyungwoo Yang 	{0x5303, 0x0f},
715*5fcf092eSHyungwoo Yang 	{0x5304, 0x00},
716*5fcf092eSHyungwoo Yang 	{0x5305, 0x70},
717*5fcf092eSHyungwoo Yang 	{0x5306, 0x00},
718*5fcf092eSHyungwoo Yang 	{0x5307, 0x80},
719*5fcf092eSHyungwoo Yang 	{0x5308, 0x00},
720*5fcf092eSHyungwoo Yang 	{0x5309, 0xa5},
721*5fcf092eSHyungwoo Yang 	{0x530a, 0x00},
722*5fcf092eSHyungwoo Yang 	{0x530b, 0xd3},
723*5fcf092eSHyungwoo Yang 	{0x530c, 0x00},
724*5fcf092eSHyungwoo Yang 	{0x530d, 0xf0},
725*5fcf092eSHyungwoo Yang 	{0x530e, 0x01},
726*5fcf092eSHyungwoo Yang 	{0x530f, 0x10},
727*5fcf092eSHyungwoo Yang 	{0x5310, 0x01},
728*5fcf092eSHyungwoo Yang 	{0x5311, 0x20},
729*5fcf092eSHyungwoo Yang 	{0x5312, 0x01},
730*5fcf092eSHyungwoo Yang 	{0x5313, 0x20},
731*5fcf092eSHyungwoo Yang 	{0x5314, 0x01},
732*5fcf092eSHyungwoo Yang 	{0x5315, 0x20},
733*5fcf092eSHyungwoo Yang 	{0x5316, 0x08},
734*5fcf092eSHyungwoo Yang 	{0x5317, 0x08},
735*5fcf092eSHyungwoo Yang 	{0x5318, 0x10},
736*5fcf092eSHyungwoo Yang 	{0x5319, 0x88},
737*5fcf092eSHyungwoo Yang 	{0x531a, 0x88},
738*5fcf092eSHyungwoo Yang 	{0x531b, 0xa9},
739*5fcf092eSHyungwoo Yang 	{0x531c, 0xaa},
740*5fcf092eSHyungwoo Yang 	{0x531d, 0x0a},
741*5fcf092eSHyungwoo Yang 	{0x5405, 0x02},
742*5fcf092eSHyungwoo Yang 	{0x5406, 0x67},
743*5fcf092eSHyungwoo Yang 	{0x5407, 0x01},
744*5fcf092eSHyungwoo Yang 	{0x5408, 0x4a},
745*5fcf092eSHyungwoo Yang };
746*5fcf092eSHyungwoo Yang 
747*5fcf092eSHyungwoo Yang static const struct ov13858_reg mode_1056x784_regs[] = {
748*5fcf092eSHyungwoo Yang 	{0x3013, 0x32},
749*5fcf092eSHyungwoo Yang 	{0x301b, 0xf0},
750*5fcf092eSHyungwoo Yang 	{0x301f, 0xd0},
751*5fcf092eSHyungwoo Yang 	{0x3106, 0x15},
752*5fcf092eSHyungwoo Yang 	{0x3107, 0x23},
753*5fcf092eSHyungwoo Yang 	{0x350a, 0x00},
754*5fcf092eSHyungwoo Yang 	{0x350e, 0x00},
755*5fcf092eSHyungwoo Yang 	{0x3510, 0x00},
756*5fcf092eSHyungwoo Yang 	{0x3511, 0x02},
757*5fcf092eSHyungwoo Yang 	{0x3512, 0x00},
758*5fcf092eSHyungwoo Yang 	{0x3600, 0x2b},
759*5fcf092eSHyungwoo Yang 	{0x3601, 0x52},
760*5fcf092eSHyungwoo Yang 	{0x3602, 0x60},
761*5fcf092eSHyungwoo Yang 	{0x3612, 0x05},
762*5fcf092eSHyungwoo Yang 	{0x3613, 0xa4},
763*5fcf092eSHyungwoo Yang 	{0x3620, 0x80},
764*5fcf092eSHyungwoo Yang 	{0x3621, 0x10},
765*5fcf092eSHyungwoo Yang 	{0x3622, 0x30},
766*5fcf092eSHyungwoo Yang 	{0x3624, 0x1c},
767*5fcf092eSHyungwoo Yang 	{0x3640, 0x10},
768*5fcf092eSHyungwoo Yang 	{0x3641, 0x70},
769*5fcf092eSHyungwoo Yang 	{0x3661, 0x80},
770*5fcf092eSHyungwoo Yang 	{0x3662, 0x08},
771*5fcf092eSHyungwoo Yang 	{0x3664, 0x73},
772*5fcf092eSHyungwoo Yang 	{0x3665, 0xa7},
773*5fcf092eSHyungwoo Yang 	{0x366e, 0xff},
774*5fcf092eSHyungwoo Yang 	{0x366f, 0xf4},
775*5fcf092eSHyungwoo Yang 	{0x3674, 0x00},
776*5fcf092eSHyungwoo Yang 	{0x3679, 0x0c},
777*5fcf092eSHyungwoo Yang 	{0x367f, 0x01},
778*5fcf092eSHyungwoo Yang 	{0x3680, 0x0c},
779*5fcf092eSHyungwoo Yang 	{0x3681, 0x50},
780*5fcf092eSHyungwoo Yang 	{0x3682, 0x50},
781*5fcf092eSHyungwoo Yang 	{0x3683, 0xa9},
782*5fcf092eSHyungwoo Yang 	{0x3684, 0xa9},
783*5fcf092eSHyungwoo Yang 	{0x3709, 0x5f},
784*5fcf092eSHyungwoo Yang 	{0x3714, 0x30},
785*5fcf092eSHyungwoo Yang 	{0x371a, 0x3e},
786*5fcf092eSHyungwoo Yang 	{0x3737, 0x08},
787*5fcf092eSHyungwoo Yang 	{0x3738, 0xcc},
788*5fcf092eSHyungwoo Yang 	{0x3739, 0x20},
789*5fcf092eSHyungwoo Yang 	{0x373d, 0x26},
790*5fcf092eSHyungwoo Yang 	{0x3764, 0x20},
791*5fcf092eSHyungwoo Yang 	{0x3765, 0x20},
792*5fcf092eSHyungwoo Yang 	{0x37a1, 0x36},
793*5fcf092eSHyungwoo Yang 	{0x37a8, 0x3b},
794*5fcf092eSHyungwoo Yang 	{0x37ab, 0x31},
795*5fcf092eSHyungwoo Yang 	{0x37c2, 0x2c},
796*5fcf092eSHyungwoo Yang 	{0x37c3, 0xf1},
797*5fcf092eSHyungwoo Yang 	{0x37c5, 0x00},
798*5fcf092eSHyungwoo Yang 	{0x37d8, 0x03},
799*5fcf092eSHyungwoo Yang 	{0x37d9, 0x06},
800*5fcf092eSHyungwoo Yang 	{0x37da, 0xc2},
801*5fcf092eSHyungwoo Yang 	{0x37dc, 0x02},
802*5fcf092eSHyungwoo Yang 	{0x37e0, 0x00},
803*5fcf092eSHyungwoo Yang 	{0x37e1, 0x0a},
804*5fcf092eSHyungwoo Yang 	{0x37e2, 0x14},
805*5fcf092eSHyungwoo Yang 	{0x37e3, 0x08},
806*5fcf092eSHyungwoo Yang 	{0x37e4, 0x36},
807*5fcf092eSHyungwoo Yang 	{0x37e5, 0x03},
808*5fcf092eSHyungwoo Yang 	{0x37e6, 0x08},
809*5fcf092eSHyungwoo Yang 	{0x3800, 0x00},
810*5fcf092eSHyungwoo Yang 	{0x3801, 0x00},
811*5fcf092eSHyungwoo Yang 	{0x3802, 0x00},
812*5fcf092eSHyungwoo Yang 	{0x3803, 0x00},
813*5fcf092eSHyungwoo Yang 	{0x3804, 0x10},
814*5fcf092eSHyungwoo Yang 	{0x3805, 0x9f},
815*5fcf092eSHyungwoo Yang 	{0x3806, 0x0c},
816*5fcf092eSHyungwoo Yang 	{0x3807, 0x5f},
817*5fcf092eSHyungwoo Yang 	{0x3808, 0x04},
818*5fcf092eSHyungwoo Yang 	{0x3809, 0x20},
819*5fcf092eSHyungwoo Yang 	{0x380a, 0x03},
820*5fcf092eSHyungwoo Yang 	{0x380b, 0x10},
821*5fcf092eSHyungwoo Yang 	{0x380c, 0x04},
822*5fcf092eSHyungwoo Yang 	{0x380d, 0x62},
823*5fcf092eSHyungwoo Yang 	{0x380e, 0x0c},
824*5fcf092eSHyungwoo Yang 	{0x380f, 0x8e},
825*5fcf092eSHyungwoo Yang 	{0x3811, 0x04},
826*5fcf092eSHyungwoo Yang 	{0x3813, 0x05},
827*5fcf092eSHyungwoo Yang 	{0x3814, 0x07},
828*5fcf092eSHyungwoo Yang 	{0x3815, 0x01},
829*5fcf092eSHyungwoo Yang 	{0x3816, 0x07},
830*5fcf092eSHyungwoo Yang 	{0x3817, 0x01},
831*5fcf092eSHyungwoo Yang 	{0x3820, 0xac},
832*5fcf092eSHyungwoo Yang 	{0x3821, 0x00},
833*5fcf092eSHyungwoo Yang 	{0x3822, 0xc2},
834*5fcf092eSHyungwoo Yang 	{0x3823, 0x18},
835*5fcf092eSHyungwoo Yang 	{0x3826, 0x04},
836*5fcf092eSHyungwoo Yang 	{0x3827, 0x48},
837*5fcf092eSHyungwoo Yang 	{0x3829, 0x03},
838*5fcf092eSHyungwoo Yang 	{0x3832, 0x00},
839*5fcf092eSHyungwoo Yang 	{0x3c80, 0x00},
840*5fcf092eSHyungwoo Yang 	{0x3c87, 0x01},
841*5fcf092eSHyungwoo Yang 	{0x3c8c, 0x19},
842*5fcf092eSHyungwoo Yang 	{0x3c8d, 0x1c},
843*5fcf092eSHyungwoo Yang 	{0x3c90, 0x00},
844*5fcf092eSHyungwoo Yang 	{0x3c91, 0x00},
845*5fcf092eSHyungwoo Yang 	{0x3c92, 0x00},
846*5fcf092eSHyungwoo Yang 	{0x3c93, 0x00},
847*5fcf092eSHyungwoo Yang 	{0x3c94, 0x40},
848*5fcf092eSHyungwoo Yang 	{0x3c95, 0x54},
849*5fcf092eSHyungwoo Yang 	{0x3c96, 0x34},
850*5fcf092eSHyungwoo Yang 	{0x3c97, 0x04},
851*5fcf092eSHyungwoo Yang 	{0x3c98, 0x00},
852*5fcf092eSHyungwoo Yang 	{0x3d8c, 0x73},
853*5fcf092eSHyungwoo Yang 	{0x3d8d, 0xc0},
854*5fcf092eSHyungwoo Yang 	{0x3f00, 0x0b},
855*5fcf092eSHyungwoo Yang 	{0x3f03, 0x00},
856*5fcf092eSHyungwoo Yang 	{0x4001, 0xe0},
857*5fcf092eSHyungwoo Yang 	{0x4008, 0x00},
858*5fcf092eSHyungwoo Yang 	{0x4009, 0x05},
859*5fcf092eSHyungwoo Yang 	{0x4011, 0xf0},
860*5fcf092eSHyungwoo Yang 	{0x4017, 0x08},
861*5fcf092eSHyungwoo Yang 	{0x4050, 0x02},
862*5fcf092eSHyungwoo Yang 	{0x4051, 0x05},
863*5fcf092eSHyungwoo Yang 	{0x4052, 0x00},
864*5fcf092eSHyungwoo Yang 	{0x4053, 0x80},
865*5fcf092eSHyungwoo Yang 	{0x4054, 0x00},
866*5fcf092eSHyungwoo Yang 	{0x4055, 0x80},
867*5fcf092eSHyungwoo Yang 	{0x4056, 0x00},
868*5fcf092eSHyungwoo Yang 	{0x4057, 0x80},
869*5fcf092eSHyungwoo Yang 	{0x4058, 0x00},
870*5fcf092eSHyungwoo Yang 	{0x4059, 0x80},
871*5fcf092eSHyungwoo Yang 	{0x405e, 0x20},
872*5fcf092eSHyungwoo Yang 	{0x4500, 0x07},
873*5fcf092eSHyungwoo Yang 	{0x4503, 0x00},
874*5fcf092eSHyungwoo Yang 	{0x450a, 0x04},
875*5fcf092eSHyungwoo Yang 	{0x4809, 0x04},
876*5fcf092eSHyungwoo Yang 	{0x480c, 0x12},
877*5fcf092eSHyungwoo Yang 	{0x481f, 0x30},
878*5fcf092eSHyungwoo Yang 	{0x4833, 0x10},
879*5fcf092eSHyungwoo Yang 	{0x4837, 0x1e},
880*5fcf092eSHyungwoo Yang 	{0x4902, 0x02},
881*5fcf092eSHyungwoo Yang 	{0x4d00, 0x03},
882*5fcf092eSHyungwoo Yang 	{0x4d01, 0xc9},
883*5fcf092eSHyungwoo Yang 	{0x4d02, 0xbc},
884*5fcf092eSHyungwoo Yang 	{0x4d03, 0xd7},
885*5fcf092eSHyungwoo Yang 	{0x4d04, 0xf0},
886*5fcf092eSHyungwoo Yang 	{0x4d05, 0xa2},
887*5fcf092eSHyungwoo Yang 	{0x5000, 0xfd},
888*5fcf092eSHyungwoo Yang 	{0x5001, 0x01},
889*5fcf092eSHyungwoo Yang 	{0x5040, 0x39},
890*5fcf092eSHyungwoo Yang 	{0x5041, 0x10},
891*5fcf092eSHyungwoo Yang 	{0x5042, 0x10},
892*5fcf092eSHyungwoo Yang 	{0x5043, 0x84},
893*5fcf092eSHyungwoo Yang 	{0x5044, 0x62},
894*5fcf092eSHyungwoo Yang 	{0x5180, 0x00},
895*5fcf092eSHyungwoo Yang 	{0x5181, 0x10},
896*5fcf092eSHyungwoo Yang 	{0x5182, 0x02},
897*5fcf092eSHyungwoo Yang 	{0x5183, 0x0f},
898*5fcf092eSHyungwoo Yang 	{0x5200, 0x1b},
899*5fcf092eSHyungwoo Yang 	{0x520b, 0x07},
900*5fcf092eSHyungwoo Yang 	{0x520c, 0x0f},
901*5fcf092eSHyungwoo Yang 	{0x5300, 0x04},
902*5fcf092eSHyungwoo Yang 	{0x5301, 0x0c},
903*5fcf092eSHyungwoo Yang 	{0x5302, 0x0c},
904*5fcf092eSHyungwoo Yang 	{0x5303, 0x0f},
905*5fcf092eSHyungwoo Yang 	{0x5304, 0x00},
906*5fcf092eSHyungwoo Yang 	{0x5305, 0x70},
907*5fcf092eSHyungwoo Yang 	{0x5306, 0x00},
908*5fcf092eSHyungwoo Yang 	{0x5307, 0x80},
909*5fcf092eSHyungwoo Yang 	{0x5308, 0x00},
910*5fcf092eSHyungwoo Yang 	{0x5309, 0xa5},
911*5fcf092eSHyungwoo Yang 	{0x530a, 0x00},
912*5fcf092eSHyungwoo Yang 	{0x530b, 0xd3},
913*5fcf092eSHyungwoo Yang 	{0x530c, 0x00},
914*5fcf092eSHyungwoo Yang 	{0x530d, 0xf0},
915*5fcf092eSHyungwoo Yang 	{0x530e, 0x01},
916*5fcf092eSHyungwoo Yang 	{0x530f, 0x10},
917*5fcf092eSHyungwoo Yang 	{0x5310, 0x01},
918*5fcf092eSHyungwoo Yang 	{0x5311, 0x20},
919*5fcf092eSHyungwoo Yang 	{0x5312, 0x01},
920*5fcf092eSHyungwoo Yang 	{0x5313, 0x20},
921*5fcf092eSHyungwoo Yang 	{0x5314, 0x01},
922*5fcf092eSHyungwoo Yang 	{0x5315, 0x20},
923*5fcf092eSHyungwoo Yang 	{0x5316, 0x08},
924*5fcf092eSHyungwoo Yang 	{0x5317, 0x08},
925*5fcf092eSHyungwoo Yang 	{0x5318, 0x10},
926*5fcf092eSHyungwoo Yang 	{0x5319, 0x88},
927*5fcf092eSHyungwoo Yang 	{0x531a, 0x88},
928*5fcf092eSHyungwoo Yang 	{0x531b, 0xa9},
929*5fcf092eSHyungwoo Yang 	{0x531c, 0xaa},
930*5fcf092eSHyungwoo Yang 	{0x531d, 0x0a},
931*5fcf092eSHyungwoo Yang 	{0x5405, 0x02},
932*5fcf092eSHyungwoo Yang 	{0x5406, 0x67},
933*5fcf092eSHyungwoo Yang 	{0x5407, 0x01},
934*5fcf092eSHyungwoo Yang 	{0x5408, 0x4a},
935*5fcf092eSHyungwoo Yang };
936*5fcf092eSHyungwoo Yang 
937*5fcf092eSHyungwoo Yang static const char * const ov13858_test_pattern_menu[] = {
938*5fcf092eSHyungwoo Yang 	"Disabled",
939*5fcf092eSHyungwoo Yang 	"Vertical Color Bar Type 1",
940*5fcf092eSHyungwoo Yang 	"Vertical Color Bar Type 2",
941*5fcf092eSHyungwoo Yang 	"Vertical Color Bar Type 3",
942*5fcf092eSHyungwoo Yang 	"Vertical Color Bar Type 4"
943*5fcf092eSHyungwoo Yang };
944*5fcf092eSHyungwoo Yang 
945*5fcf092eSHyungwoo Yang /* Configurations for supported link frequencies */
946*5fcf092eSHyungwoo Yang #define OV13858_NUM_OF_LINK_FREQS	2
947*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_1080MBPS	1080000000
948*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_540MBPS	540000000
949*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_INDEX_0	0
950*5fcf092eSHyungwoo Yang #define OV13858_LINK_FREQ_INDEX_1	1
951*5fcf092eSHyungwoo Yang 
952*5fcf092eSHyungwoo Yang /* Menu items for LINK_FREQ V4L2 control */
953*5fcf092eSHyungwoo Yang static const const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = {
954*5fcf092eSHyungwoo Yang 	OV13858_LINK_FREQ_1080MBPS,
955*5fcf092eSHyungwoo Yang 	OV13858_LINK_FREQ_540MBPS
956*5fcf092eSHyungwoo Yang };
957*5fcf092eSHyungwoo Yang 
958*5fcf092eSHyungwoo Yang /* Link frequency configs */
959*5fcf092eSHyungwoo Yang static const struct ov13858_link_freq_config
960*5fcf092eSHyungwoo Yang 			link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = {
961*5fcf092eSHyungwoo Yang 	{
962*5fcf092eSHyungwoo Yang 		.pixel_rate = 864000000,
963*5fcf092eSHyungwoo Yang 		.pixels_per_line = OV13858_PPL_1080MHZ,
964*5fcf092eSHyungwoo Yang 		.reg_list = {
965*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps),
966*5fcf092eSHyungwoo Yang 			.regs = mipi_data_rate_1080mbps,
967*5fcf092eSHyungwoo Yang 		}
968*5fcf092eSHyungwoo Yang 	},
969*5fcf092eSHyungwoo Yang 	{
970*5fcf092eSHyungwoo Yang 		.pixel_rate = 432000000,
971*5fcf092eSHyungwoo Yang 		.pixels_per_line = OV13858_PPL_540MHZ,
972*5fcf092eSHyungwoo Yang 		.reg_list = {
973*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps),
974*5fcf092eSHyungwoo Yang 			.regs = mipi_data_rate_540mbps,
975*5fcf092eSHyungwoo Yang 		}
976*5fcf092eSHyungwoo Yang 	}
977*5fcf092eSHyungwoo Yang };
978*5fcf092eSHyungwoo Yang 
979*5fcf092eSHyungwoo Yang /* Mode configs */
980*5fcf092eSHyungwoo Yang static const struct ov13858_mode supported_modes[] = {
981*5fcf092eSHyungwoo Yang 	{
982*5fcf092eSHyungwoo Yang 		.width = 4224,
983*5fcf092eSHyungwoo Yang 		.height = 3136,
984*5fcf092eSHyungwoo Yang 		.vts = OV13858_VTS_30FPS,
985*5fcf092eSHyungwoo Yang 		.reg_list = {
986*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mode_4224x3136_regs),
987*5fcf092eSHyungwoo Yang 			.regs = mode_4224x3136_regs,
988*5fcf092eSHyungwoo Yang 		},
989*5fcf092eSHyungwoo Yang 		.link_freq_index = OV13858_LINK_FREQ_INDEX_0,
990*5fcf092eSHyungwoo Yang 	},
991*5fcf092eSHyungwoo Yang 	{
992*5fcf092eSHyungwoo Yang 		.width = 2112,
993*5fcf092eSHyungwoo Yang 		.height = 1568,
994*5fcf092eSHyungwoo Yang 		.vts = OV13858_VTS_30FPS,
995*5fcf092eSHyungwoo Yang 		.reg_list = {
996*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mode_2112x1568_regs),
997*5fcf092eSHyungwoo Yang 			.regs = mode_2112x1568_regs,
998*5fcf092eSHyungwoo Yang 		},
999*5fcf092eSHyungwoo Yang 		.link_freq_index = OV13858_LINK_FREQ_INDEX_1,
1000*5fcf092eSHyungwoo Yang 	},
1001*5fcf092eSHyungwoo Yang 	{
1002*5fcf092eSHyungwoo Yang 		.width = 2112,
1003*5fcf092eSHyungwoo Yang 		.height = 1188,
1004*5fcf092eSHyungwoo Yang 		.vts = OV13858_VTS_30FPS,
1005*5fcf092eSHyungwoo Yang 		.reg_list = {
1006*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mode_2112x1188_regs),
1007*5fcf092eSHyungwoo Yang 			.regs = mode_2112x1188_regs,
1008*5fcf092eSHyungwoo Yang 		},
1009*5fcf092eSHyungwoo Yang 		.link_freq_index = OV13858_LINK_FREQ_INDEX_1,
1010*5fcf092eSHyungwoo Yang 	},
1011*5fcf092eSHyungwoo Yang 	{
1012*5fcf092eSHyungwoo Yang 		.width = 1056,
1013*5fcf092eSHyungwoo Yang 		.height = 784,
1014*5fcf092eSHyungwoo Yang 		.vts = OV13858_VTS_30FPS,
1015*5fcf092eSHyungwoo Yang 		.reg_list = {
1016*5fcf092eSHyungwoo Yang 			.num_of_regs = ARRAY_SIZE(mode_1056x784_regs),
1017*5fcf092eSHyungwoo Yang 			.regs = mode_1056x784_regs,
1018*5fcf092eSHyungwoo Yang 		},
1019*5fcf092eSHyungwoo Yang 		.link_freq_index = OV13858_LINK_FREQ_INDEX_1,
1020*5fcf092eSHyungwoo Yang 	}
1021*5fcf092eSHyungwoo Yang };
1022*5fcf092eSHyungwoo Yang 
1023*5fcf092eSHyungwoo Yang struct ov13858 {
1024*5fcf092eSHyungwoo Yang 	struct v4l2_subdev sd;
1025*5fcf092eSHyungwoo Yang 	struct media_pad pad;
1026*5fcf092eSHyungwoo Yang 
1027*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl_handler ctrl_handler;
1028*5fcf092eSHyungwoo Yang 	/* V4L2 Controls */
1029*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl *link_freq;
1030*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl *pixel_rate;
1031*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl *vblank;
1032*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl *hblank;
1033*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl *exposure;
1034*5fcf092eSHyungwoo Yang 
1035*5fcf092eSHyungwoo Yang 	/* Current mode */
1036*5fcf092eSHyungwoo Yang 	const struct ov13858_mode *cur_mode;
1037*5fcf092eSHyungwoo Yang 
1038*5fcf092eSHyungwoo Yang 	/* Mutex for serialized access */
1039*5fcf092eSHyungwoo Yang 	struct mutex mutex;
1040*5fcf092eSHyungwoo Yang 
1041*5fcf092eSHyungwoo Yang 	/* Streaming on/off */
1042*5fcf092eSHyungwoo Yang 	bool streaming;
1043*5fcf092eSHyungwoo Yang };
1044*5fcf092eSHyungwoo Yang 
1045*5fcf092eSHyungwoo Yang #define to_ov13858(_sd)	container_of(_sd, struct ov13858, sd)
1046*5fcf092eSHyungwoo Yang 
1047*5fcf092eSHyungwoo Yang /* Read registers up to 4 at a time */
1048*5fcf092eSHyungwoo Yang static int ov13858_read_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 *val)
1049*5fcf092eSHyungwoo Yang {
1050*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1051*5fcf092eSHyungwoo Yang 	struct i2c_msg msgs[2];
1052*5fcf092eSHyungwoo Yang 	u8 *data_be_p;
1053*5fcf092eSHyungwoo Yang 	int ret;
1054*5fcf092eSHyungwoo Yang 	u32 data_be = 0;
1055*5fcf092eSHyungwoo Yang 	u16 reg_addr_be = cpu_to_be16(reg);
1056*5fcf092eSHyungwoo Yang 
1057*5fcf092eSHyungwoo Yang 	if (len > 4)
1058*5fcf092eSHyungwoo Yang 		return -EINVAL;
1059*5fcf092eSHyungwoo Yang 
1060*5fcf092eSHyungwoo Yang 	data_be_p = (u8 *)&data_be;
1061*5fcf092eSHyungwoo Yang 	/* Write register address */
1062*5fcf092eSHyungwoo Yang 	msgs[0].addr = client->addr;
1063*5fcf092eSHyungwoo Yang 	msgs[0].flags = 0;
1064*5fcf092eSHyungwoo Yang 	msgs[0].len = 2;
1065*5fcf092eSHyungwoo Yang 	msgs[0].buf = (u8 *)&reg_addr_be;
1066*5fcf092eSHyungwoo Yang 
1067*5fcf092eSHyungwoo Yang 	/* Read data from register */
1068*5fcf092eSHyungwoo Yang 	msgs[1].addr = client->addr;
1069*5fcf092eSHyungwoo Yang 	msgs[1].flags = I2C_M_RD;
1070*5fcf092eSHyungwoo Yang 	msgs[1].len = len;
1071*5fcf092eSHyungwoo Yang 	msgs[1].buf = &data_be_p[4 - len];
1072*5fcf092eSHyungwoo Yang 
1073*5fcf092eSHyungwoo Yang 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1074*5fcf092eSHyungwoo Yang 	if (ret != ARRAY_SIZE(msgs))
1075*5fcf092eSHyungwoo Yang 		return -EIO;
1076*5fcf092eSHyungwoo Yang 
1077*5fcf092eSHyungwoo Yang 	*val = be32_to_cpu(data_be);
1078*5fcf092eSHyungwoo Yang 
1079*5fcf092eSHyungwoo Yang 	return 0;
1080*5fcf092eSHyungwoo Yang }
1081*5fcf092eSHyungwoo Yang 
1082*5fcf092eSHyungwoo Yang /* Write registers up to 4 at a time */
1083*5fcf092eSHyungwoo Yang static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 val)
1084*5fcf092eSHyungwoo Yang {
1085*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1086*5fcf092eSHyungwoo Yang 	int buf_i, val_i;
1087*5fcf092eSHyungwoo Yang 	u8 buf[6], *val_p;
1088*5fcf092eSHyungwoo Yang 
1089*5fcf092eSHyungwoo Yang 	if (len > 4)
1090*5fcf092eSHyungwoo Yang 		return -EINVAL;
1091*5fcf092eSHyungwoo Yang 
1092*5fcf092eSHyungwoo Yang 	buf[0] = reg >> 8;
1093*5fcf092eSHyungwoo Yang 	buf[1] = reg & 0xff;
1094*5fcf092eSHyungwoo Yang 
1095*5fcf092eSHyungwoo Yang 	val = cpu_to_be32(val);
1096*5fcf092eSHyungwoo Yang 	val_p = (u8 *)&val;
1097*5fcf092eSHyungwoo Yang 	buf_i = 2;
1098*5fcf092eSHyungwoo Yang 	val_i = 4 - len;
1099*5fcf092eSHyungwoo Yang 
1100*5fcf092eSHyungwoo Yang 	while (val_i < 4)
1101*5fcf092eSHyungwoo Yang 		buf[buf_i++] = val_p[val_i++];
1102*5fcf092eSHyungwoo Yang 
1103*5fcf092eSHyungwoo Yang 	if (i2c_master_send(client, buf, len + 2) != len + 2)
1104*5fcf092eSHyungwoo Yang 		return -EIO;
1105*5fcf092eSHyungwoo Yang 
1106*5fcf092eSHyungwoo Yang 	return 0;
1107*5fcf092eSHyungwoo Yang }
1108*5fcf092eSHyungwoo Yang 
1109*5fcf092eSHyungwoo Yang /* Write a list of registers */
1110*5fcf092eSHyungwoo Yang static int ov13858_write_regs(struct ov13858 *ov13858,
1111*5fcf092eSHyungwoo Yang 			      const struct ov13858_reg *regs, u32 len)
1112*5fcf092eSHyungwoo Yang {
1113*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1114*5fcf092eSHyungwoo Yang 	int ret;
1115*5fcf092eSHyungwoo Yang 	u32 i;
1116*5fcf092eSHyungwoo Yang 
1117*5fcf092eSHyungwoo Yang 	for (i = 0; i < len; i++) {
1118*5fcf092eSHyungwoo Yang 		ret = ov13858_write_reg(ov13858, regs[i].address, 1,
1119*5fcf092eSHyungwoo Yang 					regs[i].val);
1120*5fcf092eSHyungwoo Yang 		if (ret) {
1121*5fcf092eSHyungwoo Yang 			dev_err_ratelimited(
1122*5fcf092eSHyungwoo Yang 				&client->dev,
1123*5fcf092eSHyungwoo Yang 				"Failed to write reg 0x%4.4x. error = %d\n",
1124*5fcf092eSHyungwoo Yang 				regs[i].address, ret);
1125*5fcf092eSHyungwoo Yang 
1126*5fcf092eSHyungwoo Yang 			return ret;
1127*5fcf092eSHyungwoo Yang 		}
1128*5fcf092eSHyungwoo Yang 	}
1129*5fcf092eSHyungwoo Yang 
1130*5fcf092eSHyungwoo Yang 	return 0;
1131*5fcf092eSHyungwoo Yang }
1132*5fcf092eSHyungwoo Yang 
1133*5fcf092eSHyungwoo Yang static int ov13858_write_reg_list(struct ov13858 *ov13858,
1134*5fcf092eSHyungwoo Yang 				  const struct ov13858_reg_list *r_list)
1135*5fcf092eSHyungwoo Yang {
1136*5fcf092eSHyungwoo Yang 	return ov13858_write_regs(ov13858, r_list->regs, r_list->num_of_regs);
1137*5fcf092eSHyungwoo Yang }
1138*5fcf092eSHyungwoo Yang 
1139*5fcf092eSHyungwoo Yang /* Open sub-device */
1140*5fcf092eSHyungwoo Yang static int ov13858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1141*5fcf092eSHyungwoo Yang {
1142*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1143*5fcf092eSHyungwoo Yang 	struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd,
1144*5fcf092eSHyungwoo Yang 									fh->pad,
1145*5fcf092eSHyungwoo Yang 									0);
1146*5fcf092eSHyungwoo Yang 
1147*5fcf092eSHyungwoo Yang 	mutex_lock(&ov13858->mutex);
1148*5fcf092eSHyungwoo Yang 
1149*5fcf092eSHyungwoo Yang 	/* Initialize try_fmt */
1150*5fcf092eSHyungwoo Yang 	try_fmt->width = ov13858->cur_mode->width;
1151*5fcf092eSHyungwoo Yang 	try_fmt->height = ov13858->cur_mode->height;
1152*5fcf092eSHyungwoo Yang 	try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
1153*5fcf092eSHyungwoo Yang 	try_fmt->field = V4L2_FIELD_NONE;
1154*5fcf092eSHyungwoo Yang 
1155*5fcf092eSHyungwoo Yang 	/* No crop or compose */
1156*5fcf092eSHyungwoo Yang 	mutex_unlock(&ov13858->mutex);
1157*5fcf092eSHyungwoo Yang 
1158*5fcf092eSHyungwoo Yang 	return 0;
1159*5fcf092eSHyungwoo Yang }
1160*5fcf092eSHyungwoo Yang 
1161*5fcf092eSHyungwoo Yang static int ov13858_update_digital_gain(struct ov13858 *ov13858, u32 d_gain)
1162*5fcf092eSHyungwoo Yang {
1163*5fcf092eSHyungwoo Yang 	int ret;
1164*5fcf092eSHyungwoo Yang 	u32 val;
1165*5fcf092eSHyungwoo Yang 
1166*5fcf092eSHyungwoo Yang 	if (d_gain == 3)
1167*5fcf092eSHyungwoo Yang 		return -EINVAL;
1168*5fcf092eSHyungwoo Yang 
1169*5fcf092eSHyungwoo Yang 	ret = ov13858_read_reg(ov13858, OV13858_REG_DIGITAL_GAIN,
1170*5fcf092eSHyungwoo Yang 			       OV13858_REG_VALUE_08BIT, &val);
1171*5fcf092eSHyungwoo Yang 	if (ret)
1172*5fcf092eSHyungwoo Yang 		return ret;
1173*5fcf092eSHyungwoo Yang 
1174*5fcf092eSHyungwoo Yang 	val &= OV13858_DGTL_GAIN_MASK;
1175*5fcf092eSHyungwoo Yang 	val |= (d_gain - 1) << OV13858_DGTL_GAIN_SHIFT;
1176*5fcf092eSHyungwoo Yang 
1177*5fcf092eSHyungwoo Yang 	return ov13858_write_reg(ov13858, OV13858_REG_DIGITAL_GAIN,
1178*5fcf092eSHyungwoo Yang 				 OV13858_REG_VALUE_08BIT, val);
1179*5fcf092eSHyungwoo Yang }
1180*5fcf092eSHyungwoo Yang 
1181*5fcf092eSHyungwoo Yang static int ov13858_enable_test_pattern(struct ov13858 *ov13858, u32 pattern)
1182*5fcf092eSHyungwoo Yang {
1183*5fcf092eSHyungwoo Yang 	int ret;
1184*5fcf092eSHyungwoo Yang 	u32 val;
1185*5fcf092eSHyungwoo Yang 
1186*5fcf092eSHyungwoo Yang 	ret = ov13858_read_reg(ov13858, OV13858_REG_TEST_PATTERN,
1187*5fcf092eSHyungwoo Yang 			       OV13858_REG_VALUE_08BIT, &val);
1188*5fcf092eSHyungwoo Yang 	if (ret)
1189*5fcf092eSHyungwoo Yang 		return ret;
1190*5fcf092eSHyungwoo Yang 
1191*5fcf092eSHyungwoo Yang 	if (pattern) {
1192*5fcf092eSHyungwoo Yang 		val &= OV13858_TEST_PATTERN_MASK;
1193*5fcf092eSHyungwoo Yang 		val |= (pattern - 1) | OV13858_TEST_PATTERN_ENABLE;
1194*5fcf092eSHyungwoo Yang 	} else {
1195*5fcf092eSHyungwoo Yang 		val &= ~OV13858_TEST_PATTERN_ENABLE;
1196*5fcf092eSHyungwoo Yang 	}
1197*5fcf092eSHyungwoo Yang 
1198*5fcf092eSHyungwoo Yang 	return ov13858_write_reg(ov13858, OV13858_REG_TEST_PATTERN,
1199*5fcf092eSHyungwoo Yang 				 OV13858_REG_VALUE_08BIT, val);
1200*5fcf092eSHyungwoo Yang }
1201*5fcf092eSHyungwoo Yang 
1202*5fcf092eSHyungwoo Yang static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
1203*5fcf092eSHyungwoo Yang {
1204*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = container_of(ctrl->handler,
1205*5fcf092eSHyungwoo Yang 					       struct ov13858, ctrl_handler);
1206*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1207*5fcf092eSHyungwoo Yang 	s64 max;
1208*5fcf092eSHyungwoo Yang 	int ret;
1209*5fcf092eSHyungwoo Yang 
1210*5fcf092eSHyungwoo Yang 	/* Propagate change of current control to all related controls */
1211*5fcf092eSHyungwoo Yang 	switch (ctrl->id) {
1212*5fcf092eSHyungwoo Yang 	case V4L2_CID_VBLANK:
1213*5fcf092eSHyungwoo Yang 		/* Update max exposure while meeting expected vblanking */
1214*5fcf092eSHyungwoo Yang 		max = ov13858->cur_mode->height + ctrl->val - 8;
1215*5fcf092eSHyungwoo Yang 		__v4l2_ctrl_modify_range(ov13858->exposure,
1216*5fcf092eSHyungwoo Yang 					 ov13858->exposure->minimum,
1217*5fcf092eSHyungwoo Yang 					 max, ov13858->exposure->step, max);
1218*5fcf092eSHyungwoo Yang 		break;
1219*5fcf092eSHyungwoo Yang 	};
1220*5fcf092eSHyungwoo Yang 
1221*5fcf092eSHyungwoo Yang 	/*
1222*5fcf092eSHyungwoo Yang 	 * Applying V4L2 control value only happens
1223*5fcf092eSHyungwoo Yang 	 * when power is up for streaming
1224*5fcf092eSHyungwoo Yang 	 */
1225*5fcf092eSHyungwoo Yang 	if (pm_runtime_get_if_in_use(&client->dev) <= 0)
1226*5fcf092eSHyungwoo Yang 		return 0;
1227*5fcf092eSHyungwoo Yang 
1228*5fcf092eSHyungwoo Yang 	ret = 0;
1229*5fcf092eSHyungwoo Yang 	switch (ctrl->id) {
1230*5fcf092eSHyungwoo Yang 	case V4L2_CID_ANALOGUE_GAIN:
1231*5fcf092eSHyungwoo Yang 		ret = ov13858_write_reg(ov13858, OV13858_REG_ANALOG_GAIN,
1232*5fcf092eSHyungwoo Yang 					OV13858_REG_VALUE_16BIT, ctrl->val);
1233*5fcf092eSHyungwoo Yang 		break;
1234*5fcf092eSHyungwoo Yang 	case V4L2_CID_DIGITAL_GAIN:
1235*5fcf092eSHyungwoo Yang 		ret = ov13858_update_digital_gain(ov13858, ctrl->val);
1236*5fcf092eSHyungwoo Yang 		break;
1237*5fcf092eSHyungwoo Yang 	case V4L2_CID_EXPOSURE:
1238*5fcf092eSHyungwoo Yang 		ret = ov13858_write_reg(ov13858, OV13858_REG_EXPOSURE,
1239*5fcf092eSHyungwoo Yang 					OV13858_REG_VALUE_24BIT,
1240*5fcf092eSHyungwoo Yang 					ctrl->val << 4);
1241*5fcf092eSHyungwoo Yang 		break;
1242*5fcf092eSHyungwoo Yang 	case V4L2_CID_VBLANK:
1243*5fcf092eSHyungwoo Yang 		/* Update VTS that meets expected vertical blanking */
1244*5fcf092eSHyungwoo Yang 		ret = ov13858_write_reg(ov13858, OV13858_REG_VTS,
1245*5fcf092eSHyungwoo Yang 					OV13858_REG_VALUE_16BIT,
1246*5fcf092eSHyungwoo Yang 					ov13858->cur_mode->height
1247*5fcf092eSHyungwoo Yang 					  + ctrl->val);
1248*5fcf092eSHyungwoo Yang 		break;
1249*5fcf092eSHyungwoo Yang 	case V4L2_CID_TEST_PATTERN:
1250*5fcf092eSHyungwoo Yang 		ret = ov13858_enable_test_pattern(ov13858, ctrl->val);
1251*5fcf092eSHyungwoo Yang 		break;
1252*5fcf092eSHyungwoo Yang 	default:
1253*5fcf092eSHyungwoo Yang 		dev_info(&client->dev,
1254*5fcf092eSHyungwoo Yang 			 "ctrl(id:0x%x,val:0x%x) is not handled\n",
1255*5fcf092eSHyungwoo Yang 			 ctrl->id, ctrl->val);
1256*5fcf092eSHyungwoo Yang 		break;
1257*5fcf092eSHyungwoo Yang 	};
1258*5fcf092eSHyungwoo Yang 
1259*5fcf092eSHyungwoo Yang 	pm_runtime_put(&client->dev);
1260*5fcf092eSHyungwoo Yang 
1261*5fcf092eSHyungwoo Yang 	return ret;
1262*5fcf092eSHyungwoo Yang }
1263*5fcf092eSHyungwoo Yang 
1264*5fcf092eSHyungwoo Yang static const struct v4l2_ctrl_ops ov13858_ctrl_ops = {
1265*5fcf092eSHyungwoo Yang 	.s_ctrl = ov13858_set_ctrl,
1266*5fcf092eSHyungwoo Yang };
1267*5fcf092eSHyungwoo Yang 
1268*5fcf092eSHyungwoo Yang static int ov13858_enum_mbus_code(struct v4l2_subdev *sd,
1269*5fcf092eSHyungwoo Yang 				  struct v4l2_subdev_pad_config *cfg,
1270*5fcf092eSHyungwoo Yang 				  struct v4l2_subdev_mbus_code_enum *code)
1271*5fcf092eSHyungwoo Yang {
1272*5fcf092eSHyungwoo Yang 	/* Only one bayer order(GRBG) is supported */
1273*5fcf092eSHyungwoo Yang 	if (code->index > 0)
1274*5fcf092eSHyungwoo Yang 		return -EINVAL;
1275*5fcf092eSHyungwoo Yang 
1276*5fcf092eSHyungwoo Yang 	code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
1277*5fcf092eSHyungwoo Yang 
1278*5fcf092eSHyungwoo Yang 	return 0;
1279*5fcf092eSHyungwoo Yang }
1280*5fcf092eSHyungwoo Yang 
1281*5fcf092eSHyungwoo Yang static int ov13858_enum_frame_size(struct v4l2_subdev *sd,
1282*5fcf092eSHyungwoo Yang 				   struct v4l2_subdev_pad_config *cfg,
1283*5fcf092eSHyungwoo Yang 				   struct v4l2_subdev_frame_size_enum *fse)
1284*5fcf092eSHyungwoo Yang {
1285*5fcf092eSHyungwoo Yang 	if (fse->index >= ARRAY_SIZE(supported_modes))
1286*5fcf092eSHyungwoo Yang 		return -EINVAL;
1287*5fcf092eSHyungwoo Yang 
1288*5fcf092eSHyungwoo Yang 	if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
1289*5fcf092eSHyungwoo Yang 		return -EINVAL;
1290*5fcf092eSHyungwoo Yang 
1291*5fcf092eSHyungwoo Yang 	fse->min_width = supported_modes[fse->index].width;
1292*5fcf092eSHyungwoo Yang 	fse->max_width = fse->min_width;
1293*5fcf092eSHyungwoo Yang 	fse->min_height = supported_modes[fse->index].height;
1294*5fcf092eSHyungwoo Yang 	fse->max_height = fse->min_height;
1295*5fcf092eSHyungwoo Yang 
1296*5fcf092eSHyungwoo Yang 	return 0;
1297*5fcf092eSHyungwoo Yang }
1298*5fcf092eSHyungwoo Yang 
1299*5fcf092eSHyungwoo Yang static void ov13858_update_pad_format(const struct ov13858_mode *mode,
1300*5fcf092eSHyungwoo Yang 				      struct v4l2_subdev_format *fmt)
1301*5fcf092eSHyungwoo Yang {
1302*5fcf092eSHyungwoo Yang 	fmt->format.width = mode->width;
1303*5fcf092eSHyungwoo Yang 	fmt->format.height = mode->height;
1304*5fcf092eSHyungwoo Yang 	fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
1305*5fcf092eSHyungwoo Yang 	fmt->format.field = V4L2_FIELD_NONE;
1306*5fcf092eSHyungwoo Yang }
1307*5fcf092eSHyungwoo Yang 
1308*5fcf092eSHyungwoo Yang static int ov13858_do_get_pad_format(struct ov13858 *ov13858,
1309*5fcf092eSHyungwoo Yang 				     struct v4l2_subdev_pad_config *cfg,
1310*5fcf092eSHyungwoo Yang 				     struct v4l2_subdev_format *fmt)
1311*5fcf092eSHyungwoo Yang {
1312*5fcf092eSHyungwoo Yang 	struct v4l2_mbus_framefmt *framefmt;
1313*5fcf092eSHyungwoo Yang 	struct v4l2_subdev *sd = &ov13858->sd;
1314*5fcf092eSHyungwoo Yang 
1315*5fcf092eSHyungwoo Yang 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1316*5fcf092eSHyungwoo Yang 		framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1317*5fcf092eSHyungwoo Yang 		fmt->format = *framefmt;
1318*5fcf092eSHyungwoo Yang 	} else {
1319*5fcf092eSHyungwoo Yang 		ov13858_update_pad_format(ov13858->cur_mode, fmt);
1320*5fcf092eSHyungwoo Yang 	}
1321*5fcf092eSHyungwoo Yang 
1322*5fcf092eSHyungwoo Yang 	return 0;
1323*5fcf092eSHyungwoo Yang }
1324*5fcf092eSHyungwoo Yang 
1325*5fcf092eSHyungwoo Yang static int ov13858_get_pad_format(struct v4l2_subdev *sd,
1326*5fcf092eSHyungwoo Yang 				  struct v4l2_subdev_pad_config *cfg,
1327*5fcf092eSHyungwoo Yang 				  struct v4l2_subdev_format *fmt)
1328*5fcf092eSHyungwoo Yang {
1329*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1330*5fcf092eSHyungwoo Yang 	int ret;
1331*5fcf092eSHyungwoo Yang 
1332*5fcf092eSHyungwoo Yang 	mutex_lock(&ov13858->mutex);
1333*5fcf092eSHyungwoo Yang 	ret = ov13858_do_get_pad_format(ov13858, cfg, fmt);
1334*5fcf092eSHyungwoo Yang 	mutex_unlock(&ov13858->mutex);
1335*5fcf092eSHyungwoo Yang 
1336*5fcf092eSHyungwoo Yang 	return ret;
1337*5fcf092eSHyungwoo Yang }
1338*5fcf092eSHyungwoo Yang 
1339*5fcf092eSHyungwoo Yang /*
1340*5fcf092eSHyungwoo Yang  * Calculate resolution distance
1341*5fcf092eSHyungwoo Yang  */
1342*5fcf092eSHyungwoo Yang static int
1343*5fcf092eSHyungwoo Yang ov13858_get_resolution_dist(const struct ov13858_mode *mode,
1344*5fcf092eSHyungwoo Yang 			    struct v4l2_mbus_framefmt *framefmt)
1345*5fcf092eSHyungwoo Yang {
1346*5fcf092eSHyungwoo Yang 	return abs(mode->width - framefmt->width) +
1347*5fcf092eSHyungwoo Yang 	       abs(mode->height - framefmt->height);
1348*5fcf092eSHyungwoo Yang }
1349*5fcf092eSHyungwoo Yang 
1350*5fcf092eSHyungwoo Yang /*
1351*5fcf092eSHyungwoo Yang  * Find the closest supported resolution to the requested resolution
1352*5fcf092eSHyungwoo Yang  */
1353*5fcf092eSHyungwoo Yang static const struct ov13858_mode *
1354*5fcf092eSHyungwoo Yang ov13858_find_best_fit(struct ov13858 *ov13858,
1355*5fcf092eSHyungwoo Yang 		      struct v4l2_subdev_format *fmt)
1356*5fcf092eSHyungwoo Yang {
1357*5fcf092eSHyungwoo Yang 	int i, dist, cur_best_fit = 0, cur_best_fit_dist = -1;
1358*5fcf092eSHyungwoo Yang 	struct v4l2_mbus_framefmt *framefmt = &fmt->format;
1359*5fcf092eSHyungwoo Yang 
1360*5fcf092eSHyungwoo Yang 	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1361*5fcf092eSHyungwoo Yang 		dist = ov13858_get_resolution_dist(&supported_modes[i],
1362*5fcf092eSHyungwoo Yang 						   framefmt);
1363*5fcf092eSHyungwoo Yang 		if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
1364*5fcf092eSHyungwoo Yang 			cur_best_fit_dist = dist;
1365*5fcf092eSHyungwoo Yang 			cur_best_fit = i;
1366*5fcf092eSHyungwoo Yang 		}
1367*5fcf092eSHyungwoo Yang 	}
1368*5fcf092eSHyungwoo Yang 
1369*5fcf092eSHyungwoo Yang 	return &supported_modes[cur_best_fit];
1370*5fcf092eSHyungwoo Yang }
1371*5fcf092eSHyungwoo Yang 
1372*5fcf092eSHyungwoo Yang static int
1373*5fcf092eSHyungwoo Yang ov13858_set_pad_format(struct v4l2_subdev *sd,
1374*5fcf092eSHyungwoo Yang 		       struct v4l2_subdev_pad_config *cfg,
1375*5fcf092eSHyungwoo Yang 		       struct v4l2_subdev_format *fmt)
1376*5fcf092eSHyungwoo Yang {
1377*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1378*5fcf092eSHyungwoo Yang 	const struct ov13858_mode *mode;
1379*5fcf092eSHyungwoo Yang 	struct v4l2_mbus_framefmt *framefmt;
1380*5fcf092eSHyungwoo Yang 	s64 h_blank;
1381*5fcf092eSHyungwoo Yang 
1382*5fcf092eSHyungwoo Yang 	mutex_lock(&ov13858->mutex);
1383*5fcf092eSHyungwoo Yang 
1384*5fcf092eSHyungwoo Yang 	/* Only one raw bayer(GRBG) order is supported */
1385*5fcf092eSHyungwoo Yang 	if (fmt->format.code != MEDIA_BUS_FMT_SGRBG10_1X10)
1386*5fcf092eSHyungwoo Yang 		fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
1387*5fcf092eSHyungwoo Yang 
1388*5fcf092eSHyungwoo Yang 	mode = ov13858_find_best_fit(ov13858, fmt);
1389*5fcf092eSHyungwoo Yang 	ov13858_update_pad_format(mode, fmt);
1390*5fcf092eSHyungwoo Yang 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1391*5fcf092eSHyungwoo Yang 		framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1392*5fcf092eSHyungwoo Yang 		*framefmt = fmt->format;
1393*5fcf092eSHyungwoo Yang 	} else {
1394*5fcf092eSHyungwoo Yang 		ov13858->cur_mode = mode;
1395*5fcf092eSHyungwoo Yang 		__v4l2_ctrl_s_ctrl(ov13858->link_freq, mode->link_freq_index);
1396*5fcf092eSHyungwoo Yang 		__v4l2_ctrl_s_ctrl_int64(
1397*5fcf092eSHyungwoo Yang 			ov13858->pixel_rate,
1398*5fcf092eSHyungwoo Yang 			link_freq_configs[mode->link_freq_index].pixel_rate);
1399*5fcf092eSHyungwoo Yang 		/* Update limits and set FPS to default */
1400*5fcf092eSHyungwoo Yang 		__v4l2_ctrl_modify_range(
1401*5fcf092eSHyungwoo Yang 			ov13858->vblank, OV13858_VBLANK_MIN,
1402*5fcf092eSHyungwoo Yang 			OV13858_VTS_MAX - ov13858->cur_mode->height, 1,
1403*5fcf092eSHyungwoo Yang 			ov13858->cur_mode->vts - ov13858->cur_mode->height);
1404*5fcf092eSHyungwoo Yang 		h_blank =
1405*5fcf092eSHyungwoo Yang 			link_freq_configs[mode->link_freq_index].pixels_per_line
1406*5fcf092eSHyungwoo Yang 			 - ov13858->cur_mode->width;
1407*5fcf092eSHyungwoo Yang 		__v4l2_ctrl_modify_range(ov13858->hblank, h_blank,
1408*5fcf092eSHyungwoo Yang 					 h_blank, 1, h_blank);
1409*5fcf092eSHyungwoo Yang 	}
1410*5fcf092eSHyungwoo Yang 
1411*5fcf092eSHyungwoo Yang 	mutex_unlock(&ov13858->mutex);
1412*5fcf092eSHyungwoo Yang 
1413*5fcf092eSHyungwoo Yang 	return 0;
1414*5fcf092eSHyungwoo Yang }
1415*5fcf092eSHyungwoo Yang 
1416*5fcf092eSHyungwoo Yang static int ov13858_get_skip_frames(struct v4l2_subdev *sd, u32 *frames)
1417*5fcf092eSHyungwoo Yang {
1418*5fcf092eSHyungwoo Yang 	*frames = OV13858_NUM_OF_SKIP_FRAMES;
1419*5fcf092eSHyungwoo Yang 
1420*5fcf092eSHyungwoo Yang 	return 0;
1421*5fcf092eSHyungwoo Yang }
1422*5fcf092eSHyungwoo Yang 
1423*5fcf092eSHyungwoo Yang /* Start streaming */
1424*5fcf092eSHyungwoo Yang static int ov13858_start_streaming(struct ov13858 *ov13858)
1425*5fcf092eSHyungwoo Yang {
1426*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1427*5fcf092eSHyungwoo Yang 	const struct ov13858_reg_list *reg_list;
1428*5fcf092eSHyungwoo Yang 	int ret, link_freq_index;
1429*5fcf092eSHyungwoo Yang 
1430*5fcf092eSHyungwoo Yang 	/* Get out of from software reset */
1431*5fcf092eSHyungwoo Yang 	ret = ov13858_write_reg(ov13858, OV13858_REG_SOFTWARE_RST,
1432*5fcf092eSHyungwoo Yang 				OV13858_REG_VALUE_08BIT, OV13858_SOFTWARE_RST);
1433*5fcf092eSHyungwoo Yang 	if (ret) {
1434*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "%s failed to set powerup registers\n",
1435*5fcf092eSHyungwoo Yang 			__func__);
1436*5fcf092eSHyungwoo Yang 		return ret;
1437*5fcf092eSHyungwoo Yang 	}
1438*5fcf092eSHyungwoo Yang 
1439*5fcf092eSHyungwoo Yang 	/* Setup PLL */
1440*5fcf092eSHyungwoo Yang 	link_freq_index = ov13858->cur_mode->link_freq_index;
1441*5fcf092eSHyungwoo Yang 	reg_list = &link_freq_configs[link_freq_index].reg_list;
1442*5fcf092eSHyungwoo Yang 	ret = ov13858_write_reg_list(ov13858, reg_list);
1443*5fcf092eSHyungwoo Yang 	if (ret) {
1444*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "%s failed to set plls\n", __func__);
1445*5fcf092eSHyungwoo Yang 		return ret;
1446*5fcf092eSHyungwoo Yang 	}
1447*5fcf092eSHyungwoo Yang 
1448*5fcf092eSHyungwoo Yang 	/* Apply default values of current mode */
1449*5fcf092eSHyungwoo Yang 	reg_list = &ov13858->cur_mode->reg_list;
1450*5fcf092eSHyungwoo Yang 	ret = ov13858_write_reg_list(ov13858, reg_list);
1451*5fcf092eSHyungwoo Yang 	if (ret) {
1452*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "%s failed to set mode\n", __func__);
1453*5fcf092eSHyungwoo Yang 		return ret;
1454*5fcf092eSHyungwoo Yang 	}
1455*5fcf092eSHyungwoo Yang 
1456*5fcf092eSHyungwoo Yang 	/* Apply customized values from user */
1457*5fcf092eSHyungwoo Yang 	ret =  __v4l2_ctrl_handler_setup(ov13858->sd.ctrl_handler);
1458*5fcf092eSHyungwoo Yang 	if (ret)
1459*5fcf092eSHyungwoo Yang 		return ret;
1460*5fcf092eSHyungwoo Yang 
1461*5fcf092eSHyungwoo Yang 	return ov13858_write_reg(ov13858, OV13858_REG_MODE_SELECT,
1462*5fcf092eSHyungwoo Yang 				 OV13858_REG_VALUE_08BIT,
1463*5fcf092eSHyungwoo Yang 				 OV13858_MODE_STREAMING);
1464*5fcf092eSHyungwoo Yang }
1465*5fcf092eSHyungwoo Yang 
1466*5fcf092eSHyungwoo Yang /* Stop streaming */
1467*5fcf092eSHyungwoo Yang static int ov13858_stop_streaming(struct ov13858 *ov13858)
1468*5fcf092eSHyungwoo Yang {
1469*5fcf092eSHyungwoo Yang 	return ov13858_write_reg(ov13858, OV13858_REG_MODE_SELECT,
1470*5fcf092eSHyungwoo Yang 				 OV13858_REG_VALUE_08BIT, OV13858_MODE_STANDBY);
1471*5fcf092eSHyungwoo Yang }
1472*5fcf092eSHyungwoo Yang 
1473*5fcf092eSHyungwoo Yang static int ov13858_set_stream(struct v4l2_subdev *sd, int enable)
1474*5fcf092eSHyungwoo Yang {
1475*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1476*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(sd);
1477*5fcf092eSHyungwoo Yang 	int ret = 0;
1478*5fcf092eSHyungwoo Yang 
1479*5fcf092eSHyungwoo Yang 	mutex_lock(&ov13858->mutex);
1480*5fcf092eSHyungwoo Yang 	if (ov13858->streaming == enable) {
1481*5fcf092eSHyungwoo Yang 		mutex_unlock(&ov13858->mutex);
1482*5fcf092eSHyungwoo Yang 		return 0;
1483*5fcf092eSHyungwoo Yang 	}
1484*5fcf092eSHyungwoo Yang 
1485*5fcf092eSHyungwoo Yang 	if (enable) {
1486*5fcf092eSHyungwoo Yang 		ret = pm_runtime_get_sync(&client->dev);
1487*5fcf092eSHyungwoo Yang 		if (ret < 0) {
1488*5fcf092eSHyungwoo Yang 			pm_runtime_put_noidle(&client->dev);
1489*5fcf092eSHyungwoo Yang 			goto err_unlock;
1490*5fcf092eSHyungwoo Yang 		}
1491*5fcf092eSHyungwoo Yang 
1492*5fcf092eSHyungwoo Yang 		/*
1493*5fcf092eSHyungwoo Yang 		 * Apply default & customized values
1494*5fcf092eSHyungwoo Yang 		 * and then start streaming.
1495*5fcf092eSHyungwoo Yang 		 */
1496*5fcf092eSHyungwoo Yang 		ret = ov13858_start_streaming(ov13858);
1497*5fcf092eSHyungwoo Yang 		if (ret)
1498*5fcf092eSHyungwoo Yang 			goto err_rpm_put;
1499*5fcf092eSHyungwoo Yang 	} else {
1500*5fcf092eSHyungwoo Yang 		ov13858_stop_streaming(ov13858);
1501*5fcf092eSHyungwoo Yang 		pm_runtime_put(&client->dev);
1502*5fcf092eSHyungwoo Yang 	}
1503*5fcf092eSHyungwoo Yang 
1504*5fcf092eSHyungwoo Yang 	ov13858->streaming = enable;
1505*5fcf092eSHyungwoo Yang 	mutex_unlock(&ov13858->mutex);
1506*5fcf092eSHyungwoo Yang 
1507*5fcf092eSHyungwoo Yang 	return ret;
1508*5fcf092eSHyungwoo Yang 
1509*5fcf092eSHyungwoo Yang err_rpm_put:
1510*5fcf092eSHyungwoo Yang 	pm_runtime_put(&client->dev);
1511*5fcf092eSHyungwoo Yang err_unlock:
1512*5fcf092eSHyungwoo Yang 	mutex_unlock(&ov13858->mutex);
1513*5fcf092eSHyungwoo Yang 
1514*5fcf092eSHyungwoo Yang 	return ret;
1515*5fcf092eSHyungwoo Yang }
1516*5fcf092eSHyungwoo Yang 
1517*5fcf092eSHyungwoo Yang static int __maybe_unused ov13858_suspend(struct device *dev)
1518*5fcf092eSHyungwoo Yang {
1519*5fcf092eSHyungwoo Yang 	struct i2c_client *client = to_i2c_client(dev);
1520*5fcf092eSHyungwoo Yang 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1521*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1522*5fcf092eSHyungwoo Yang 
1523*5fcf092eSHyungwoo Yang 	if (ov13858->streaming)
1524*5fcf092eSHyungwoo Yang 		ov13858_stop_streaming(ov13858);
1525*5fcf092eSHyungwoo Yang 
1526*5fcf092eSHyungwoo Yang 	return 0;
1527*5fcf092eSHyungwoo Yang }
1528*5fcf092eSHyungwoo Yang 
1529*5fcf092eSHyungwoo Yang static int __maybe_unused ov13858_resume(struct device *dev)
1530*5fcf092eSHyungwoo Yang {
1531*5fcf092eSHyungwoo Yang 	struct i2c_client *client = to_i2c_client(dev);
1532*5fcf092eSHyungwoo Yang 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1533*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1534*5fcf092eSHyungwoo Yang 	int ret;
1535*5fcf092eSHyungwoo Yang 
1536*5fcf092eSHyungwoo Yang 	if (ov13858->streaming) {
1537*5fcf092eSHyungwoo Yang 		ret = ov13858_start_streaming(ov13858);
1538*5fcf092eSHyungwoo Yang 		if (ret)
1539*5fcf092eSHyungwoo Yang 			goto error;
1540*5fcf092eSHyungwoo Yang 	}
1541*5fcf092eSHyungwoo Yang 
1542*5fcf092eSHyungwoo Yang 	return 0;
1543*5fcf092eSHyungwoo Yang 
1544*5fcf092eSHyungwoo Yang error:
1545*5fcf092eSHyungwoo Yang 	ov13858_stop_streaming(ov13858);
1546*5fcf092eSHyungwoo Yang 	ov13858->streaming = 0;
1547*5fcf092eSHyungwoo Yang 	return ret;
1548*5fcf092eSHyungwoo Yang }
1549*5fcf092eSHyungwoo Yang 
1550*5fcf092eSHyungwoo Yang /* Verify chip ID */
1551*5fcf092eSHyungwoo Yang static int ov13858_identify_module(struct ov13858 *ov13858)
1552*5fcf092eSHyungwoo Yang {
1553*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1554*5fcf092eSHyungwoo Yang 	int ret;
1555*5fcf092eSHyungwoo Yang 	u32 val;
1556*5fcf092eSHyungwoo Yang 
1557*5fcf092eSHyungwoo Yang 	ret = ov13858_read_reg(ov13858, OV13858_REG_CHIP_ID,
1558*5fcf092eSHyungwoo Yang 			       OV13858_REG_VALUE_24BIT, &val);
1559*5fcf092eSHyungwoo Yang 	if (ret)
1560*5fcf092eSHyungwoo Yang 		return ret;
1561*5fcf092eSHyungwoo Yang 
1562*5fcf092eSHyungwoo Yang 	if (val != OV13858_CHIP_ID) {
1563*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1564*5fcf092eSHyungwoo Yang 			OV13858_CHIP_ID, val);
1565*5fcf092eSHyungwoo Yang 		return -EIO;
1566*5fcf092eSHyungwoo Yang 	}
1567*5fcf092eSHyungwoo Yang 
1568*5fcf092eSHyungwoo Yang 	return 0;
1569*5fcf092eSHyungwoo Yang }
1570*5fcf092eSHyungwoo Yang 
1571*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_video_ops ov13858_video_ops = {
1572*5fcf092eSHyungwoo Yang 	.s_stream = ov13858_set_stream,
1573*5fcf092eSHyungwoo Yang };
1574*5fcf092eSHyungwoo Yang 
1575*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_pad_ops ov13858_pad_ops = {
1576*5fcf092eSHyungwoo Yang 	.enum_mbus_code = ov13858_enum_mbus_code,
1577*5fcf092eSHyungwoo Yang 	.get_fmt = ov13858_get_pad_format,
1578*5fcf092eSHyungwoo Yang 	.set_fmt = ov13858_set_pad_format,
1579*5fcf092eSHyungwoo Yang 	.enum_frame_size = ov13858_enum_frame_size,
1580*5fcf092eSHyungwoo Yang };
1581*5fcf092eSHyungwoo Yang 
1582*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_sensor_ops ov13858_sensor_ops = {
1583*5fcf092eSHyungwoo Yang 	.g_skip_frames = ov13858_get_skip_frames,
1584*5fcf092eSHyungwoo Yang };
1585*5fcf092eSHyungwoo Yang 
1586*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_ops ov13858_subdev_ops = {
1587*5fcf092eSHyungwoo Yang 	.video = &ov13858_video_ops,
1588*5fcf092eSHyungwoo Yang 	.pad = &ov13858_pad_ops,
1589*5fcf092eSHyungwoo Yang 	.sensor = &ov13858_sensor_ops,
1590*5fcf092eSHyungwoo Yang };
1591*5fcf092eSHyungwoo Yang 
1592*5fcf092eSHyungwoo Yang static const struct media_entity_operations ov13858_subdev_entity_ops = {
1593*5fcf092eSHyungwoo Yang 	.link_validate = v4l2_subdev_link_validate,
1594*5fcf092eSHyungwoo Yang };
1595*5fcf092eSHyungwoo Yang 
1596*5fcf092eSHyungwoo Yang static const struct v4l2_subdev_internal_ops ov13858_internal_ops = {
1597*5fcf092eSHyungwoo Yang 	.open = ov13858_open,
1598*5fcf092eSHyungwoo Yang };
1599*5fcf092eSHyungwoo Yang 
1600*5fcf092eSHyungwoo Yang /* Initialize control handlers */
1601*5fcf092eSHyungwoo Yang static int ov13858_init_controls(struct ov13858 *ov13858)
1602*5fcf092eSHyungwoo Yang {
1603*5fcf092eSHyungwoo Yang 	struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
1604*5fcf092eSHyungwoo Yang 	struct v4l2_ctrl_handler *ctrl_hdlr;
1605*5fcf092eSHyungwoo Yang 	int ret;
1606*5fcf092eSHyungwoo Yang 
1607*5fcf092eSHyungwoo Yang 	ctrl_hdlr = &ov13858->ctrl_handler;
1608*5fcf092eSHyungwoo Yang 	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
1609*5fcf092eSHyungwoo Yang 	if (ret)
1610*5fcf092eSHyungwoo Yang 		return ret;
1611*5fcf092eSHyungwoo Yang 
1612*5fcf092eSHyungwoo Yang 	mutex_init(&ov13858->mutex);
1613*5fcf092eSHyungwoo Yang 	ctrl_hdlr->lock = &ov13858->mutex;
1614*5fcf092eSHyungwoo Yang 	ov13858->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
1615*5fcf092eSHyungwoo Yang 				&ov13858_ctrl_ops,
1616*5fcf092eSHyungwoo Yang 				V4L2_CID_LINK_FREQ,
1617*5fcf092eSHyungwoo Yang 				OV13858_NUM_OF_LINK_FREQS - 1,
1618*5fcf092eSHyungwoo Yang 				0,
1619*5fcf092eSHyungwoo Yang 				link_freq_menu_items);
1620*5fcf092eSHyungwoo Yang 	ov13858->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1621*5fcf092eSHyungwoo Yang 
1622*5fcf092eSHyungwoo Yang 	/* By default, PIXEL_RATE is read only */
1623*5fcf092eSHyungwoo Yang 	ov13858->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops,
1624*5fcf092eSHyungwoo Yang 					V4L2_CID_PIXEL_RATE, 0,
1625*5fcf092eSHyungwoo Yang 					link_freq_configs[0].pixel_rate, 1,
1626*5fcf092eSHyungwoo Yang 					link_freq_configs[0].pixel_rate);
1627*5fcf092eSHyungwoo Yang 
1628*5fcf092eSHyungwoo Yang 	ov13858->vblank = v4l2_ctrl_new_std(
1629*5fcf092eSHyungwoo Yang 				ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VBLANK,
1630*5fcf092eSHyungwoo Yang 				OV13858_VBLANK_MIN,
1631*5fcf092eSHyungwoo Yang 				OV13858_VTS_MAX - ov13858->cur_mode->height, 1,
1632*5fcf092eSHyungwoo Yang 				ov13858->cur_mode->vts
1633*5fcf092eSHyungwoo Yang 				  - ov13858->cur_mode->height);
1634*5fcf092eSHyungwoo Yang 
1635*5fcf092eSHyungwoo Yang 	ov13858->hblank = v4l2_ctrl_new_std(
1636*5fcf092eSHyungwoo Yang 				ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK,
1637*5fcf092eSHyungwoo Yang 				OV13858_PPL_1080MHZ - ov13858->cur_mode->width,
1638*5fcf092eSHyungwoo Yang 				OV13858_PPL_1080MHZ - ov13858->cur_mode->width,
1639*5fcf092eSHyungwoo Yang 				1,
1640*5fcf092eSHyungwoo Yang 				OV13858_PPL_1080MHZ - ov13858->cur_mode->width);
1641*5fcf092eSHyungwoo Yang 	ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1642*5fcf092eSHyungwoo Yang 
1643*5fcf092eSHyungwoo Yang 	ov13858->exposure = v4l2_ctrl_new_std(
1644*5fcf092eSHyungwoo Yang 				ctrl_hdlr, &ov13858_ctrl_ops,
1645*5fcf092eSHyungwoo Yang 				V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN,
1646*5fcf092eSHyungwoo Yang 				OV13858_EXPOSURE_MAX, OV13858_EXPOSURE_STEP,
1647*5fcf092eSHyungwoo Yang 				OV13858_EXPOSURE_DEFAULT);
1648*5fcf092eSHyungwoo Yang 
1649*5fcf092eSHyungwoo Yang 	v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1650*5fcf092eSHyungwoo Yang 			  OV13858_ANA_GAIN_MIN, OV13858_ANA_GAIN_MAX,
1651*5fcf092eSHyungwoo Yang 			  OV13858_ANA_GAIN_STEP, OV13858_ANA_GAIN_DEFAULT);
1652*5fcf092eSHyungwoo Yang 
1653*5fcf092eSHyungwoo Yang 	/* Digital gain */
1654*5fcf092eSHyungwoo Yang 	v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1655*5fcf092eSHyungwoo Yang 			  OV13858_DGTL_GAIN_MIN, OV13858_DGTL_GAIN_MAX,
1656*5fcf092eSHyungwoo Yang 			  OV13858_DGTL_GAIN_STEP, OV13858_DGTL_GAIN_DEFAULT);
1657*5fcf092eSHyungwoo Yang 
1658*5fcf092eSHyungwoo Yang 	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov13858_ctrl_ops,
1659*5fcf092eSHyungwoo Yang 				     V4L2_CID_TEST_PATTERN,
1660*5fcf092eSHyungwoo Yang 				     ARRAY_SIZE(ov13858_test_pattern_menu) - 1,
1661*5fcf092eSHyungwoo Yang 				     0, 0, ov13858_test_pattern_menu);
1662*5fcf092eSHyungwoo Yang 	if (ctrl_hdlr->error) {
1663*5fcf092eSHyungwoo Yang 		ret = ctrl_hdlr->error;
1664*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "%s control init failed (%d)\n",
1665*5fcf092eSHyungwoo Yang 			__func__, ret);
1666*5fcf092eSHyungwoo Yang 		goto error;
1667*5fcf092eSHyungwoo Yang 	}
1668*5fcf092eSHyungwoo Yang 
1669*5fcf092eSHyungwoo Yang 	ov13858->sd.ctrl_handler = ctrl_hdlr;
1670*5fcf092eSHyungwoo Yang 
1671*5fcf092eSHyungwoo Yang 	return 0;
1672*5fcf092eSHyungwoo Yang 
1673*5fcf092eSHyungwoo Yang error:
1674*5fcf092eSHyungwoo Yang 	v4l2_ctrl_handler_free(ctrl_hdlr);
1675*5fcf092eSHyungwoo Yang 	mutex_destroy(&ov13858->mutex);
1676*5fcf092eSHyungwoo Yang 
1677*5fcf092eSHyungwoo Yang 	return ret;
1678*5fcf092eSHyungwoo Yang }
1679*5fcf092eSHyungwoo Yang 
1680*5fcf092eSHyungwoo Yang static void ov13858_free_controls(struct ov13858 *ov13858)
1681*5fcf092eSHyungwoo Yang {
1682*5fcf092eSHyungwoo Yang 	v4l2_ctrl_handler_free(ov13858->sd.ctrl_handler);
1683*5fcf092eSHyungwoo Yang 	mutex_destroy(&ov13858->mutex);
1684*5fcf092eSHyungwoo Yang }
1685*5fcf092eSHyungwoo Yang 
1686*5fcf092eSHyungwoo Yang static int ov13858_probe(struct i2c_client *client,
1687*5fcf092eSHyungwoo Yang 			 const struct i2c_device_id *devid)
1688*5fcf092eSHyungwoo Yang {
1689*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858;
1690*5fcf092eSHyungwoo Yang 	int ret;
1691*5fcf092eSHyungwoo Yang 	u32 val = 0;
1692*5fcf092eSHyungwoo Yang 
1693*5fcf092eSHyungwoo Yang 	device_property_read_u32(&client->dev, "clock-frequency", &val);
1694*5fcf092eSHyungwoo Yang 	if (val != 19200000)
1695*5fcf092eSHyungwoo Yang 		return -EINVAL;
1696*5fcf092eSHyungwoo Yang 
1697*5fcf092eSHyungwoo Yang 	ov13858 = devm_kzalloc(&client->dev, sizeof(*ov13858), GFP_KERNEL);
1698*5fcf092eSHyungwoo Yang 	if (!ov13858)
1699*5fcf092eSHyungwoo Yang 		return -ENOMEM;
1700*5fcf092eSHyungwoo Yang 
1701*5fcf092eSHyungwoo Yang 	/* Initialize subdev */
1702*5fcf092eSHyungwoo Yang 	v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops);
1703*5fcf092eSHyungwoo Yang 
1704*5fcf092eSHyungwoo Yang 	/* Check module identity */
1705*5fcf092eSHyungwoo Yang 	ret = ov13858_identify_module(ov13858);
1706*5fcf092eSHyungwoo Yang 	if (ret) {
1707*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "failed to find sensor: %d\n", ret);
1708*5fcf092eSHyungwoo Yang 		return ret;
1709*5fcf092eSHyungwoo Yang 	}
1710*5fcf092eSHyungwoo Yang 
1711*5fcf092eSHyungwoo Yang 	/* Set default mode to max resolution */
1712*5fcf092eSHyungwoo Yang 	ov13858->cur_mode = &supported_modes[0];
1713*5fcf092eSHyungwoo Yang 
1714*5fcf092eSHyungwoo Yang 	ret = ov13858_init_controls(ov13858);
1715*5fcf092eSHyungwoo Yang 	if (ret)
1716*5fcf092eSHyungwoo Yang 		return ret;
1717*5fcf092eSHyungwoo Yang 
1718*5fcf092eSHyungwoo Yang 	/* Initialize subdev */
1719*5fcf092eSHyungwoo Yang 	ov13858->sd.internal_ops = &ov13858_internal_ops;
1720*5fcf092eSHyungwoo Yang 	ov13858->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1721*5fcf092eSHyungwoo Yang 	ov13858->sd.entity.ops = &ov13858_subdev_entity_ops;
1722*5fcf092eSHyungwoo Yang 	ov13858->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1723*5fcf092eSHyungwoo Yang 
1724*5fcf092eSHyungwoo Yang 	/* Initialize source pad */
1725*5fcf092eSHyungwoo Yang 	ov13858->pad.flags = MEDIA_PAD_FL_SOURCE;
1726*5fcf092eSHyungwoo Yang 	ret = media_entity_pads_init(&ov13858->sd.entity, 1, &ov13858->pad);
1727*5fcf092eSHyungwoo Yang 	if (ret) {
1728*5fcf092eSHyungwoo Yang 		dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
1729*5fcf092eSHyungwoo Yang 		goto error_handler_free;
1730*5fcf092eSHyungwoo Yang 	}
1731*5fcf092eSHyungwoo Yang 
1732*5fcf092eSHyungwoo Yang 	ret = v4l2_async_register_subdev(&ov13858->sd);
1733*5fcf092eSHyungwoo Yang 	if (ret < 0)
1734*5fcf092eSHyungwoo Yang 		goto error_media_entity;
1735*5fcf092eSHyungwoo Yang 
1736*5fcf092eSHyungwoo Yang 	/*
1737*5fcf092eSHyungwoo Yang 	 * Device is already turned on by i2c-core with ACPI domain PM.
1738*5fcf092eSHyungwoo Yang 	 * Enable runtime PM and turn off the device.
1739*5fcf092eSHyungwoo Yang 	 */
1740*5fcf092eSHyungwoo Yang 	pm_runtime_get_noresume(&client->dev);
1741*5fcf092eSHyungwoo Yang 	pm_runtime_set_active(&client->dev);
1742*5fcf092eSHyungwoo Yang 	pm_runtime_enable(&client->dev);
1743*5fcf092eSHyungwoo Yang 	pm_runtime_put(&client->dev);
1744*5fcf092eSHyungwoo Yang 
1745*5fcf092eSHyungwoo Yang 	return 0;
1746*5fcf092eSHyungwoo Yang 
1747*5fcf092eSHyungwoo Yang error_media_entity:
1748*5fcf092eSHyungwoo Yang 	media_entity_cleanup(&ov13858->sd.entity);
1749*5fcf092eSHyungwoo Yang 
1750*5fcf092eSHyungwoo Yang error_handler_free:
1751*5fcf092eSHyungwoo Yang 	ov13858_free_controls(ov13858);
1752*5fcf092eSHyungwoo Yang 	dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
1753*5fcf092eSHyungwoo Yang 
1754*5fcf092eSHyungwoo Yang 	return ret;
1755*5fcf092eSHyungwoo Yang }
1756*5fcf092eSHyungwoo Yang 
1757*5fcf092eSHyungwoo Yang static int ov13858_remove(struct i2c_client *client)
1758*5fcf092eSHyungwoo Yang {
1759*5fcf092eSHyungwoo Yang 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1760*5fcf092eSHyungwoo Yang 	struct ov13858 *ov13858 = to_ov13858(sd);
1761*5fcf092eSHyungwoo Yang 
1762*5fcf092eSHyungwoo Yang 	v4l2_async_unregister_subdev(sd);
1763*5fcf092eSHyungwoo Yang 	media_entity_cleanup(&sd->entity);
1764*5fcf092eSHyungwoo Yang 	ov13858_free_controls(ov13858);
1765*5fcf092eSHyungwoo Yang 
1766*5fcf092eSHyungwoo Yang 	/*
1767*5fcf092eSHyungwoo Yang 	 * Disable runtime PM but keep the device turned on.
1768*5fcf092eSHyungwoo Yang 	 * i2c-core with ACPI domain PM will turn off the device.
1769*5fcf092eSHyungwoo Yang 	 */
1770*5fcf092eSHyungwoo Yang 	pm_runtime_get_sync(&client->dev);
1771*5fcf092eSHyungwoo Yang 	pm_runtime_disable(&client->dev);
1772*5fcf092eSHyungwoo Yang 	pm_runtime_set_suspended(&client->dev);
1773*5fcf092eSHyungwoo Yang 	pm_runtime_put_noidle(&client->dev);
1774*5fcf092eSHyungwoo Yang 
1775*5fcf092eSHyungwoo Yang 	return 0;
1776*5fcf092eSHyungwoo Yang }
1777*5fcf092eSHyungwoo Yang 
1778*5fcf092eSHyungwoo Yang static const struct i2c_device_id ov13858_id_table[] = {
1779*5fcf092eSHyungwoo Yang 	{"ov13858", 0},
1780*5fcf092eSHyungwoo Yang 	{},
1781*5fcf092eSHyungwoo Yang };
1782*5fcf092eSHyungwoo Yang 
1783*5fcf092eSHyungwoo Yang MODULE_DEVICE_TABLE(i2c, ov13858_id_table);
1784*5fcf092eSHyungwoo Yang 
1785*5fcf092eSHyungwoo Yang static const struct dev_pm_ops ov13858_pm_ops = {
1786*5fcf092eSHyungwoo Yang 	SET_SYSTEM_SLEEP_PM_OPS(ov13858_suspend, ov13858_resume)
1787*5fcf092eSHyungwoo Yang };
1788*5fcf092eSHyungwoo Yang 
1789*5fcf092eSHyungwoo Yang #ifdef CONFIG_ACPI
1790*5fcf092eSHyungwoo Yang static const struct acpi_device_id ov13858_acpi_ids[] = {
1791*5fcf092eSHyungwoo Yang 	{"OVTID858"},
1792*5fcf092eSHyungwoo Yang 	{ /* sentinel */ }
1793*5fcf092eSHyungwoo Yang };
1794*5fcf092eSHyungwoo Yang 
1795*5fcf092eSHyungwoo Yang MODULE_DEVICE_TABLE(acpi, ov13858_acpi_ids);
1796*5fcf092eSHyungwoo Yang #endif
1797*5fcf092eSHyungwoo Yang 
1798*5fcf092eSHyungwoo Yang static struct i2c_driver ov13858_i2c_driver = {
1799*5fcf092eSHyungwoo Yang 	.driver = {
1800*5fcf092eSHyungwoo Yang 		.name = "ov13858",
1801*5fcf092eSHyungwoo Yang 		.owner = THIS_MODULE,
1802*5fcf092eSHyungwoo Yang 		.pm = &ov13858_pm_ops,
1803*5fcf092eSHyungwoo Yang 		.acpi_match_table = ACPI_PTR(ov13858_acpi_ids),
1804*5fcf092eSHyungwoo Yang 	},
1805*5fcf092eSHyungwoo Yang 	.probe = ov13858_probe,
1806*5fcf092eSHyungwoo Yang 	.remove = ov13858_remove,
1807*5fcf092eSHyungwoo Yang 	.id_table = ov13858_id_table,
1808*5fcf092eSHyungwoo Yang };
1809*5fcf092eSHyungwoo Yang 
1810*5fcf092eSHyungwoo Yang module_i2c_driver(ov13858_i2c_driver);
1811*5fcf092eSHyungwoo Yang 
1812*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Kan, Chris <chris.kan@intel.com>");
1813*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
1814*5fcf092eSHyungwoo Yang MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
1815*5fcf092eSHyungwoo Yang MODULE_DESCRIPTION("Omnivision ov13858 sensor driver");
1816*5fcf092eSHyungwoo Yang MODULE_LICENSE("GPL v2");
1817