xref: /openbmc/linux/drivers/media/i2c/imx319.c (revision 8a89dc62f28c481f62e0a1329679304ec2145323)
1*8a89dc62SBingbu Cao // SPDX-License-Identifier: GPL-2.0
2*8a89dc62SBingbu Cao // Copyright (C) 2018 Intel Corporation
3*8a89dc62SBingbu Cao 
4*8a89dc62SBingbu Cao #include <asm/unaligned.h>
5*8a89dc62SBingbu Cao #include <linux/acpi.h>
6*8a89dc62SBingbu Cao #include <linux/i2c.h>
7*8a89dc62SBingbu Cao #include <linux/module.h>
8*8a89dc62SBingbu Cao #include <linux/pm_runtime.h>
9*8a89dc62SBingbu Cao #include <media/v4l2-ctrls.h>
10*8a89dc62SBingbu Cao #include <media/v4l2-device.h>
11*8a89dc62SBingbu Cao #include <media/v4l2-event.h>
12*8a89dc62SBingbu Cao #include <media/v4l2-fwnode.h>
13*8a89dc62SBingbu Cao 
14*8a89dc62SBingbu Cao #define IMX319_REG_MODE_SELECT		0x0100
15*8a89dc62SBingbu Cao #define IMX319_MODE_STANDBY		0x00
16*8a89dc62SBingbu Cao #define IMX319_MODE_STREAMING		0x01
17*8a89dc62SBingbu Cao 
18*8a89dc62SBingbu Cao /* Chip ID */
19*8a89dc62SBingbu Cao #define IMX319_REG_CHIP_ID		0x0016
20*8a89dc62SBingbu Cao #define IMX319_CHIP_ID			0x0319
21*8a89dc62SBingbu Cao 
22*8a89dc62SBingbu Cao /* V_TIMING internal */
23*8a89dc62SBingbu Cao #define IMX319_REG_FLL			0x0340
24*8a89dc62SBingbu Cao #define IMX319_FLL_MAX			0xffff
25*8a89dc62SBingbu Cao 
26*8a89dc62SBingbu Cao /* Exposure control */
27*8a89dc62SBingbu Cao #define IMX319_REG_EXPOSURE		0x0202
28*8a89dc62SBingbu Cao #define IMX319_EXPOSURE_MIN		1
29*8a89dc62SBingbu Cao #define IMX319_EXPOSURE_STEP		1
30*8a89dc62SBingbu Cao #define IMX319_EXPOSURE_DEFAULT		0x04f6
31*8a89dc62SBingbu Cao 
32*8a89dc62SBingbu Cao /*
33*8a89dc62SBingbu Cao  *  the digital control register for all color control looks like:
34*8a89dc62SBingbu Cao  *  +-----------------+------------------+
35*8a89dc62SBingbu Cao  *  |      [7:0]      |       [15:8]     |
36*8a89dc62SBingbu Cao  *  +-----------------+------------------+
37*8a89dc62SBingbu Cao  *  |	  0x020f      |       0x020e     |
38*8a89dc62SBingbu Cao  *  --------------------------------------
39*8a89dc62SBingbu Cao  *  it is used to calculate the digital gain times value(integral + fractional)
40*8a89dc62SBingbu Cao  *  the [15:8] bits is the fractional part and [7:0] bits is the integral
41*8a89dc62SBingbu Cao  *  calculation equation is:
42*8a89dc62SBingbu Cao  *      gain value (unit: times) = REG[15:8] + REG[7:0]/0x100
43*8a89dc62SBingbu Cao  *  Only value in 0x0100 ~ 0x0FFF range is allowed.
44*8a89dc62SBingbu Cao  *  Analog gain use 10 bits in the registers and allowed range is 0 ~ 960
45*8a89dc62SBingbu Cao  */
46*8a89dc62SBingbu Cao /* Analog gain control */
47*8a89dc62SBingbu Cao #define IMX319_REG_ANALOG_GAIN		0x0204
48*8a89dc62SBingbu Cao #define IMX319_ANA_GAIN_MIN		0
49*8a89dc62SBingbu Cao #define IMX319_ANA_GAIN_MAX		960
50*8a89dc62SBingbu Cao #define IMX319_ANA_GAIN_STEP		1
51*8a89dc62SBingbu Cao #define IMX319_ANA_GAIN_DEFAULT		0
52*8a89dc62SBingbu Cao 
53*8a89dc62SBingbu Cao /* Digital gain control */
54*8a89dc62SBingbu Cao #define IMX319_REG_DPGA_USE_GLOBAL_GAIN	0x3ff9
55*8a89dc62SBingbu Cao #define IMX319_REG_DIG_GAIN_GLOBAL	0x020e
56*8a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_MIN		256
57*8a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_MAX		4095
58*8a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_STEP		1
59*8a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_DEFAULT	256
60*8a89dc62SBingbu Cao 
61*8a89dc62SBingbu Cao /* Test Pattern Control */
62*8a89dc62SBingbu Cao #define IMX319_REG_TEST_PATTERN		0x0600
63*8a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_DISABLED		0
64*8a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_SOLID_COLOR		1
65*8a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_COLOR_BARS		2
66*8a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_GRAY_COLOR_BARS	3
67*8a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_PN9			4
68*8a89dc62SBingbu Cao 
69*8a89dc62SBingbu Cao /* Flip Control */
70*8a89dc62SBingbu Cao #define IMX319_REG_ORIENTATION		0x0101
71*8a89dc62SBingbu Cao 
72*8a89dc62SBingbu Cao /* default link frequency and external clock */
73*8a89dc62SBingbu Cao #define IMX319_LINK_FREQ_DEFAULT	482400000
74*8a89dc62SBingbu Cao #define IMX319_EXT_CLK			19200000
75*8a89dc62SBingbu Cao #define IMX319_LINK_FREQ_INDEX		0
76*8a89dc62SBingbu Cao 
77*8a89dc62SBingbu Cao struct imx319_reg {
78*8a89dc62SBingbu Cao 	u16 address;
79*8a89dc62SBingbu Cao 	u8 val;
80*8a89dc62SBingbu Cao };
81*8a89dc62SBingbu Cao 
82*8a89dc62SBingbu Cao struct imx319_reg_list {
83*8a89dc62SBingbu Cao 	u32 num_of_regs;
84*8a89dc62SBingbu Cao 	const struct imx319_reg *regs;
85*8a89dc62SBingbu Cao };
86*8a89dc62SBingbu Cao 
87*8a89dc62SBingbu Cao /* Mode : resolution and related config&values */
88*8a89dc62SBingbu Cao struct imx319_mode {
89*8a89dc62SBingbu Cao 	/* Frame width */
90*8a89dc62SBingbu Cao 	u32 width;
91*8a89dc62SBingbu Cao 	/* Frame height */
92*8a89dc62SBingbu Cao 	u32 height;
93*8a89dc62SBingbu Cao 
94*8a89dc62SBingbu Cao 	/* V-timing */
95*8a89dc62SBingbu Cao 	u32 fll_def;
96*8a89dc62SBingbu Cao 	u32 fll_min;
97*8a89dc62SBingbu Cao 
98*8a89dc62SBingbu Cao 	/* H-timing */
99*8a89dc62SBingbu Cao 	u32 llp;
100*8a89dc62SBingbu Cao 
101*8a89dc62SBingbu Cao 	/* index of link frequency */
102*8a89dc62SBingbu Cao 	u32 link_freq_index;
103*8a89dc62SBingbu Cao 
104*8a89dc62SBingbu Cao 	/* Default register values */
105*8a89dc62SBingbu Cao 	struct imx319_reg_list reg_list;
106*8a89dc62SBingbu Cao };
107*8a89dc62SBingbu Cao 
108*8a89dc62SBingbu Cao struct imx319_hwcfg {
109*8a89dc62SBingbu Cao 	u32 ext_clk;			/* sensor external clk */
110*8a89dc62SBingbu Cao 	s64 *link_freqs;		/* CSI-2 link frequencies */
111*8a89dc62SBingbu Cao 	unsigned int nr_of_link_freqs;
112*8a89dc62SBingbu Cao };
113*8a89dc62SBingbu Cao 
114*8a89dc62SBingbu Cao struct imx319 {
115*8a89dc62SBingbu Cao 	struct v4l2_subdev sd;
116*8a89dc62SBingbu Cao 	struct media_pad pad;
117*8a89dc62SBingbu Cao 
118*8a89dc62SBingbu Cao 	struct v4l2_ctrl_handler ctrl_handler;
119*8a89dc62SBingbu Cao 	/* V4L2 Controls */
120*8a89dc62SBingbu Cao 	struct v4l2_ctrl *link_freq;
121*8a89dc62SBingbu Cao 	struct v4l2_ctrl *pixel_rate;
122*8a89dc62SBingbu Cao 	struct v4l2_ctrl *vblank;
123*8a89dc62SBingbu Cao 	struct v4l2_ctrl *hblank;
124*8a89dc62SBingbu Cao 	struct v4l2_ctrl *exposure;
125*8a89dc62SBingbu Cao 	struct v4l2_ctrl *vflip;
126*8a89dc62SBingbu Cao 	struct v4l2_ctrl *hflip;
127*8a89dc62SBingbu Cao 
128*8a89dc62SBingbu Cao 	/* Current mode */
129*8a89dc62SBingbu Cao 	const struct imx319_mode *cur_mode;
130*8a89dc62SBingbu Cao 
131*8a89dc62SBingbu Cao 	struct imx319_hwcfg *hwcfg;
132*8a89dc62SBingbu Cao 	s64 link_def_freq;	/* CSI-2 link default frequency */
133*8a89dc62SBingbu Cao 
134*8a89dc62SBingbu Cao 	/*
135*8a89dc62SBingbu Cao 	 * Mutex for serialized access:
136*8a89dc62SBingbu Cao 	 * Protect sensor set pad format and start/stop streaming safely.
137*8a89dc62SBingbu Cao 	 * Protect access to sensor v4l2 controls.
138*8a89dc62SBingbu Cao 	 */
139*8a89dc62SBingbu Cao 	struct mutex mutex;
140*8a89dc62SBingbu Cao 
141*8a89dc62SBingbu Cao 	/* Streaming on/off */
142*8a89dc62SBingbu Cao 	bool streaming;
143*8a89dc62SBingbu Cao };
144*8a89dc62SBingbu Cao 
145*8a89dc62SBingbu Cao static const struct imx319_reg imx319_global_regs[] = {
146*8a89dc62SBingbu Cao 	{ 0x0136, 0x13 },
147*8a89dc62SBingbu Cao 	{ 0x0137, 0x33 },
148*8a89dc62SBingbu Cao 	{ 0x3c7e, 0x05 },
149*8a89dc62SBingbu Cao 	{ 0x3c7f, 0x07 },
150*8a89dc62SBingbu Cao 	{ 0x4d39, 0x0b },
151*8a89dc62SBingbu Cao 	{ 0x4d41, 0x33 },
152*8a89dc62SBingbu Cao 	{ 0x4d43, 0x0c },
153*8a89dc62SBingbu Cao 	{ 0x4d49, 0x89 },
154*8a89dc62SBingbu Cao 	{ 0x4e05, 0x0b },
155*8a89dc62SBingbu Cao 	{ 0x4e0d, 0x33 },
156*8a89dc62SBingbu Cao 	{ 0x4e0f, 0x0c },
157*8a89dc62SBingbu Cao 	{ 0x4e15, 0x89 },
158*8a89dc62SBingbu Cao 	{ 0x4e49, 0x2a },
159*8a89dc62SBingbu Cao 	{ 0x4e51, 0x33 },
160*8a89dc62SBingbu Cao 	{ 0x4e53, 0x0c },
161*8a89dc62SBingbu Cao 	{ 0x4e59, 0x89 },
162*8a89dc62SBingbu Cao 	{ 0x5601, 0x4f },
163*8a89dc62SBingbu Cao 	{ 0x560b, 0x45 },
164*8a89dc62SBingbu Cao 	{ 0x562f, 0x0a },
165*8a89dc62SBingbu Cao 	{ 0x5643, 0x0a },
166*8a89dc62SBingbu Cao 	{ 0x5645, 0x0c },
167*8a89dc62SBingbu Cao 	{ 0x56ef, 0x51 },
168*8a89dc62SBingbu Cao 	{ 0x586f, 0x33 },
169*8a89dc62SBingbu Cao 	{ 0x5873, 0x89 },
170*8a89dc62SBingbu Cao 	{ 0x5905, 0x33 },
171*8a89dc62SBingbu Cao 	{ 0x5907, 0x89 },
172*8a89dc62SBingbu Cao 	{ 0x590d, 0x33 },
173*8a89dc62SBingbu Cao 	{ 0x590f, 0x89 },
174*8a89dc62SBingbu Cao 	{ 0x5915, 0x33 },
175*8a89dc62SBingbu Cao 	{ 0x5917, 0x89 },
176*8a89dc62SBingbu Cao 	{ 0x5969, 0x1c },
177*8a89dc62SBingbu Cao 	{ 0x596b, 0x72 },
178*8a89dc62SBingbu Cao 	{ 0x5971, 0x33 },
179*8a89dc62SBingbu Cao 	{ 0x5973, 0x89 },
180*8a89dc62SBingbu Cao 	{ 0x5975, 0x33 },
181*8a89dc62SBingbu Cao 	{ 0x5977, 0x89 },
182*8a89dc62SBingbu Cao 	{ 0x5979, 0x1c },
183*8a89dc62SBingbu Cao 	{ 0x597b, 0x72 },
184*8a89dc62SBingbu Cao 	{ 0x5985, 0x33 },
185*8a89dc62SBingbu Cao 	{ 0x5987, 0x89 },
186*8a89dc62SBingbu Cao 	{ 0x5999, 0x1c },
187*8a89dc62SBingbu Cao 	{ 0x599b, 0x72 },
188*8a89dc62SBingbu Cao 	{ 0x59a5, 0x33 },
189*8a89dc62SBingbu Cao 	{ 0x59a7, 0x89 },
190*8a89dc62SBingbu Cao 	{ 0x7485, 0x08 },
191*8a89dc62SBingbu Cao 	{ 0x7487, 0x0c },
192*8a89dc62SBingbu Cao 	{ 0x7489, 0xc7 },
193*8a89dc62SBingbu Cao 	{ 0x748b, 0x8b },
194*8a89dc62SBingbu Cao 	{ 0x9004, 0x09 },
195*8a89dc62SBingbu Cao 	{ 0x9200, 0x6a },
196*8a89dc62SBingbu Cao 	{ 0x9201, 0x22 },
197*8a89dc62SBingbu Cao 	{ 0x9202, 0x6a },
198*8a89dc62SBingbu Cao 	{ 0x9203, 0x23 },
199*8a89dc62SBingbu Cao 	{ 0x9204, 0x5f },
200*8a89dc62SBingbu Cao 	{ 0x9205, 0x23 },
201*8a89dc62SBingbu Cao 	{ 0x9206, 0x5f },
202*8a89dc62SBingbu Cao 	{ 0x9207, 0x24 },
203*8a89dc62SBingbu Cao 	{ 0x9208, 0x5f },
204*8a89dc62SBingbu Cao 	{ 0x9209, 0x26 },
205*8a89dc62SBingbu Cao 	{ 0x920a, 0x5f },
206*8a89dc62SBingbu Cao 	{ 0x920b, 0x27 },
207*8a89dc62SBingbu Cao 	{ 0x920c, 0x5f },
208*8a89dc62SBingbu Cao 	{ 0x920d, 0x29 },
209*8a89dc62SBingbu Cao 	{ 0x920e, 0x5f },
210*8a89dc62SBingbu Cao 	{ 0x920f, 0x2a },
211*8a89dc62SBingbu Cao 	{ 0x9210, 0x5f },
212*8a89dc62SBingbu Cao 	{ 0x9211, 0x2c },
213*8a89dc62SBingbu Cao 	{ 0xbc22, 0x1a },
214*8a89dc62SBingbu Cao 	{ 0xf01f, 0x04 },
215*8a89dc62SBingbu Cao 	{ 0xf021, 0x03 },
216*8a89dc62SBingbu Cao 	{ 0xf023, 0x02 },
217*8a89dc62SBingbu Cao 	{ 0xf03d, 0x05 },
218*8a89dc62SBingbu Cao 	{ 0xf03f, 0x03 },
219*8a89dc62SBingbu Cao 	{ 0xf041, 0x02 },
220*8a89dc62SBingbu Cao 	{ 0xf0af, 0x04 },
221*8a89dc62SBingbu Cao 	{ 0xf0b1, 0x03 },
222*8a89dc62SBingbu Cao 	{ 0xf0b3, 0x02 },
223*8a89dc62SBingbu Cao 	{ 0xf0cd, 0x05 },
224*8a89dc62SBingbu Cao 	{ 0xf0cf, 0x03 },
225*8a89dc62SBingbu Cao 	{ 0xf0d1, 0x02 },
226*8a89dc62SBingbu Cao 	{ 0xf13f, 0x04 },
227*8a89dc62SBingbu Cao 	{ 0xf141, 0x03 },
228*8a89dc62SBingbu Cao 	{ 0xf143, 0x02 },
229*8a89dc62SBingbu Cao 	{ 0xf15d, 0x05 },
230*8a89dc62SBingbu Cao 	{ 0xf15f, 0x03 },
231*8a89dc62SBingbu Cao 	{ 0xf161, 0x02 },
232*8a89dc62SBingbu Cao 	{ 0xf1cf, 0x04 },
233*8a89dc62SBingbu Cao 	{ 0xf1d1, 0x03 },
234*8a89dc62SBingbu Cao 	{ 0xf1d3, 0x02 },
235*8a89dc62SBingbu Cao 	{ 0xf1ed, 0x05 },
236*8a89dc62SBingbu Cao 	{ 0xf1ef, 0x03 },
237*8a89dc62SBingbu Cao 	{ 0xf1f1, 0x02 },
238*8a89dc62SBingbu Cao 	{ 0xf287, 0x04 },
239*8a89dc62SBingbu Cao 	{ 0xf289, 0x03 },
240*8a89dc62SBingbu Cao 	{ 0xf28b, 0x02 },
241*8a89dc62SBingbu Cao 	{ 0xf2a5, 0x05 },
242*8a89dc62SBingbu Cao 	{ 0xf2a7, 0x03 },
243*8a89dc62SBingbu Cao 	{ 0xf2a9, 0x02 },
244*8a89dc62SBingbu Cao 	{ 0xf2b7, 0x04 },
245*8a89dc62SBingbu Cao 	{ 0xf2b9, 0x03 },
246*8a89dc62SBingbu Cao 	{ 0xf2bb, 0x02 },
247*8a89dc62SBingbu Cao 	{ 0xf2d5, 0x05 },
248*8a89dc62SBingbu Cao 	{ 0xf2d7, 0x03 },
249*8a89dc62SBingbu Cao 	{ 0xf2d9, 0x02 },
250*8a89dc62SBingbu Cao };
251*8a89dc62SBingbu Cao 
252*8a89dc62SBingbu Cao static const struct imx319_reg_list imx319_global_setting = {
253*8a89dc62SBingbu Cao 	.num_of_regs = ARRAY_SIZE(imx319_global_regs),
254*8a89dc62SBingbu Cao 	.regs = imx319_global_regs,
255*8a89dc62SBingbu Cao };
256*8a89dc62SBingbu Cao 
257*8a89dc62SBingbu Cao static const struct imx319_reg mode_3264x2448_regs[] = {
258*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
259*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
260*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
261*8a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
262*8a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
263*8a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
264*8a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
265*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
266*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
267*8a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
268*8a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
269*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
270*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
271*8a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
272*8a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
273*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
274*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
275*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
276*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
277*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
278*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
279*8a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
280*8a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
281*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
282*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
283*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
284*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
285*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
286*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
287*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
288*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
289*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
290*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
291*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
292*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
293*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
294*8a89dc62SBingbu Cao 	{ 0x0409, 0x08 },
295*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
296*8a89dc62SBingbu Cao 	{ 0x040b, 0x08 },
297*8a89dc62SBingbu Cao 	{ 0x040c, 0x0c },
298*8a89dc62SBingbu Cao 	{ 0x040d, 0xc0 },
299*8a89dc62SBingbu Cao 	{ 0x040e, 0x09 },
300*8a89dc62SBingbu Cao 	{ 0x040f, 0x90 },
301*8a89dc62SBingbu Cao 	{ 0x034c, 0x0c },
302*8a89dc62SBingbu Cao 	{ 0x034d, 0xc0 },
303*8a89dc62SBingbu Cao 	{ 0x034e, 0x09 },
304*8a89dc62SBingbu Cao 	{ 0x034f, 0x90 },
305*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
306*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
307*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
308*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
309*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
310*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
311*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
312*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
313*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
314*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
315*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
316*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
317*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
318*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
319*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
320*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
321*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
322*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
323*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
324*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
325*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
326*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
327*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
328*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
329*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
330*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
331*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
332*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
333*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
334*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
335*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
336*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
337*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
338*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
339*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
340*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
341*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
342*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
343*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
344*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
345*8a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
346*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
347*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
348*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
349*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
350*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
351*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
352*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
353*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
354*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
355*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
356*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
357*8a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
358*8a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
359*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
360*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
361*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
362*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
363*8a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
364*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
365*8a89dc62SBingbu Cao 	{ 0x0202, 0x0a },
366*8a89dc62SBingbu Cao 	{ 0x0203, 0x7a },
367*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
368*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
369*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
370*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
371*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
372*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
373*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
374*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
375*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
376*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
377*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
378*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
379*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
380*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
381*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
382*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
383*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
384*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
385*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
386*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
387*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
388*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
389*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
390*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
391*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
392*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
393*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
394*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
395*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
396*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
397*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
398*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
399*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
400*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
401*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
402*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
403*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
404*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
405*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
406*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
407*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
408*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
409*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
410*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
411*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
412*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
413*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
414*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
415*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
416*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
417*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
418*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
419*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
420*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
421*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
422*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
423*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
424*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
425*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
426*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
427*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
428*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
429*8a89dc62SBingbu Cao };
430*8a89dc62SBingbu Cao 
431*8a89dc62SBingbu Cao static const struct imx319_reg mode_3280x2464_regs[] = {
432*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
433*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
434*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
435*8a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
436*8a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
437*8a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
438*8a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
439*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
440*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
441*8a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
442*8a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
443*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
444*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
445*8a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
446*8a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
447*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
448*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
449*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
450*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
451*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
452*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
453*8a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
454*8a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
455*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
456*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
457*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
458*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
459*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
460*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
461*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
462*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
463*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
464*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
465*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
466*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
467*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
468*8a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
469*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
470*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
471*8a89dc62SBingbu Cao 	{ 0x040c, 0x0c },
472*8a89dc62SBingbu Cao 	{ 0x040d, 0xd0 },
473*8a89dc62SBingbu Cao 	{ 0x040e, 0x09 },
474*8a89dc62SBingbu Cao 	{ 0x040f, 0xa0 },
475*8a89dc62SBingbu Cao 	{ 0x034c, 0x0c },
476*8a89dc62SBingbu Cao 	{ 0x034d, 0xd0 },
477*8a89dc62SBingbu Cao 	{ 0x034e, 0x09 },
478*8a89dc62SBingbu Cao 	{ 0x034f, 0xa0 },
479*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
480*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
481*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
482*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
483*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
484*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
485*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
486*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
487*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
488*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
489*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
490*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
491*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
492*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
493*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
494*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
495*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
496*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
497*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
498*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
499*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
500*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
501*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
502*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
503*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
504*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
505*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
506*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
507*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
508*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
509*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
510*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
511*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
512*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
513*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
514*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
515*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
516*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
517*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
518*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
519*8a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
520*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
521*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
522*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
523*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
524*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
525*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
526*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
527*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
528*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
529*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
530*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
531*8a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
532*8a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
533*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
534*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
535*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
536*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
537*8a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
538*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
539*8a89dc62SBingbu Cao 	{ 0x0202, 0x0a },
540*8a89dc62SBingbu Cao 	{ 0x0203, 0x7a },
541*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
542*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
543*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
544*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
545*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
546*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
547*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
548*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
549*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
550*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
551*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
552*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
553*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
554*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
555*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
556*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
557*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
558*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
559*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
560*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
561*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
562*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
563*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
564*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
565*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
566*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
567*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
568*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
569*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
570*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
571*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
572*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
573*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
574*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
575*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
576*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
577*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
578*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
579*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
580*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
581*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
582*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
583*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
584*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
585*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
586*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
587*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
588*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
589*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
590*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
591*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
592*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
593*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
594*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
595*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
596*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
597*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
598*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
599*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
600*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
601*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
602*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
603*8a89dc62SBingbu Cao };
604*8a89dc62SBingbu Cao 
605*8a89dc62SBingbu Cao static const struct imx319_reg mode_1936x1096_regs[] = {
606*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
607*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
608*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
609*8a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
610*8a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
611*8a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
612*8a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
613*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
614*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
615*8a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
616*8a89dc62SBingbu Cao 	{ 0x0347, 0xac },
617*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
618*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
619*8a89dc62SBingbu Cao 	{ 0x034a, 0x06 },
620*8a89dc62SBingbu Cao 	{ 0x034b, 0xf3 },
621*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
622*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
623*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
624*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
625*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
626*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
627*8a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
628*8a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
629*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
630*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
631*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
632*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
633*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
634*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
635*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
636*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
637*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
638*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
639*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
640*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
641*8a89dc62SBingbu Cao 	{ 0x0408, 0x02 },
642*8a89dc62SBingbu Cao 	{ 0x0409, 0xa0 },
643*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
644*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
645*8a89dc62SBingbu Cao 	{ 0x040c, 0x07 },
646*8a89dc62SBingbu Cao 	{ 0x040d, 0x90 },
647*8a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
648*8a89dc62SBingbu Cao 	{ 0x040f, 0x48 },
649*8a89dc62SBingbu Cao 	{ 0x034c, 0x07 },
650*8a89dc62SBingbu Cao 	{ 0x034d, 0x90 },
651*8a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
652*8a89dc62SBingbu Cao 	{ 0x034f, 0x48 },
653*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
654*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
655*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
656*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
657*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
658*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
659*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
660*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
661*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
662*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
663*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
664*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
665*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
666*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
667*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
668*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
669*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
670*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
671*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
672*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
673*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
674*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
675*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
676*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
677*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
678*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
679*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
680*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
681*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
682*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
683*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
684*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
685*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
686*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
687*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
688*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
689*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
690*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
691*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
692*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
693*8a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
694*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
695*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
696*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
697*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
698*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
699*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
700*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
701*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
702*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
703*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
704*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
705*8a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
706*8a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
707*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
708*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
709*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
710*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
711*8a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
712*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
713*8a89dc62SBingbu Cao 	{ 0x0202, 0x05 },
714*8a89dc62SBingbu Cao 	{ 0x0203, 0x34 },
715*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
716*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
717*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
718*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
719*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
720*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
721*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
722*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
723*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
724*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
725*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
726*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
727*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
728*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
729*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
730*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
731*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
732*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
733*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
734*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
735*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
736*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
737*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
738*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
739*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
740*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
741*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
742*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
743*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
744*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
745*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
746*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
747*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
748*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
749*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
750*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
751*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
752*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
753*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
754*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
755*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
756*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
757*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
758*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
759*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
760*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
761*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
762*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
763*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
764*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
765*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
766*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
767*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
768*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
769*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
770*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
771*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
772*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
773*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
774*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
775*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
776*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
777*8a89dc62SBingbu Cao };
778*8a89dc62SBingbu Cao 
779*8a89dc62SBingbu Cao static const struct imx319_reg mode_1920x1080_regs[] = {
780*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
781*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
782*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
783*8a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
784*8a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
785*8a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
786*8a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
787*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
788*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
789*8a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
790*8a89dc62SBingbu Cao 	{ 0x0347, 0xb4 },
791*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
792*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
793*8a89dc62SBingbu Cao 	{ 0x034a, 0x06 },
794*8a89dc62SBingbu Cao 	{ 0x034b, 0xeb },
795*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
796*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
797*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
798*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
799*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
800*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
801*8a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
802*8a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
803*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
804*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
805*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
806*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
807*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
808*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
809*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
810*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
811*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
812*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
813*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
814*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
815*8a89dc62SBingbu Cao 	{ 0x0408, 0x02 },
816*8a89dc62SBingbu Cao 	{ 0x0409, 0xa8 },
817*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
818*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
819*8a89dc62SBingbu Cao 	{ 0x040c, 0x07 },
820*8a89dc62SBingbu Cao 	{ 0x040d, 0x80 },
821*8a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
822*8a89dc62SBingbu Cao 	{ 0x040f, 0x38 },
823*8a89dc62SBingbu Cao 	{ 0x034c, 0x07 },
824*8a89dc62SBingbu Cao 	{ 0x034d, 0x80 },
825*8a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
826*8a89dc62SBingbu Cao 	{ 0x034f, 0x38 },
827*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
828*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
829*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
830*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
831*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
832*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
833*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
834*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
835*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
836*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
837*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
838*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
839*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
840*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
841*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
842*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
843*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
844*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
845*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
846*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
847*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
848*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
849*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
850*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
851*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
852*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
853*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
854*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
855*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
856*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
857*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
858*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
859*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
860*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
861*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
862*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
863*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
864*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
865*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
866*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
867*8a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
868*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
869*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
870*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
871*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
872*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
873*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
874*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
875*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
876*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
877*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
878*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
879*8a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
880*8a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
881*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
882*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
883*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
884*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
885*8a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
886*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
887*8a89dc62SBingbu Cao 	{ 0x0202, 0x05 },
888*8a89dc62SBingbu Cao 	{ 0x0203, 0x34 },
889*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
890*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
891*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
892*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
893*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
894*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
895*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
896*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
897*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
898*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
899*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
900*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
901*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
902*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
903*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
904*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
905*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
906*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
907*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
908*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
909*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
910*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
911*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
912*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
913*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
914*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
915*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
916*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
917*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
918*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
919*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
920*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
921*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
922*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
923*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
924*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
925*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
926*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
927*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
928*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
929*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
930*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
931*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
932*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
933*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
934*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
935*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
936*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
937*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
938*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
939*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
940*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
941*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
942*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
943*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
944*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
945*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
946*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
947*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
948*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
949*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
950*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
951*8a89dc62SBingbu Cao };
952*8a89dc62SBingbu Cao 
953*8a89dc62SBingbu Cao static const struct imx319_reg mode_1640x1232_regs[] = {
954*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
955*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
956*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
957*8a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
958*8a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
959*8a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
960*8a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
961*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
962*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
963*8a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
964*8a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
965*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
966*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
967*8a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
968*8a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
969*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
970*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
971*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
972*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
973*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
974*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
975*8a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
976*8a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
977*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
978*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
979*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
980*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
981*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
982*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
983*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
984*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
985*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
986*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
987*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
988*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
989*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
990*8a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
991*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
992*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
993*8a89dc62SBingbu Cao 	{ 0x040c, 0x06 },
994*8a89dc62SBingbu Cao 	{ 0x040d, 0x68 },
995*8a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
996*8a89dc62SBingbu Cao 	{ 0x040f, 0xd0 },
997*8a89dc62SBingbu Cao 	{ 0x034c, 0x06 },
998*8a89dc62SBingbu Cao 	{ 0x034d, 0x68 },
999*8a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
1000*8a89dc62SBingbu Cao 	{ 0x034f, 0xd0 },
1001*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
1002*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
1003*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
1004*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
1005*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
1006*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
1007*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
1008*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
1009*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
1010*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
1011*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
1012*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
1013*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
1014*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
1015*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
1016*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
1017*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
1018*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
1019*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
1020*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
1021*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
1022*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
1023*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
1024*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
1025*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
1026*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
1027*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
1028*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
1029*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
1030*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
1031*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
1032*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
1033*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
1034*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
1035*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
1036*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
1037*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
1038*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
1039*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
1040*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
1041*8a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
1042*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
1043*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
1044*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
1045*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
1046*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
1047*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
1048*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
1049*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
1050*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
1051*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
1052*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
1053*8a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
1054*8a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
1055*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
1056*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
1057*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
1058*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
1059*8a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
1060*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
1061*8a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
1062*8a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
1063*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
1064*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
1065*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
1066*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
1067*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
1068*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
1069*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
1070*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
1071*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
1072*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
1073*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
1074*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
1075*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
1076*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
1077*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
1078*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
1079*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
1080*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
1081*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
1082*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
1083*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
1084*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
1085*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
1086*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
1087*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
1088*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
1089*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
1090*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
1091*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
1092*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
1093*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
1094*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
1095*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
1096*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
1097*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
1098*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
1099*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
1100*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
1101*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
1102*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
1103*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
1104*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
1105*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
1106*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
1107*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
1108*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
1109*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
1110*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
1111*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
1112*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
1113*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
1114*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
1115*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
1116*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
1117*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
1118*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
1119*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
1120*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
1121*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
1122*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
1123*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
1124*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
1125*8a89dc62SBingbu Cao };
1126*8a89dc62SBingbu Cao 
1127*8a89dc62SBingbu Cao static const struct imx319_reg mode_1640x922_regs[] = {
1128*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
1129*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
1130*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
1131*8a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
1132*8a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
1133*8a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
1134*8a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
1135*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
1136*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
1137*8a89dc62SBingbu Cao 	{ 0x0346, 0x01 },
1138*8a89dc62SBingbu Cao 	{ 0x0347, 0x30 },
1139*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
1140*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
1141*8a89dc62SBingbu Cao 	{ 0x034a, 0x08 },
1142*8a89dc62SBingbu Cao 	{ 0x034b, 0x6f },
1143*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
1144*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
1145*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
1146*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
1147*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
1148*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
1149*8a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
1150*8a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
1151*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
1152*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
1153*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
1154*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
1155*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
1156*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
1157*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
1158*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
1159*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
1160*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
1161*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
1162*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
1163*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
1164*8a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
1165*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
1166*8a89dc62SBingbu Cao 	{ 0x040b, 0x02 },
1167*8a89dc62SBingbu Cao 	{ 0x040c, 0x06 },
1168*8a89dc62SBingbu Cao 	{ 0x040d, 0x68 },
1169*8a89dc62SBingbu Cao 	{ 0x040e, 0x03 },
1170*8a89dc62SBingbu Cao 	{ 0x040f, 0x9a },
1171*8a89dc62SBingbu Cao 	{ 0x034c, 0x06 },
1172*8a89dc62SBingbu Cao 	{ 0x034d, 0x68 },
1173*8a89dc62SBingbu Cao 	{ 0x034e, 0x03 },
1174*8a89dc62SBingbu Cao 	{ 0x034f, 0x9a },
1175*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
1176*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
1177*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
1178*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
1179*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
1180*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
1181*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
1182*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
1183*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
1184*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
1185*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
1186*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
1187*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
1188*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
1189*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
1190*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
1191*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
1192*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
1193*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
1194*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
1195*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
1196*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
1197*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
1198*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
1199*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
1200*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
1201*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
1202*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
1203*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
1204*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
1205*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
1206*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
1207*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
1208*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
1209*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
1210*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
1211*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
1212*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
1213*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
1214*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
1215*8a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
1216*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
1217*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
1218*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
1219*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
1220*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
1221*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
1222*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
1223*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
1224*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
1225*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
1226*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
1227*8a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
1228*8a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
1229*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
1230*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
1231*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
1232*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
1233*8a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
1234*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
1235*8a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
1236*8a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
1237*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
1238*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
1239*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
1240*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
1241*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
1242*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
1243*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
1244*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
1245*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
1246*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
1247*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
1248*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
1249*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
1250*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
1251*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
1252*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
1253*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
1254*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
1255*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
1256*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
1257*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
1258*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
1259*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
1260*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
1261*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
1262*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
1263*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
1264*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
1265*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
1266*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
1267*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
1268*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
1269*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
1270*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
1271*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
1272*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
1273*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
1274*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
1275*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
1276*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
1277*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
1278*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
1279*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
1280*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
1281*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
1282*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
1283*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
1284*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
1285*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
1286*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
1287*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
1288*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
1289*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
1290*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
1291*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
1292*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
1293*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
1294*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
1295*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
1296*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
1297*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
1298*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
1299*8a89dc62SBingbu Cao };
1300*8a89dc62SBingbu Cao 
1301*8a89dc62SBingbu Cao static const struct imx319_reg mode_1296x736_regs[] = {
1302*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
1303*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
1304*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
1305*8a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
1306*8a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
1307*8a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
1308*8a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
1309*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
1310*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
1311*8a89dc62SBingbu Cao 	{ 0x0346, 0x01 },
1312*8a89dc62SBingbu Cao 	{ 0x0347, 0xf0 },
1313*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
1314*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
1315*8a89dc62SBingbu Cao 	{ 0x034a, 0x07 },
1316*8a89dc62SBingbu Cao 	{ 0x034b, 0xaf },
1317*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
1318*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
1319*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
1320*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
1321*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
1322*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
1323*8a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
1324*8a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
1325*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
1326*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
1327*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
1328*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
1329*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
1330*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
1331*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
1332*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
1333*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
1334*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
1335*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
1336*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
1337*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
1338*8a89dc62SBingbu Cao 	{ 0x0409, 0xac },
1339*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
1340*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
1341*8a89dc62SBingbu Cao 	{ 0x040c, 0x05 },
1342*8a89dc62SBingbu Cao 	{ 0x040d, 0x10 },
1343*8a89dc62SBingbu Cao 	{ 0x040e, 0x02 },
1344*8a89dc62SBingbu Cao 	{ 0x040f, 0xe0 },
1345*8a89dc62SBingbu Cao 	{ 0x034c, 0x05 },
1346*8a89dc62SBingbu Cao 	{ 0x034d, 0x10 },
1347*8a89dc62SBingbu Cao 	{ 0x034e, 0x02 },
1348*8a89dc62SBingbu Cao 	{ 0x034f, 0xe0 },
1349*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
1350*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
1351*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
1352*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
1353*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
1354*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
1355*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
1356*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
1357*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
1358*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
1359*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
1360*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
1361*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
1362*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
1363*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
1364*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
1365*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
1366*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
1367*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
1368*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
1369*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
1370*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
1371*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
1372*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
1373*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
1374*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
1375*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
1376*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
1377*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
1378*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
1379*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
1380*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
1381*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
1382*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
1383*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
1384*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
1385*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
1386*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
1387*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
1388*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
1389*8a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
1390*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
1391*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
1392*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
1393*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
1394*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
1395*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
1396*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
1397*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
1398*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
1399*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
1400*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
1401*8a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
1402*8a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
1403*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
1404*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
1405*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
1406*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
1407*8a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
1408*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
1409*8a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
1410*8a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
1411*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
1412*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
1413*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
1414*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
1415*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
1416*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
1417*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
1418*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
1419*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
1420*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
1421*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
1422*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
1423*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
1424*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
1425*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
1426*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
1427*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
1428*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
1429*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
1430*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
1431*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
1432*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
1433*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
1434*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
1435*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
1436*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
1437*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
1438*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
1439*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
1440*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
1441*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
1442*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
1443*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
1444*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
1445*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
1446*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
1447*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
1448*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
1449*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
1450*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
1451*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
1452*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
1453*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
1454*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
1455*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
1456*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
1457*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
1458*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
1459*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
1460*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
1461*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
1462*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
1463*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
1464*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
1465*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
1466*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
1467*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
1468*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
1469*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
1470*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
1471*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
1472*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
1473*8a89dc62SBingbu Cao };
1474*8a89dc62SBingbu Cao 
1475*8a89dc62SBingbu Cao static const struct imx319_reg mode_1280x720_regs[] = {
1476*8a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
1477*8a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
1478*8a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
1479*8a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
1480*8a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
1481*8a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
1482*8a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
1483*8a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
1484*8a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
1485*8a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
1486*8a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
1487*8a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
1488*8a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
1489*8a89dc62SBingbu Cao 	{ 0x034a, 0x07 },
1490*8a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
1491*8a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
1492*8a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
1493*8a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
1494*8a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
1495*8a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
1496*8a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
1497*8a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
1498*8a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
1499*8a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
1500*8a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
1501*8a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
1502*8a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
1503*8a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
1504*8a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
1505*8a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
1506*8a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
1507*8a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
1508*8a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
1509*8a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
1510*8a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
1511*8a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
1512*8a89dc62SBingbu Cao 	{ 0x0409, 0xb4 },
1513*8a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
1514*8a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
1515*8a89dc62SBingbu Cao 	{ 0x040c, 0x05 },
1516*8a89dc62SBingbu Cao 	{ 0x040d, 0x00 },
1517*8a89dc62SBingbu Cao 	{ 0x040e, 0x02 },
1518*8a89dc62SBingbu Cao 	{ 0x040f, 0xd0 },
1519*8a89dc62SBingbu Cao 	{ 0x034c, 0x05 },
1520*8a89dc62SBingbu Cao 	{ 0x034d, 0x00 },
1521*8a89dc62SBingbu Cao 	{ 0x034e, 0x02 },
1522*8a89dc62SBingbu Cao 	{ 0x034f, 0xd0 },
1523*8a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
1524*8a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
1525*8a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
1526*8a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
1527*8a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
1528*8a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
1529*8a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
1530*8a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
1531*8a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
1532*8a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
1533*8a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
1534*8a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
1535*8a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
1536*8a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
1537*8a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
1538*8a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
1539*8a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
1540*8a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
1541*8a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
1542*8a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
1543*8a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
1544*8a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
1545*8a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
1546*8a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
1547*8a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
1548*8a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
1549*8a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
1550*8a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
1551*8a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
1552*8a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
1553*8a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
1554*8a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
1555*8a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
1556*8a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
1557*8a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
1558*8a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
1559*8a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
1560*8a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
1561*8a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
1562*8a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
1563*8a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
1564*8a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
1565*8a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
1566*8a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
1567*8a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
1568*8a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
1569*8a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
1570*8a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
1571*8a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
1572*8a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
1573*8a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
1574*8a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
1575*8a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
1576*8a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
1577*8a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
1578*8a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
1579*8a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
1580*8a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
1581*8a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
1582*8a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
1583*8a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
1584*8a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
1585*8a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
1586*8a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
1587*8a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
1588*8a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
1589*8a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
1590*8a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
1591*8a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
1592*8a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
1593*8a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
1594*8a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
1595*8a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
1596*8a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
1597*8a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
1598*8a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
1599*8a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
1600*8a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
1601*8a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
1602*8a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
1603*8a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
1604*8a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
1605*8a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
1606*8a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
1607*8a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
1608*8a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
1609*8a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
1610*8a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
1611*8a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
1612*8a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
1613*8a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
1614*8a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
1615*8a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
1616*8a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
1617*8a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
1618*8a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
1619*8a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
1620*8a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
1621*8a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
1622*8a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
1623*8a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
1624*8a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
1625*8a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
1626*8a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
1627*8a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
1628*8a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
1629*8a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
1630*8a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
1631*8a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
1632*8a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
1633*8a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
1634*8a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
1635*8a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
1636*8a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
1637*8a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
1638*8a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
1639*8a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
1640*8a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
1641*8a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
1642*8a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
1643*8a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
1644*8a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
1645*8a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
1646*8a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
1647*8a89dc62SBingbu Cao };
1648*8a89dc62SBingbu Cao 
1649*8a89dc62SBingbu Cao static const char * const imx319_test_pattern_menu[] = {
1650*8a89dc62SBingbu Cao 	"Disabled",
1651*8a89dc62SBingbu Cao 	"100% color bars",
1652*8a89dc62SBingbu Cao 	"Solid color",
1653*8a89dc62SBingbu Cao 	"Fade to gray color bars",
1654*8a89dc62SBingbu Cao 	"PN9"
1655*8a89dc62SBingbu Cao };
1656*8a89dc62SBingbu Cao 
1657*8a89dc62SBingbu Cao /* supported link frequencies */
1658*8a89dc62SBingbu Cao static const s64 link_freq_menu_items[] = {
1659*8a89dc62SBingbu Cao 	IMX319_LINK_FREQ_DEFAULT,
1660*8a89dc62SBingbu Cao };
1661*8a89dc62SBingbu Cao 
1662*8a89dc62SBingbu Cao /* Mode configs */
1663*8a89dc62SBingbu Cao static const struct imx319_mode supported_modes[] = {
1664*8a89dc62SBingbu Cao 	{
1665*8a89dc62SBingbu Cao 		.width = 3280,
1666*8a89dc62SBingbu Cao 		.height = 2464,
1667*8a89dc62SBingbu Cao 		.fll_def = 3242,
1668*8a89dc62SBingbu Cao 		.fll_min = 3242,
1669*8a89dc62SBingbu Cao 		.llp = 3968,
1670*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1671*8a89dc62SBingbu Cao 		.reg_list = {
1672*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
1673*8a89dc62SBingbu Cao 			.regs = mode_3280x2464_regs,
1674*8a89dc62SBingbu Cao 		},
1675*8a89dc62SBingbu Cao 	},
1676*8a89dc62SBingbu Cao 	{
1677*8a89dc62SBingbu Cao 		.width = 3264,
1678*8a89dc62SBingbu Cao 		.height = 2448,
1679*8a89dc62SBingbu Cao 		.fll_def = 3242,
1680*8a89dc62SBingbu Cao 		.fll_min = 3242,
1681*8a89dc62SBingbu Cao 		.llp = 3968,
1682*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1683*8a89dc62SBingbu Cao 		.reg_list = {
1684*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
1685*8a89dc62SBingbu Cao 			.regs = mode_3264x2448_regs,
1686*8a89dc62SBingbu Cao 		},
1687*8a89dc62SBingbu Cao 	},
1688*8a89dc62SBingbu Cao 	{
1689*8a89dc62SBingbu Cao 		.width = 1936,
1690*8a89dc62SBingbu Cao 		.height = 1096,
1691*8a89dc62SBingbu Cao 		.fll_def = 3242,
1692*8a89dc62SBingbu Cao 		.fll_min = 3242,
1693*8a89dc62SBingbu Cao 		.llp = 3968,
1694*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1695*8a89dc62SBingbu Cao 		.reg_list = {
1696*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
1697*8a89dc62SBingbu Cao 			.regs = mode_1936x1096_regs,
1698*8a89dc62SBingbu Cao 		},
1699*8a89dc62SBingbu Cao 	},
1700*8a89dc62SBingbu Cao 	{
1701*8a89dc62SBingbu Cao 		.width = 1920,
1702*8a89dc62SBingbu Cao 		.height = 1080,
1703*8a89dc62SBingbu Cao 		.fll_def = 3242,
1704*8a89dc62SBingbu Cao 		.fll_min = 3242,
1705*8a89dc62SBingbu Cao 		.llp = 3968,
1706*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1707*8a89dc62SBingbu Cao 		.reg_list = {
1708*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
1709*8a89dc62SBingbu Cao 			.regs = mode_1920x1080_regs,
1710*8a89dc62SBingbu Cao 		},
1711*8a89dc62SBingbu Cao 	},
1712*8a89dc62SBingbu Cao 	{
1713*8a89dc62SBingbu Cao 		.width = 1640,
1714*8a89dc62SBingbu Cao 		.height = 1232,
1715*8a89dc62SBingbu Cao 		.fll_def = 5146,
1716*8a89dc62SBingbu Cao 		.fll_min = 5146,
1717*8a89dc62SBingbu Cao 		.llp = 2500,
1718*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1719*8a89dc62SBingbu Cao 		.reg_list = {
1720*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
1721*8a89dc62SBingbu Cao 			.regs = mode_1640x1232_regs,
1722*8a89dc62SBingbu Cao 		},
1723*8a89dc62SBingbu Cao 	},
1724*8a89dc62SBingbu Cao 	{
1725*8a89dc62SBingbu Cao 		.width = 1640,
1726*8a89dc62SBingbu Cao 		.height = 922,
1727*8a89dc62SBingbu Cao 		.fll_def = 5146,
1728*8a89dc62SBingbu Cao 		.fll_min = 5146,
1729*8a89dc62SBingbu Cao 		.llp = 2500,
1730*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1731*8a89dc62SBingbu Cao 		.reg_list = {
1732*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
1733*8a89dc62SBingbu Cao 			.regs = mode_1640x922_regs,
1734*8a89dc62SBingbu Cao 		},
1735*8a89dc62SBingbu Cao 	},
1736*8a89dc62SBingbu Cao 	{
1737*8a89dc62SBingbu Cao 		.width = 1296,
1738*8a89dc62SBingbu Cao 		.height = 736,
1739*8a89dc62SBingbu Cao 		.fll_def = 5146,
1740*8a89dc62SBingbu Cao 		.fll_min = 5146,
1741*8a89dc62SBingbu Cao 		.llp = 2500,
1742*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1743*8a89dc62SBingbu Cao 		.reg_list = {
1744*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
1745*8a89dc62SBingbu Cao 			.regs = mode_1296x736_regs,
1746*8a89dc62SBingbu Cao 		},
1747*8a89dc62SBingbu Cao 	},
1748*8a89dc62SBingbu Cao 	{
1749*8a89dc62SBingbu Cao 		.width = 1280,
1750*8a89dc62SBingbu Cao 		.height = 720,
1751*8a89dc62SBingbu Cao 		.fll_def = 5146,
1752*8a89dc62SBingbu Cao 		.fll_min = 5146,
1753*8a89dc62SBingbu Cao 		.llp = 2500,
1754*8a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
1755*8a89dc62SBingbu Cao 		.reg_list = {
1756*8a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
1757*8a89dc62SBingbu Cao 			.regs = mode_1280x720_regs,
1758*8a89dc62SBingbu Cao 		},
1759*8a89dc62SBingbu Cao 	},
1760*8a89dc62SBingbu Cao };
1761*8a89dc62SBingbu Cao 
1762*8a89dc62SBingbu Cao static inline struct imx319 *to_imx319(struct v4l2_subdev *_sd)
1763*8a89dc62SBingbu Cao {
1764*8a89dc62SBingbu Cao 	return container_of(_sd, struct imx319, sd);
1765*8a89dc62SBingbu Cao }
1766*8a89dc62SBingbu Cao 
1767*8a89dc62SBingbu Cao /* Get bayer order based on flip setting. */
1768*8a89dc62SBingbu Cao static u32 imx319_get_format_code(struct imx319 *imx319)
1769*8a89dc62SBingbu Cao {
1770*8a89dc62SBingbu Cao 	/*
1771*8a89dc62SBingbu Cao 	 * Only one bayer order is supported.
1772*8a89dc62SBingbu Cao 	 * It depends on the flip settings.
1773*8a89dc62SBingbu Cao 	 */
1774*8a89dc62SBingbu Cao 	u32 code;
1775*8a89dc62SBingbu Cao 	static const u32 codes[2][2] = {
1776*8a89dc62SBingbu Cao 		{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
1777*8a89dc62SBingbu Cao 		{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
1778*8a89dc62SBingbu Cao 	};
1779*8a89dc62SBingbu Cao 
1780*8a89dc62SBingbu Cao 	lockdep_assert_held(&imx319->mutex);
1781*8a89dc62SBingbu Cao 	code = codes[imx319->vflip->val][imx319->hflip->val];
1782*8a89dc62SBingbu Cao 
1783*8a89dc62SBingbu Cao 	return code;
1784*8a89dc62SBingbu Cao }
1785*8a89dc62SBingbu Cao 
1786*8a89dc62SBingbu Cao /* Read registers up to 4 at a time */
1787*8a89dc62SBingbu Cao static int imx319_read_reg(struct imx319 *imx319, u16 reg, u32 len, u32 *val)
1788*8a89dc62SBingbu Cao {
1789*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1790*8a89dc62SBingbu Cao 	struct i2c_msg msgs[2];
1791*8a89dc62SBingbu Cao 	u8 addr_buf[2];
1792*8a89dc62SBingbu Cao 	u8 data_buf[4] = { 0 };
1793*8a89dc62SBingbu Cao 	int ret;
1794*8a89dc62SBingbu Cao 
1795*8a89dc62SBingbu Cao 	if (len > 4)
1796*8a89dc62SBingbu Cao 		return -EINVAL;
1797*8a89dc62SBingbu Cao 
1798*8a89dc62SBingbu Cao 	put_unaligned_be16(reg, addr_buf);
1799*8a89dc62SBingbu Cao 	/* Write register address */
1800*8a89dc62SBingbu Cao 	msgs[0].addr = client->addr;
1801*8a89dc62SBingbu Cao 	msgs[0].flags = 0;
1802*8a89dc62SBingbu Cao 	msgs[0].len = ARRAY_SIZE(addr_buf);
1803*8a89dc62SBingbu Cao 	msgs[0].buf = addr_buf;
1804*8a89dc62SBingbu Cao 
1805*8a89dc62SBingbu Cao 	/* Read data from register */
1806*8a89dc62SBingbu Cao 	msgs[1].addr = client->addr;
1807*8a89dc62SBingbu Cao 	msgs[1].flags = I2C_M_RD;
1808*8a89dc62SBingbu Cao 	msgs[1].len = len;
1809*8a89dc62SBingbu Cao 	msgs[1].buf = &data_buf[4 - len];
1810*8a89dc62SBingbu Cao 
1811*8a89dc62SBingbu Cao 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1812*8a89dc62SBingbu Cao 	if (ret != ARRAY_SIZE(msgs))
1813*8a89dc62SBingbu Cao 		return -EIO;
1814*8a89dc62SBingbu Cao 
1815*8a89dc62SBingbu Cao 	*val = get_unaligned_be32(data_buf);
1816*8a89dc62SBingbu Cao 
1817*8a89dc62SBingbu Cao 	return 0;
1818*8a89dc62SBingbu Cao }
1819*8a89dc62SBingbu Cao 
1820*8a89dc62SBingbu Cao /* Write registers up to 4 at a time */
1821*8a89dc62SBingbu Cao static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
1822*8a89dc62SBingbu Cao {
1823*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1824*8a89dc62SBingbu Cao 	u8 buf[6];
1825*8a89dc62SBingbu Cao 
1826*8a89dc62SBingbu Cao 	if (len > 4)
1827*8a89dc62SBingbu Cao 		return -EINVAL;
1828*8a89dc62SBingbu Cao 
1829*8a89dc62SBingbu Cao 	put_unaligned_be16(reg, buf);
1830*8a89dc62SBingbu Cao 	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1831*8a89dc62SBingbu Cao 	if (i2c_master_send(client, buf, len + 2) != len + 2)
1832*8a89dc62SBingbu Cao 		return -EIO;
1833*8a89dc62SBingbu Cao 
1834*8a89dc62SBingbu Cao 	return 0;
1835*8a89dc62SBingbu Cao }
1836*8a89dc62SBingbu Cao 
1837*8a89dc62SBingbu Cao /* Write a list of registers */
1838*8a89dc62SBingbu Cao static int imx319_write_regs(struct imx319 *imx319,
1839*8a89dc62SBingbu Cao 			      const struct imx319_reg *regs, u32 len)
1840*8a89dc62SBingbu Cao {
1841*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1842*8a89dc62SBingbu Cao 	int ret;
1843*8a89dc62SBingbu Cao 	u32 i;
1844*8a89dc62SBingbu Cao 
1845*8a89dc62SBingbu Cao 	for (i = 0; i < len; i++) {
1846*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
1847*8a89dc62SBingbu Cao 		if (ret) {
1848*8a89dc62SBingbu Cao 			dev_err_ratelimited(&client->dev,
1849*8a89dc62SBingbu Cao 					    "write reg 0x%4.4x return err %d",
1850*8a89dc62SBingbu Cao 					    regs[i].address, ret);
1851*8a89dc62SBingbu Cao 			return ret;
1852*8a89dc62SBingbu Cao 		}
1853*8a89dc62SBingbu Cao 	}
1854*8a89dc62SBingbu Cao 
1855*8a89dc62SBingbu Cao 	return 0;
1856*8a89dc62SBingbu Cao }
1857*8a89dc62SBingbu Cao 
1858*8a89dc62SBingbu Cao /* Open sub-device */
1859*8a89dc62SBingbu Cao static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1860*8a89dc62SBingbu Cao {
1861*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
1862*8a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *try_fmt =
1863*8a89dc62SBingbu Cao 		v4l2_subdev_get_try_format(sd, fh->pad, 0);
1864*8a89dc62SBingbu Cao 
1865*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
1866*8a89dc62SBingbu Cao 
1867*8a89dc62SBingbu Cao 	/* Initialize try_fmt */
1868*8a89dc62SBingbu Cao 	try_fmt->width = imx319->cur_mode->width;
1869*8a89dc62SBingbu Cao 	try_fmt->height = imx319->cur_mode->height;
1870*8a89dc62SBingbu Cao 	try_fmt->code = imx319_get_format_code(imx319);
1871*8a89dc62SBingbu Cao 	try_fmt->field = V4L2_FIELD_NONE;
1872*8a89dc62SBingbu Cao 
1873*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
1874*8a89dc62SBingbu Cao 
1875*8a89dc62SBingbu Cao 	return 0;
1876*8a89dc62SBingbu Cao }
1877*8a89dc62SBingbu Cao 
1878*8a89dc62SBingbu Cao static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
1879*8a89dc62SBingbu Cao {
1880*8a89dc62SBingbu Cao 	struct imx319 *imx319 = container_of(ctrl->handler,
1881*8a89dc62SBingbu Cao 					     struct imx319, ctrl_handler);
1882*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1883*8a89dc62SBingbu Cao 	s64 max;
1884*8a89dc62SBingbu Cao 	int ret;
1885*8a89dc62SBingbu Cao 
1886*8a89dc62SBingbu Cao 	/* Propagate change of current control to all related controls */
1887*8a89dc62SBingbu Cao 	switch (ctrl->id) {
1888*8a89dc62SBingbu Cao 	case V4L2_CID_VBLANK:
1889*8a89dc62SBingbu Cao 		/* Update max exposure while meeting expected vblanking */
1890*8a89dc62SBingbu Cao 		max = imx319->cur_mode->height + ctrl->val - 18;
1891*8a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->exposure,
1892*8a89dc62SBingbu Cao 					 imx319->exposure->minimum,
1893*8a89dc62SBingbu Cao 					 max, imx319->exposure->step, max);
1894*8a89dc62SBingbu Cao 		break;
1895*8a89dc62SBingbu Cao 	}
1896*8a89dc62SBingbu Cao 
1897*8a89dc62SBingbu Cao 	/*
1898*8a89dc62SBingbu Cao 	 * Applying V4L2 control value only happens
1899*8a89dc62SBingbu Cao 	 * when power is up for streaming
1900*8a89dc62SBingbu Cao 	 */
1901*8a89dc62SBingbu Cao 	if (!pm_runtime_get_if_in_use(&client->dev))
1902*8a89dc62SBingbu Cao 		return 0;
1903*8a89dc62SBingbu Cao 
1904*8a89dc62SBingbu Cao 	switch (ctrl->id) {
1905*8a89dc62SBingbu Cao 	case V4L2_CID_ANALOGUE_GAIN:
1906*8a89dc62SBingbu Cao 		/* Analog gain = 1024/(1024 - ctrl->val) times */
1907*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_ANALOG_GAIN, 2,
1908*8a89dc62SBingbu Cao 				       ctrl->val);
1909*8a89dc62SBingbu Cao 		break;
1910*8a89dc62SBingbu Cao 	case V4L2_CID_DIGITAL_GAIN:
1911*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_DIG_GAIN_GLOBAL, 2,
1912*8a89dc62SBingbu Cao 				       ctrl->val);
1913*8a89dc62SBingbu Cao 		break;
1914*8a89dc62SBingbu Cao 	case V4L2_CID_EXPOSURE:
1915*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_EXPOSURE, 2,
1916*8a89dc62SBingbu Cao 				       ctrl->val);
1917*8a89dc62SBingbu Cao 		break;
1918*8a89dc62SBingbu Cao 	case V4L2_CID_VBLANK:
1919*8a89dc62SBingbu Cao 		/* Update FLL that meets expected vertical blanking */
1920*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_FLL, 2,
1921*8a89dc62SBingbu Cao 				       imx319->cur_mode->height + ctrl->val);
1922*8a89dc62SBingbu Cao 		break;
1923*8a89dc62SBingbu Cao 	case V4L2_CID_TEST_PATTERN:
1924*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_TEST_PATTERN,
1925*8a89dc62SBingbu Cao 				       2, ctrl->val);
1926*8a89dc62SBingbu Cao 		break;
1927*8a89dc62SBingbu Cao 	case V4L2_CID_HFLIP:
1928*8a89dc62SBingbu Cao 	case V4L2_CID_VFLIP:
1929*8a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_ORIENTATION, 1,
1930*8a89dc62SBingbu Cao 				       imx319->hflip->val |
1931*8a89dc62SBingbu Cao 				       imx319->vflip->val << 1);
1932*8a89dc62SBingbu Cao 		break;
1933*8a89dc62SBingbu Cao 	default:
1934*8a89dc62SBingbu Cao 		ret = -EINVAL;
1935*8a89dc62SBingbu Cao 		dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
1936*8a89dc62SBingbu Cao 			 ctrl->id, ctrl->val);
1937*8a89dc62SBingbu Cao 		break;
1938*8a89dc62SBingbu Cao 	}
1939*8a89dc62SBingbu Cao 
1940*8a89dc62SBingbu Cao 	pm_runtime_put(&client->dev);
1941*8a89dc62SBingbu Cao 
1942*8a89dc62SBingbu Cao 	return ret;
1943*8a89dc62SBingbu Cao }
1944*8a89dc62SBingbu Cao 
1945*8a89dc62SBingbu Cao static const struct v4l2_ctrl_ops imx319_ctrl_ops = {
1946*8a89dc62SBingbu Cao 	.s_ctrl = imx319_set_ctrl,
1947*8a89dc62SBingbu Cao };
1948*8a89dc62SBingbu Cao 
1949*8a89dc62SBingbu Cao static int imx319_enum_mbus_code(struct v4l2_subdev *sd,
1950*8a89dc62SBingbu Cao 				  struct v4l2_subdev_pad_config *cfg,
1951*8a89dc62SBingbu Cao 				  struct v4l2_subdev_mbus_code_enum *code)
1952*8a89dc62SBingbu Cao {
1953*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
1954*8a89dc62SBingbu Cao 
1955*8a89dc62SBingbu Cao 	if (code->index > 0)
1956*8a89dc62SBingbu Cao 		return -EINVAL;
1957*8a89dc62SBingbu Cao 
1958*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
1959*8a89dc62SBingbu Cao 	code->code = imx319_get_format_code(imx319);
1960*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
1961*8a89dc62SBingbu Cao 
1962*8a89dc62SBingbu Cao 	return 0;
1963*8a89dc62SBingbu Cao }
1964*8a89dc62SBingbu Cao 
1965*8a89dc62SBingbu Cao static int imx319_enum_frame_size(struct v4l2_subdev *sd,
1966*8a89dc62SBingbu Cao 				   struct v4l2_subdev_pad_config *cfg,
1967*8a89dc62SBingbu Cao 				   struct v4l2_subdev_frame_size_enum *fse)
1968*8a89dc62SBingbu Cao {
1969*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
1970*8a89dc62SBingbu Cao 
1971*8a89dc62SBingbu Cao 	if (fse->index >= ARRAY_SIZE(supported_modes))
1972*8a89dc62SBingbu Cao 		return -EINVAL;
1973*8a89dc62SBingbu Cao 
1974*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
1975*8a89dc62SBingbu Cao 	if (fse->code != imx319_get_format_code(imx319)) {
1976*8a89dc62SBingbu Cao 		mutex_unlock(&imx319->mutex);
1977*8a89dc62SBingbu Cao 		return -EINVAL;
1978*8a89dc62SBingbu Cao 	}
1979*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
1980*8a89dc62SBingbu Cao 
1981*8a89dc62SBingbu Cao 	fse->min_width = supported_modes[fse->index].width;
1982*8a89dc62SBingbu Cao 	fse->max_width = fse->min_width;
1983*8a89dc62SBingbu Cao 	fse->min_height = supported_modes[fse->index].height;
1984*8a89dc62SBingbu Cao 	fse->max_height = fse->min_height;
1985*8a89dc62SBingbu Cao 
1986*8a89dc62SBingbu Cao 	return 0;
1987*8a89dc62SBingbu Cao }
1988*8a89dc62SBingbu Cao 
1989*8a89dc62SBingbu Cao static void imx319_update_pad_format(struct imx319 *imx319,
1990*8a89dc62SBingbu Cao 				     const struct imx319_mode *mode,
1991*8a89dc62SBingbu Cao 				     struct v4l2_subdev_format *fmt)
1992*8a89dc62SBingbu Cao {
1993*8a89dc62SBingbu Cao 	fmt->format.width = mode->width;
1994*8a89dc62SBingbu Cao 	fmt->format.height = mode->height;
1995*8a89dc62SBingbu Cao 	fmt->format.code = imx319_get_format_code(imx319);
1996*8a89dc62SBingbu Cao 	fmt->format.field = V4L2_FIELD_NONE;
1997*8a89dc62SBingbu Cao }
1998*8a89dc62SBingbu Cao 
1999*8a89dc62SBingbu Cao static int imx319_do_get_pad_format(struct imx319 *imx319,
2000*8a89dc62SBingbu Cao 				     struct v4l2_subdev_pad_config *cfg,
2001*8a89dc62SBingbu Cao 				     struct v4l2_subdev_format *fmt)
2002*8a89dc62SBingbu Cao {
2003*8a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *framefmt;
2004*8a89dc62SBingbu Cao 	struct v4l2_subdev *sd = &imx319->sd;
2005*8a89dc62SBingbu Cao 
2006*8a89dc62SBingbu Cao 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2007*8a89dc62SBingbu Cao 		framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2008*8a89dc62SBingbu Cao 		fmt->format = *framefmt;
2009*8a89dc62SBingbu Cao 	} else {
2010*8a89dc62SBingbu Cao 		imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
2011*8a89dc62SBingbu Cao 	}
2012*8a89dc62SBingbu Cao 
2013*8a89dc62SBingbu Cao 	return 0;
2014*8a89dc62SBingbu Cao }
2015*8a89dc62SBingbu Cao 
2016*8a89dc62SBingbu Cao static int imx319_get_pad_format(struct v4l2_subdev *sd,
2017*8a89dc62SBingbu Cao 				  struct v4l2_subdev_pad_config *cfg,
2018*8a89dc62SBingbu Cao 				  struct v4l2_subdev_format *fmt)
2019*8a89dc62SBingbu Cao {
2020*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2021*8a89dc62SBingbu Cao 	int ret;
2022*8a89dc62SBingbu Cao 
2023*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
2024*8a89dc62SBingbu Cao 	ret = imx319_do_get_pad_format(imx319, cfg, fmt);
2025*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
2026*8a89dc62SBingbu Cao 
2027*8a89dc62SBingbu Cao 	return ret;
2028*8a89dc62SBingbu Cao }
2029*8a89dc62SBingbu Cao 
2030*8a89dc62SBingbu Cao static int
2031*8a89dc62SBingbu Cao imx319_set_pad_format(struct v4l2_subdev *sd,
2032*8a89dc62SBingbu Cao 		       struct v4l2_subdev_pad_config *cfg,
2033*8a89dc62SBingbu Cao 		       struct v4l2_subdev_format *fmt)
2034*8a89dc62SBingbu Cao {
2035*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2036*8a89dc62SBingbu Cao 	const struct imx319_mode *mode;
2037*8a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *framefmt;
2038*8a89dc62SBingbu Cao 	s32 vblank_def;
2039*8a89dc62SBingbu Cao 	s32 vblank_min;
2040*8a89dc62SBingbu Cao 	s64 h_blank;
2041*8a89dc62SBingbu Cao 	u64 pixel_rate;
2042*8a89dc62SBingbu Cao 	u32 height;
2043*8a89dc62SBingbu Cao 
2044*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
2045*8a89dc62SBingbu Cao 
2046*8a89dc62SBingbu Cao 	/*
2047*8a89dc62SBingbu Cao 	 * Only one bayer order is supported.
2048*8a89dc62SBingbu Cao 	 * It depends on the flip settings.
2049*8a89dc62SBingbu Cao 	 */
2050*8a89dc62SBingbu Cao 	fmt->format.code = imx319_get_format_code(imx319);
2051*8a89dc62SBingbu Cao 
2052*8a89dc62SBingbu Cao 	mode = v4l2_find_nearest_size(supported_modes,
2053*8a89dc62SBingbu Cao 				      ARRAY_SIZE(supported_modes),
2054*8a89dc62SBingbu Cao 				      width, height,
2055*8a89dc62SBingbu Cao 				      fmt->format.width, fmt->format.height);
2056*8a89dc62SBingbu Cao 	imx319_update_pad_format(imx319, mode, fmt);
2057*8a89dc62SBingbu Cao 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2058*8a89dc62SBingbu Cao 		framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2059*8a89dc62SBingbu Cao 		*framefmt = fmt->format;
2060*8a89dc62SBingbu Cao 	} else {
2061*8a89dc62SBingbu Cao 		imx319->cur_mode = mode;
2062*8a89dc62SBingbu Cao 		pixel_rate = imx319->link_def_freq * 2 * 4;
2063*8a89dc62SBingbu Cao 		do_div(pixel_rate, 10);
2064*8a89dc62SBingbu Cao 		__v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
2065*8a89dc62SBingbu Cao 		/* Update limits and set FPS to default */
2066*8a89dc62SBingbu Cao 		height = imx319->cur_mode->height;
2067*8a89dc62SBingbu Cao 		vblank_def = imx319->cur_mode->fll_def - height;
2068*8a89dc62SBingbu Cao 		vblank_min = imx319->cur_mode->fll_min - height;
2069*8a89dc62SBingbu Cao 		height = IMX319_FLL_MAX - height;
2070*8a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->vblank, vblank_min, height, 1,
2071*8a89dc62SBingbu Cao 					 vblank_def);
2072*8a89dc62SBingbu Cao 		__v4l2_ctrl_s_ctrl(imx319->vblank, vblank_def);
2073*8a89dc62SBingbu Cao 		h_blank = mode->llp - imx319->cur_mode->width;
2074*8a89dc62SBingbu Cao 		/*
2075*8a89dc62SBingbu Cao 		 * Currently hblank is not changeable.
2076*8a89dc62SBingbu Cao 		 * So FPS control is done only by vblank.
2077*8a89dc62SBingbu Cao 		 */
2078*8a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->hblank, h_blank,
2079*8a89dc62SBingbu Cao 					 h_blank, 1, h_blank);
2080*8a89dc62SBingbu Cao 	}
2081*8a89dc62SBingbu Cao 
2082*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
2083*8a89dc62SBingbu Cao 
2084*8a89dc62SBingbu Cao 	return 0;
2085*8a89dc62SBingbu Cao }
2086*8a89dc62SBingbu Cao 
2087*8a89dc62SBingbu Cao /* Start streaming */
2088*8a89dc62SBingbu Cao static int imx319_start_streaming(struct imx319 *imx319)
2089*8a89dc62SBingbu Cao {
2090*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2091*8a89dc62SBingbu Cao 	const struct imx319_reg_list *reg_list;
2092*8a89dc62SBingbu Cao 	int ret;
2093*8a89dc62SBingbu Cao 
2094*8a89dc62SBingbu Cao 	/* Global Setting */
2095*8a89dc62SBingbu Cao 	reg_list = &imx319_global_setting;
2096*8a89dc62SBingbu Cao 	ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
2097*8a89dc62SBingbu Cao 	if (ret) {
2098*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to set global settings");
2099*8a89dc62SBingbu Cao 		return ret;
2100*8a89dc62SBingbu Cao 	}
2101*8a89dc62SBingbu Cao 
2102*8a89dc62SBingbu Cao 	/* Apply default values of current mode */
2103*8a89dc62SBingbu Cao 	reg_list = &imx319->cur_mode->reg_list;
2104*8a89dc62SBingbu Cao 	ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
2105*8a89dc62SBingbu Cao 	if (ret) {
2106*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to set mode");
2107*8a89dc62SBingbu Cao 		return ret;
2108*8a89dc62SBingbu Cao 	}
2109*8a89dc62SBingbu Cao 
2110*8a89dc62SBingbu Cao 	/* set digital gain control to all color mode */
2111*8a89dc62SBingbu Cao 	ret = imx319_write_reg(imx319, IMX319_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
2112*8a89dc62SBingbu Cao 	if (ret)
2113*8a89dc62SBingbu Cao 		return ret;
2114*8a89dc62SBingbu Cao 
2115*8a89dc62SBingbu Cao 	/* Apply customized values from user */
2116*8a89dc62SBingbu Cao 	ret =  __v4l2_ctrl_handler_setup(imx319->sd.ctrl_handler);
2117*8a89dc62SBingbu Cao 	if (ret)
2118*8a89dc62SBingbu Cao 		return ret;
2119*8a89dc62SBingbu Cao 
2120*8a89dc62SBingbu Cao 	return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
2121*8a89dc62SBingbu Cao 				1, IMX319_MODE_STREAMING);
2122*8a89dc62SBingbu Cao }
2123*8a89dc62SBingbu Cao 
2124*8a89dc62SBingbu Cao /* Stop streaming */
2125*8a89dc62SBingbu Cao static int imx319_stop_streaming(struct imx319 *imx319)
2126*8a89dc62SBingbu Cao {
2127*8a89dc62SBingbu Cao 	return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
2128*8a89dc62SBingbu Cao 				1, IMX319_MODE_STANDBY);
2129*8a89dc62SBingbu Cao }
2130*8a89dc62SBingbu Cao 
2131*8a89dc62SBingbu Cao static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
2132*8a89dc62SBingbu Cao {
2133*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2134*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(sd);
2135*8a89dc62SBingbu Cao 	int ret = 0;
2136*8a89dc62SBingbu Cao 
2137*8a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
2138*8a89dc62SBingbu Cao 	if (imx319->streaming == enable) {
2139*8a89dc62SBingbu Cao 		mutex_unlock(&imx319->mutex);
2140*8a89dc62SBingbu Cao 		return 0;
2141*8a89dc62SBingbu Cao 	}
2142*8a89dc62SBingbu Cao 
2143*8a89dc62SBingbu Cao 	if (enable) {
2144*8a89dc62SBingbu Cao 		ret = pm_runtime_get_sync(&client->dev);
2145*8a89dc62SBingbu Cao 		if (ret < 0) {
2146*8a89dc62SBingbu Cao 			pm_runtime_put_noidle(&client->dev);
2147*8a89dc62SBingbu Cao 			goto err_unlock;
2148*8a89dc62SBingbu Cao 		}
2149*8a89dc62SBingbu Cao 
2150*8a89dc62SBingbu Cao 		/*
2151*8a89dc62SBingbu Cao 		 * Apply default & customized values
2152*8a89dc62SBingbu Cao 		 * and then start streaming.
2153*8a89dc62SBingbu Cao 		 */
2154*8a89dc62SBingbu Cao 		ret = imx319_start_streaming(imx319);
2155*8a89dc62SBingbu Cao 		if (ret)
2156*8a89dc62SBingbu Cao 			goto err_rpm_put;
2157*8a89dc62SBingbu Cao 	} else {
2158*8a89dc62SBingbu Cao 		imx319_stop_streaming(imx319);
2159*8a89dc62SBingbu Cao 		pm_runtime_put(&client->dev);
2160*8a89dc62SBingbu Cao 	}
2161*8a89dc62SBingbu Cao 
2162*8a89dc62SBingbu Cao 	imx319->streaming = enable;
2163*8a89dc62SBingbu Cao 
2164*8a89dc62SBingbu Cao 	/* vflip and hflip cannot change during streaming */
2165*8a89dc62SBingbu Cao 	__v4l2_ctrl_grab(imx319->vflip, enable);
2166*8a89dc62SBingbu Cao 	__v4l2_ctrl_grab(imx319->hflip, enable);
2167*8a89dc62SBingbu Cao 
2168*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
2169*8a89dc62SBingbu Cao 
2170*8a89dc62SBingbu Cao 	return ret;
2171*8a89dc62SBingbu Cao 
2172*8a89dc62SBingbu Cao err_rpm_put:
2173*8a89dc62SBingbu Cao 	pm_runtime_put(&client->dev);
2174*8a89dc62SBingbu Cao err_unlock:
2175*8a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
2176*8a89dc62SBingbu Cao 
2177*8a89dc62SBingbu Cao 	return ret;
2178*8a89dc62SBingbu Cao }
2179*8a89dc62SBingbu Cao 
2180*8a89dc62SBingbu Cao static int __maybe_unused imx319_suspend(struct device *dev)
2181*8a89dc62SBingbu Cao {
2182*8a89dc62SBingbu Cao 	struct i2c_client *client = to_i2c_client(dev);
2183*8a89dc62SBingbu Cao 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2184*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2185*8a89dc62SBingbu Cao 
2186*8a89dc62SBingbu Cao 	if (imx319->streaming)
2187*8a89dc62SBingbu Cao 		imx319_stop_streaming(imx319);
2188*8a89dc62SBingbu Cao 
2189*8a89dc62SBingbu Cao 	return 0;
2190*8a89dc62SBingbu Cao }
2191*8a89dc62SBingbu Cao 
2192*8a89dc62SBingbu Cao static int __maybe_unused imx319_resume(struct device *dev)
2193*8a89dc62SBingbu Cao {
2194*8a89dc62SBingbu Cao 	struct i2c_client *client = to_i2c_client(dev);
2195*8a89dc62SBingbu Cao 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2196*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2197*8a89dc62SBingbu Cao 	int ret;
2198*8a89dc62SBingbu Cao 
2199*8a89dc62SBingbu Cao 	if (imx319->streaming) {
2200*8a89dc62SBingbu Cao 		ret = imx319_start_streaming(imx319);
2201*8a89dc62SBingbu Cao 		if (ret)
2202*8a89dc62SBingbu Cao 			goto error;
2203*8a89dc62SBingbu Cao 	}
2204*8a89dc62SBingbu Cao 
2205*8a89dc62SBingbu Cao 	return 0;
2206*8a89dc62SBingbu Cao 
2207*8a89dc62SBingbu Cao error:
2208*8a89dc62SBingbu Cao 	imx319_stop_streaming(imx319);
2209*8a89dc62SBingbu Cao 	imx319->streaming = 0;
2210*8a89dc62SBingbu Cao 	return ret;
2211*8a89dc62SBingbu Cao }
2212*8a89dc62SBingbu Cao 
2213*8a89dc62SBingbu Cao /* Verify chip ID */
2214*8a89dc62SBingbu Cao static int imx319_identify_module(struct imx319 *imx319)
2215*8a89dc62SBingbu Cao {
2216*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2217*8a89dc62SBingbu Cao 	int ret;
2218*8a89dc62SBingbu Cao 	u32 val;
2219*8a89dc62SBingbu Cao 
2220*8a89dc62SBingbu Cao 	ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
2221*8a89dc62SBingbu Cao 	if (ret)
2222*8a89dc62SBingbu Cao 		return ret;
2223*8a89dc62SBingbu Cao 
2224*8a89dc62SBingbu Cao 	if (val != IMX319_CHIP_ID) {
2225*8a89dc62SBingbu Cao 		dev_err(&client->dev, "chip id mismatch: %x!=%x",
2226*8a89dc62SBingbu Cao 			IMX319_CHIP_ID, val);
2227*8a89dc62SBingbu Cao 		return -EIO;
2228*8a89dc62SBingbu Cao 	}
2229*8a89dc62SBingbu Cao 
2230*8a89dc62SBingbu Cao 	return 0;
2231*8a89dc62SBingbu Cao }
2232*8a89dc62SBingbu Cao 
2233*8a89dc62SBingbu Cao static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
2234*8a89dc62SBingbu Cao 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
2235*8a89dc62SBingbu Cao 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
2236*8a89dc62SBingbu Cao };
2237*8a89dc62SBingbu Cao 
2238*8a89dc62SBingbu Cao static const struct v4l2_subdev_video_ops imx319_video_ops = {
2239*8a89dc62SBingbu Cao 	.s_stream = imx319_set_stream,
2240*8a89dc62SBingbu Cao };
2241*8a89dc62SBingbu Cao 
2242*8a89dc62SBingbu Cao static const struct v4l2_subdev_pad_ops imx319_pad_ops = {
2243*8a89dc62SBingbu Cao 	.enum_mbus_code = imx319_enum_mbus_code,
2244*8a89dc62SBingbu Cao 	.get_fmt = imx319_get_pad_format,
2245*8a89dc62SBingbu Cao 	.set_fmt = imx319_set_pad_format,
2246*8a89dc62SBingbu Cao 	.enum_frame_size = imx319_enum_frame_size,
2247*8a89dc62SBingbu Cao };
2248*8a89dc62SBingbu Cao 
2249*8a89dc62SBingbu Cao static const struct v4l2_subdev_ops imx319_subdev_ops = {
2250*8a89dc62SBingbu Cao 	.core = &imx319_subdev_core_ops,
2251*8a89dc62SBingbu Cao 	.video = &imx319_video_ops,
2252*8a89dc62SBingbu Cao 	.pad = &imx319_pad_ops,
2253*8a89dc62SBingbu Cao };
2254*8a89dc62SBingbu Cao 
2255*8a89dc62SBingbu Cao static const struct media_entity_operations imx319_subdev_entity_ops = {
2256*8a89dc62SBingbu Cao 	.link_validate = v4l2_subdev_link_validate,
2257*8a89dc62SBingbu Cao };
2258*8a89dc62SBingbu Cao 
2259*8a89dc62SBingbu Cao static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
2260*8a89dc62SBingbu Cao 	.open = imx319_open,
2261*8a89dc62SBingbu Cao };
2262*8a89dc62SBingbu Cao 
2263*8a89dc62SBingbu Cao /* Initialize control handlers */
2264*8a89dc62SBingbu Cao static int imx319_init_controls(struct imx319 *imx319)
2265*8a89dc62SBingbu Cao {
2266*8a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2267*8a89dc62SBingbu Cao 	struct v4l2_ctrl_handler *ctrl_hdlr;
2268*8a89dc62SBingbu Cao 	s64 exposure_max;
2269*8a89dc62SBingbu Cao 	s64 vblank_def;
2270*8a89dc62SBingbu Cao 	s64 vblank_min;
2271*8a89dc62SBingbu Cao 	s64 hblank;
2272*8a89dc62SBingbu Cao 	u64 pixel_rate;
2273*8a89dc62SBingbu Cao 	const struct imx319_mode *mode;
2274*8a89dc62SBingbu Cao 	u32 max;
2275*8a89dc62SBingbu Cao 	int ret;
2276*8a89dc62SBingbu Cao 
2277*8a89dc62SBingbu Cao 	ctrl_hdlr = &imx319->ctrl_handler;
2278*8a89dc62SBingbu Cao 	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
2279*8a89dc62SBingbu Cao 	if (ret)
2280*8a89dc62SBingbu Cao 		return ret;
2281*8a89dc62SBingbu Cao 
2282*8a89dc62SBingbu Cao 	ctrl_hdlr->lock = &imx319->mutex;
2283*8a89dc62SBingbu Cao 	max = ARRAY_SIZE(link_freq_menu_items) - 1;
2284*8a89dc62SBingbu Cao 	imx319->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx319_ctrl_ops,
2285*8a89dc62SBingbu Cao 						   V4L2_CID_LINK_FREQ, max, 0,
2286*8a89dc62SBingbu Cao 						   link_freq_menu_items);
2287*8a89dc62SBingbu Cao 	if (imx319->link_freq)
2288*8a89dc62SBingbu Cao 		imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2289*8a89dc62SBingbu Cao 
2290*8a89dc62SBingbu Cao 	/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
2291*8a89dc62SBingbu Cao 	pixel_rate = imx319->link_def_freq * 2 * 4;
2292*8a89dc62SBingbu Cao 	do_div(pixel_rate, 10);
2293*8a89dc62SBingbu Cao 	/* By default, PIXEL_RATE is read only */
2294*8a89dc62SBingbu Cao 	imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2295*8a89dc62SBingbu Cao 					       V4L2_CID_PIXEL_RATE, pixel_rate,
2296*8a89dc62SBingbu Cao 					       pixel_rate, 1, pixel_rate);
2297*8a89dc62SBingbu Cao 
2298*8a89dc62SBingbu Cao 	/* Initial vblank/hblank/exposure parameters based on current mode */
2299*8a89dc62SBingbu Cao 	mode = imx319->cur_mode;
2300*8a89dc62SBingbu Cao 	vblank_def = mode->fll_def - mode->height;
2301*8a89dc62SBingbu Cao 	vblank_min = mode->fll_min - mode->height;
2302*8a89dc62SBingbu Cao 	imx319->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2303*8a89dc62SBingbu Cao 					   V4L2_CID_VBLANK, vblank_min,
2304*8a89dc62SBingbu Cao 					   IMX319_FLL_MAX - mode->height,
2305*8a89dc62SBingbu Cao 					   1, vblank_def);
2306*8a89dc62SBingbu Cao 
2307*8a89dc62SBingbu Cao 	hblank = mode->llp - mode->width;
2308*8a89dc62SBingbu Cao 	imx319->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2309*8a89dc62SBingbu Cao 					   V4L2_CID_HBLANK, hblank, hblank,
2310*8a89dc62SBingbu Cao 					   1, hblank);
2311*8a89dc62SBingbu Cao 	if (imx319->hblank)
2312*8a89dc62SBingbu Cao 		imx319->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2313*8a89dc62SBingbu Cao 
2314*8a89dc62SBingbu Cao 	/* fll >= exposure time + adjust parameter (default value is 18) */
2315*8a89dc62SBingbu Cao 	exposure_max = mode->fll_def - 18;
2316*8a89dc62SBingbu Cao 	imx319->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2317*8a89dc62SBingbu Cao 					     V4L2_CID_EXPOSURE,
2318*8a89dc62SBingbu Cao 					     IMX319_EXPOSURE_MIN, exposure_max,
2319*8a89dc62SBingbu Cao 					     IMX319_EXPOSURE_STEP,
2320*8a89dc62SBingbu Cao 					     IMX319_EXPOSURE_DEFAULT);
2321*8a89dc62SBingbu Cao 
2322*8a89dc62SBingbu Cao 	imx319->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2323*8a89dc62SBingbu Cao 					  V4L2_CID_HFLIP, 0, 1, 1, 0);
2324*8a89dc62SBingbu Cao 	imx319->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2325*8a89dc62SBingbu Cao 					  V4L2_CID_VFLIP, 0, 1, 1, 0);
2326*8a89dc62SBingbu Cao 
2327*8a89dc62SBingbu Cao 	v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
2328*8a89dc62SBingbu Cao 			  IMX319_ANA_GAIN_MIN, IMX319_ANA_GAIN_MAX,
2329*8a89dc62SBingbu Cao 			  IMX319_ANA_GAIN_STEP, IMX319_ANA_GAIN_DEFAULT);
2330*8a89dc62SBingbu Cao 
2331*8a89dc62SBingbu Cao 	/* Digital gain */
2332*8a89dc62SBingbu Cao 	v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
2333*8a89dc62SBingbu Cao 			  IMX319_DGTL_GAIN_MIN, IMX319_DGTL_GAIN_MAX,
2334*8a89dc62SBingbu Cao 			  IMX319_DGTL_GAIN_STEP, IMX319_DGTL_GAIN_DEFAULT);
2335*8a89dc62SBingbu Cao 
2336*8a89dc62SBingbu Cao 	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx319_ctrl_ops,
2337*8a89dc62SBingbu Cao 				     V4L2_CID_TEST_PATTERN,
2338*8a89dc62SBingbu Cao 				     ARRAY_SIZE(imx319_test_pattern_menu) - 1,
2339*8a89dc62SBingbu Cao 				     0, 0, imx319_test_pattern_menu);
2340*8a89dc62SBingbu Cao 	if (ctrl_hdlr->error) {
2341*8a89dc62SBingbu Cao 		ret = ctrl_hdlr->error;
2342*8a89dc62SBingbu Cao 		dev_err(&client->dev, "control init failed: %d", ret);
2343*8a89dc62SBingbu Cao 		goto error;
2344*8a89dc62SBingbu Cao 	}
2345*8a89dc62SBingbu Cao 
2346*8a89dc62SBingbu Cao 	imx319->sd.ctrl_handler = ctrl_hdlr;
2347*8a89dc62SBingbu Cao 
2348*8a89dc62SBingbu Cao 	return 0;
2349*8a89dc62SBingbu Cao 
2350*8a89dc62SBingbu Cao error:
2351*8a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(ctrl_hdlr);
2352*8a89dc62SBingbu Cao 
2353*8a89dc62SBingbu Cao 	return ret;
2354*8a89dc62SBingbu Cao }
2355*8a89dc62SBingbu Cao 
2356*8a89dc62SBingbu Cao static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
2357*8a89dc62SBingbu Cao {
2358*8a89dc62SBingbu Cao 	struct imx319_hwcfg *cfg;
2359*8a89dc62SBingbu Cao 	struct v4l2_fwnode_endpoint bus_cfg = {
2360*8a89dc62SBingbu Cao 		.bus_type = V4L2_MBUS_CSI2_DPHY
2361*8a89dc62SBingbu Cao 	};
2362*8a89dc62SBingbu Cao 	struct fwnode_handle *ep;
2363*8a89dc62SBingbu Cao 	struct fwnode_handle *fwnode = dev_fwnode(dev);
2364*8a89dc62SBingbu Cao 	unsigned int i;
2365*8a89dc62SBingbu Cao 	int ret;
2366*8a89dc62SBingbu Cao 
2367*8a89dc62SBingbu Cao 	if (!fwnode)
2368*8a89dc62SBingbu Cao 		return NULL;
2369*8a89dc62SBingbu Cao 
2370*8a89dc62SBingbu Cao 	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
2371*8a89dc62SBingbu Cao 	if (!ep)
2372*8a89dc62SBingbu Cao 		return NULL;
2373*8a89dc62SBingbu Cao 
2374*8a89dc62SBingbu Cao 	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
2375*8a89dc62SBingbu Cao 	if (ret)
2376*8a89dc62SBingbu Cao 		goto out_err;
2377*8a89dc62SBingbu Cao 
2378*8a89dc62SBingbu Cao 	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
2379*8a89dc62SBingbu Cao 	if (!cfg)
2380*8a89dc62SBingbu Cao 		goto out_err;
2381*8a89dc62SBingbu Cao 
2382*8a89dc62SBingbu Cao 	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
2383*8a89dc62SBingbu Cao 					&cfg->ext_clk);
2384*8a89dc62SBingbu Cao 	if (ret) {
2385*8a89dc62SBingbu Cao 		dev_err(dev, "can't get clock frequency");
2386*8a89dc62SBingbu Cao 		goto out_err;
2387*8a89dc62SBingbu Cao 	}
2388*8a89dc62SBingbu Cao 
2389*8a89dc62SBingbu Cao 	dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
2390*8a89dc62SBingbu Cao 	if (cfg->ext_clk != IMX319_EXT_CLK) {
2391*8a89dc62SBingbu Cao 		dev_err(dev, "external clock %d is not supported",
2392*8a89dc62SBingbu Cao 			 cfg->ext_clk);
2393*8a89dc62SBingbu Cao 		goto out_err;
2394*8a89dc62SBingbu Cao 	}
2395*8a89dc62SBingbu Cao 
2396*8a89dc62SBingbu Cao 	dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
2397*8a89dc62SBingbu Cao 	if (!bus_cfg.nr_of_link_frequencies) {
2398*8a89dc62SBingbu Cao 		dev_warn(dev, "no link frequencies defined");
2399*8a89dc62SBingbu Cao 		goto out_err;
2400*8a89dc62SBingbu Cao 	}
2401*8a89dc62SBingbu Cao 
2402*8a89dc62SBingbu Cao 	cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
2403*8a89dc62SBingbu Cao 	cfg->link_freqs = devm_kcalloc(
2404*8a89dc62SBingbu Cao 		dev, bus_cfg.nr_of_link_frequencies + 1,
2405*8a89dc62SBingbu Cao 		sizeof(*cfg->link_freqs), GFP_KERNEL);
2406*8a89dc62SBingbu Cao 	if (!cfg->link_freqs)
2407*8a89dc62SBingbu Cao 		goto out_err;
2408*8a89dc62SBingbu Cao 
2409*8a89dc62SBingbu Cao 	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
2410*8a89dc62SBingbu Cao 		cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
2411*8a89dc62SBingbu Cao 		dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
2412*8a89dc62SBingbu Cao 	}
2413*8a89dc62SBingbu Cao 
2414*8a89dc62SBingbu Cao 	v4l2_fwnode_endpoint_free(&bus_cfg);
2415*8a89dc62SBingbu Cao 	fwnode_handle_put(ep);
2416*8a89dc62SBingbu Cao 	return cfg;
2417*8a89dc62SBingbu Cao 
2418*8a89dc62SBingbu Cao out_err:
2419*8a89dc62SBingbu Cao 	v4l2_fwnode_endpoint_free(&bus_cfg);
2420*8a89dc62SBingbu Cao 	fwnode_handle_put(ep);
2421*8a89dc62SBingbu Cao 	return NULL;
2422*8a89dc62SBingbu Cao }
2423*8a89dc62SBingbu Cao 
2424*8a89dc62SBingbu Cao static int imx319_probe(struct i2c_client *client)
2425*8a89dc62SBingbu Cao {
2426*8a89dc62SBingbu Cao 	struct imx319 *imx319;
2427*8a89dc62SBingbu Cao 	int ret;
2428*8a89dc62SBingbu Cao 	u32 i;
2429*8a89dc62SBingbu Cao 
2430*8a89dc62SBingbu Cao 	imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
2431*8a89dc62SBingbu Cao 	if (!imx319)
2432*8a89dc62SBingbu Cao 		return -ENOMEM;
2433*8a89dc62SBingbu Cao 
2434*8a89dc62SBingbu Cao 	mutex_init(&imx319->mutex);
2435*8a89dc62SBingbu Cao 
2436*8a89dc62SBingbu Cao 	/* Initialize subdev */
2437*8a89dc62SBingbu Cao 	v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
2438*8a89dc62SBingbu Cao 
2439*8a89dc62SBingbu Cao 	/* Check module identity */
2440*8a89dc62SBingbu Cao 	ret = imx319_identify_module(imx319);
2441*8a89dc62SBingbu Cao 	if (ret) {
2442*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to find sensor: %d", ret);
2443*8a89dc62SBingbu Cao 		goto error_probe;
2444*8a89dc62SBingbu Cao 	}
2445*8a89dc62SBingbu Cao 
2446*8a89dc62SBingbu Cao 	imx319->hwcfg = imx319_get_hwcfg(&client->dev);
2447*8a89dc62SBingbu Cao 	if (!imx319->hwcfg) {
2448*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to get hwcfg");
2449*8a89dc62SBingbu Cao 		ret = -ENODEV;
2450*8a89dc62SBingbu Cao 		goto error_probe;
2451*8a89dc62SBingbu Cao 	}
2452*8a89dc62SBingbu Cao 
2453*8a89dc62SBingbu Cao 	imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
2454*8a89dc62SBingbu Cao 	for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
2455*8a89dc62SBingbu Cao 		if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
2456*8a89dc62SBingbu Cao 			dev_dbg(&client->dev, "link freq index %d matched", i);
2457*8a89dc62SBingbu Cao 			break;
2458*8a89dc62SBingbu Cao 		}
2459*8a89dc62SBingbu Cao 	}
2460*8a89dc62SBingbu Cao 
2461*8a89dc62SBingbu Cao 	if (i == imx319->hwcfg->nr_of_link_freqs) {
2462*8a89dc62SBingbu Cao 		dev_err(&client->dev, "no link frequency supported");
2463*8a89dc62SBingbu Cao 		ret = -EINVAL;
2464*8a89dc62SBingbu Cao 		goto error_probe;
2465*8a89dc62SBingbu Cao 	}
2466*8a89dc62SBingbu Cao 
2467*8a89dc62SBingbu Cao 	/* Set default mode to max resolution */
2468*8a89dc62SBingbu Cao 	imx319->cur_mode = &supported_modes[0];
2469*8a89dc62SBingbu Cao 
2470*8a89dc62SBingbu Cao 	ret = imx319_init_controls(imx319);
2471*8a89dc62SBingbu Cao 	if (ret) {
2472*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to init controls: %d", ret);
2473*8a89dc62SBingbu Cao 		goto error_probe;
2474*8a89dc62SBingbu Cao 	}
2475*8a89dc62SBingbu Cao 
2476*8a89dc62SBingbu Cao 	/* Initialize subdev */
2477*8a89dc62SBingbu Cao 	imx319->sd.internal_ops = &imx319_internal_ops;
2478*8a89dc62SBingbu Cao 	imx319->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
2479*8a89dc62SBingbu Cao 		V4L2_SUBDEV_FL_HAS_EVENTS;
2480*8a89dc62SBingbu Cao 	imx319->sd.entity.ops = &imx319_subdev_entity_ops;
2481*8a89dc62SBingbu Cao 	imx319->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
2482*8a89dc62SBingbu Cao 
2483*8a89dc62SBingbu Cao 	/* Initialize source pad */
2484*8a89dc62SBingbu Cao 	imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
2485*8a89dc62SBingbu Cao 	ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
2486*8a89dc62SBingbu Cao 	if (ret) {
2487*8a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to init entity pads: %d", ret);
2488*8a89dc62SBingbu Cao 		goto error_handler_free;
2489*8a89dc62SBingbu Cao 	}
2490*8a89dc62SBingbu Cao 
2491*8a89dc62SBingbu Cao 	ret = v4l2_async_register_subdev_sensor_common(&imx319->sd);
2492*8a89dc62SBingbu Cao 	if (ret < 0)
2493*8a89dc62SBingbu Cao 		goto error_media_entity;
2494*8a89dc62SBingbu Cao 
2495*8a89dc62SBingbu Cao 	/*
2496*8a89dc62SBingbu Cao 	 * Device is already turned on by i2c-core with ACPI domain PM.
2497*8a89dc62SBingbu Cao 	 * Enable runtime PM and turn off the device.
2498*8a89dc62SBingbu Cao 	 */
2499*8a89dc62SBingbu Cao 	pm_runtime_set_active(&client->dev);
2500*8a89dc62SBingbu Cao 	pm_runtime_enable(&client->dev);
2501*8a89dc62SBingbu Cao 	pm_runtime_idle(&client->dev);
2502*8a89dc62SBingbu Cao 
2503*8a89dc62SBingbu Cao 	return 0;
2504*8a89dc62SBingbu Cao 
2505*8a89dc62SBingbu Cao error_media_entity:
2506*8a89dc62SBingbu Cao 	media_entity_cleanup(&imx319->sd.entity);
2507*8a89dc62SBingbu Cao 
2508*8a89dc62SBingbu Cao error_handler_free:
2509*8a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(imx319->sd.ctrl_handler);
2510*8a89dc62SBingbu Cao 
2511*8a89dc62SBingbu Cao error_probe:
2512*8a89dc62SBingbu Cao 	mutex_destroy(&imx319->mutex);
2513*8a89dc62SBingbu Cao 
2514*8a89dc62SBingbu Cao 	return ret;
2515*8a89dc62SBingbu Cao }
2516*8a89dc62SBingbu Cao 
2517*8a89dc62SBingbu Cao static int imx319_remove(struct i2c_client *client)
2518*8a89dc62SBingbu Cao {
2519*8a89dc62SBingbu Cao 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
2520*8a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
2521*8a89dc62SBingbu Cao 
2522*8a89dc62SBingbu Cao 	v4l2_async_unregister_subdev(sd);
2523*8a89dc62SBingbu Cao 	media_entity_cleanup(&sd->entity);
2524*8a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(sd->ctrl_handler);
2525*8a89dc62SBingbu Cao 
2526*8a89dc62SBingbu Cao 	pm_runtime_disable(&client->dev);
2527*8a89dc62SBingbu Cao 	pm_runtime_set_suspended(&client->dev);
2528*8a89dc62SBingbu Cao 
2529*8a89dc62SBingbu Cao 	mutex_destroy(&imx319->mutex);
2530*8a89dc62SBingbu Cao 
2531*8a89dc62SBingbu Cao 	return 0;
2532*8a89dc62SBingbu Cao }
2533*8a89dc62SBingbu Cao 
2534*8a89dc62SBingbu Cao static const struct dev_pm_ops imx319_pm_ops = {
2535*8a89dc62SBingbu Cao 	SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
2536*8a89dc62SBingbu Cao };
2537*8a89dc62SBingbu Cao 
2538*8a89dc62SBingbu Cao static const struct acpi_device_id imx319_acpi_ids[] = {
2539*8a89dc62SBingbu Cao 	{ "SONY319A" },
2540*8a89dc62SBingbu Cao 	{ /* sentinel */ }
2541*8a89dc62SBingbu Cao };
2542*8a89dc62SBingbu Cao MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
2543*8a89dc62SBingbu Cao 
2544*8a89dc62SBingbu Cao static struct i2c_driver imx319_i2c_driver = {
2545*8a89dc62SBingbu Cao 	.driver = {
2546*8a89dc62SBingbu Cao 		.name = "imx319",
2547*8a89dc62SBingbu Cao 		.pm = &imx319_pm_ops,
2548*8a89dc62SBingbu Cao 		.acpi_match_table = ACPI_PTR(imx319_acpi_ids),
2549*8a89dc62SBingbu Cao 	},
2550*8a89dc62SBingbu Cao 	.probe_new = imx319_probe,
2551*8a89dc62SBingbu Cao 	.remove = imx319_remove,
2552*8a89dc62SBingbu Cao };
2553*8a89dc62SBingbu Cao module_i2c_driver(imx319_i2c_driver);
2554*8a89dc62SBingbu Cao 
2555*8a89dc62SBingbu Cao MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
2556*8a89dc62SBingbu Cao MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
2557*8a89dc62SBingbu Cao MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
2558*8a89dc62SBingbu Cao MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
2559*8a89dc62SBingbu Cao MODULE_DESCRIPTION("Sony imx319 sensor driver");
2560*8a89dc62SBingbu Cao MODULE_LICENSE("GPL v2");
2561