xref: /openbmc/linux/drivers/media/i2c/imx319.c (revision 4106cd72)
18a89dc62SBingbu Cao // SPDX-License-Identifier: GPL-2.0
28a89dc62SBingbu Cao // Copyright (C) 2018 Intel Corporation
38a89dc62SBingbu Cao 
48a89dc62SBingbu Cao #include <asm/unaligned.h>
58a89dc62SBingbu Cao #include <linux/acpi.h>
68a89dc62SBingbu Cao #include <linux/i2c.h>
78a89dc62SBingbu Cao #include <linux/module.h>
88a89dc62SBingbu Cao #include <linux/pm_runtime.h>
98a89dc62SBingbu Cao #include <media/v4l2-ctrls.h>
108a89dc62SBingbu Cao #include <media/v4l2-device.h>
118a89dc62SBingbu Cao #include <media/v4l2-event.h>
128a89dc62SBingbu Cao #include <media/v4l2-fwnode.h>
138a89dc62SBingbu Cao 
148a89dc62SBingbu Cao #define IMX319_REG_MODE_SELECT		0x0100
158a89dc62SBingbu Cao #define IMX319_MODE_STANDBY		0x00
168a89dc62SBingbu Cao #define IMX319_MODE_STREAMING		0x01
178a89dc62SBingbu Cao 
188a89dc62SBingbu Cao /* Chip ID */
198a89dc62SBingbu Cao #define IMX319_REG_CHIP_ID		0x0016
208a89dc62SBingbu Cao #define IMX319_CHIP_ID			0x0319
218a89dc62SBingbu Cao 
228a89dc62SBingbu Cao /* V_TIMING internal */
238a89dc62SBingbu Cao #define IMX319_REG_FLL			0x0340
248a89dc62SBingbu Cao #define IMX319_FLL_MAX			0xffff
258a89dc62SBingbu Cao 
268a89dc62SBingbu Cao /* Exposure control */
278a89dc62SBingbu Cao #define IMX319_REG_EXPOSURE		0x0202
288a89dc62SBingbu Cao #define IMX319_EXPOSURE_MIN		1
298a89dc62SBingbu Cao #define IMX319_EXPOSURE_STEP		1
308a89dc62SBingbu Cao #define IMX319_EXPOSURE_DEFAULT		0x04f6
318a89dc62SBingbu Cao 
328a89dc62SBingbu Cao /*
338a89dc62SBingbu Cao  *  the digital control register for all color control looks like:
348a89dc62SBingbu Cao  *  +-----------------+------------------+
358a89dc62SBingbu Cao  *  |      [7:0]      |       [15:8]     |
368a89dc62SBingbu Cao  *  +-----------------+------------------+
378a89dc62SBingbu Cao  *  |	  0x020f      |       0x020e     |
388a89dc62SBingbu Cao  *  --------------------------------------
398a89dc62SBingbu Cao  *  it is used to calculate the digital gain times value(integral + fractional)
408a89dc62SBingbu Cao  *  the [15:8] bits is the fractional part and [7:0] bits is the integral
418a89dc62SBingbu Cao  *  calculation equation is:
428a89dc62SBingbu Cao  *      gain value (unit: times) = REG[15:8] + REG[7:0]/0x100
438a89dc62SBingbu Cao  *  Only value in 0x0100 ~ 0x0FFF range is allowed.
448a89dc62SBingbu Cao  *  Analog gain use 10 bits in the registers and allowed range is 0 ~ 960
458a89dc62SBingbu Cao  */
468a89dc62SBingbu Cao /* Analog gain control */
478a89dc62SBingbu Cao #define IMX319_REG_ANALOG_GAIN		0x0204
488a89dc62SBingbu Cao #define IMX319_ANA_GAIN_MIN		0
498a89dc62SBingbu Cao #define IMX319_ANA_GAIN_MAX		960
508a89dc62SBingbu Cao #define IMX319_ANA_GAIN_STEP		1
518a89dc62SBingbu Cao #define IMX319_ANA_GAIN_DEFAULT		0
528a89dc62SBingbu Cao 
538a89dc62SBingbu Cao /* Digital gain control */
548a89dc62SBingbu Cao #define IMX319_REG_DPGA_USE_GLOBAL_GAIN	0x3ff9
558a89dc62SBingbu Cao #define IMX319_REG_DIG_GAIN_GLOBAL	0x020e
568a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_MIN		256
578a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_MAX		4095
588a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_STEP		1
598a89dc62SBingbu Cao #define IMX319_DGTL_GAIN_DEFAULT	256
608a89dc62SBingbu Cao 
618a89dc62SBingbu Cao /* Test Pattern Control */
628a89dc62SBingbu Cao #define IMX319_REG_TEST_PATTERN		0x0600
638a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_DISABLED		0
648a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_SOLID_COLOR		1
658a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_COLOR_BARS		2
668a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_GRAY_COLOR_BARS	3
678a89dc62SBingbu Cao #define IMX319_TEST_PATTERN_PN9			4
688a89dc62SBingbu Cao 
698a89dc62SBingbu Cao /* Flip Control */
708a89dc62SBingbu Cao #define IMX319_REG_ORIENTATION		0x0101
718a89dc62SBingbu Cao 
728a89dc62SBingbu Cao /* default link frequency and external clock */
738a89dc62SBingbu Cao #define IMX319_LINK_FREQ_DEFAULT	482400000
748a89dc62SBingbu Cao #define IMX319_EXT_CLK			19200000
758a89dc62SBingbu Cao #define IMX319_LINK_FREQ_INDEX		0
768a89dc62SBingbu Cao 
778a89dc62SBingbu Cao struct imx319_reg {
788a89dc62SBingbu Cao 	u16 address;
798a89dc62SBingbu Cao 	u8 val;
808a89dc62SBingbu Cao };
818a89dc62SBingbu Cao 
828a89dc62SBingbu Cao struct imx319_reg_list {
838a89dc62SBingbu Cao 	u32 num_of_regs;
848a89dc62SBingbu Cao 	const struct imx319_reg *regs;
858a89dc62SBingbu Cao };
868a89dc62SBingbu Cao 
878a89dc62SBingbu Cao /* Mode : resolution and related config&values */
888a89dc62SBingbu Cao struct imx319_mode {
898a89dc62SBingbu Cao 	/* Frame width */
908a89dc62SBingbu Cao 	u32 width;
918a89dc62SBingbu Cao 	/* Frame height */
928a89dc62SBingbu Cao 	u32 height;
938a89dc62SBingbu Cao 
948a89dc62SBingbu Cao 	/* V-timing */
958a89dc62SBingbu Cao 	u32 fll_def;
968a89dc62SBingbu Cao 	u32 fll_min;
978a89dc62SBingbu Cao 
988a89dc62SBingbu Cao 	/* H-timing */
998a89dc62SBingbu Cao 	u32 llp;
1008a89dc62SBingbu Cao 
1018a89dc62SBingbu Cao 	/* index of link frequency */
1028a89dc62SBingbu Cao 	u32 link_freq_index;
1038a89dc62SBingbu Cao 
1048a89dc62SBingbu Cao 	/* Default register values */
1058a89dc62SBingbu Cao 	struct imx319_reg_list reg_list;
1068a89dc62SBingbu Cao };
1078a89dc62SBingbu Cao 
1088a89dc62SBingbu Cao struct imx319_hwcfg {
1098a89dc62SBingbu Cao 	u32 ext_clk;			/* sensor external clk */
1108a89dc62SBingbu Cao 	s64 *link_freqs;		/* CSI-2 link frequencies */
1118a89dc62SBingbu Cao 	unsigned int nr_of_link_freqs;
1128a89dc62SBingbu Cao };
1138a89dc62SBingbu Cao 
1148a89dc62SBingbu Cao struct imx319 {
1158a89dc62SBingbu Cao 	struct v4l2_subdev sd;
1168a89dc62SBingbu Cao 	struct media_pad pad;
1178a89dc62SBingbu Cao 
1188a89dc62SBingbu Cao 	struct v4l2_ctrl_handler ctrl_handler;
1198a89dc62SBingbu Cao 	/* V4L2 Controls */
1208a89dc62SBingbu Cao 	struct v4l2_ctrl *link_freq;
1218a89dc62SBingbu Cao 	struct v4l2_ctrl *pixel_rate;
1228a89dc62SBingbu Cao 	struct v4l2_ctrl *vblank;
1238a89dc62SBingbu Cao 	struct v4l2_ctrl *hblank;
1248a89dc62SBingbu Cao 	struct v4l2_ctrl *exposure;
1258a89dc62SBingbu Cao 	struct v4l2_ctrl *vflip;
1268a89dc62SBingbu Cao 	struct v4l2_ctrl *hflip;
1278a89dc62SBingbu Cao 
1288a89dc62SBingbu Cao 	/* Current mode */
1298a89dc62SBingbu Cao 	const struct imx319_mode *cur_mode;
1308a89dc62SBingbu Cao 
1318a89dc62SBingbu Cao 	struct imx319_hwcfg *hwcfg;
1328a89dc62SBingbu Cao 	s64 link_def_freq;	/* CSI-2 link default frequency */
1338a89dc62SBingbu Cao 
1348a89dc62SBingbu Cao 	/*
1358a89dc62SBingbu Cao 	 * Mutex for serialized access:
1368a89dc62SBingbu Cao 	 * Protect sensor set pad format and start/stop streaming safely.
1378a89dc62SBingbu Cao 	 * Protect access to sensor v4l2 controls.
1388a89dc62SBingbu Cao 	 */
1398a89dc62SBingbu Cao 	struct mutex mutex;
1408a89dc62SBingbu Cao 
1418a89dc62SBingbu Cao 	/* Streaming on/off */
1428a89dc62SBingbu Cao 	bool streaming;
143434aa74bSRajmohan Mani 	/* True if the device has been identified */
144434aa74bSRajmohan Mani 	bool identified;
1458a89dc62SBingbu Cao };
1468a89dc62SBingbu Cao 
1478a89dc62SBingbu Cao static const struct imx319_reg imx319_global_regs[] = {
1488a89dc62SBingbu Cao 	{ 0x0136, 0x13 },
1498a89dc62SBingbu Cao 	{ 0x0137, 0x33 },
1508a89dc62SBingbu Cao 	{ 0x3c7e, 0x05 },
1518a89dc62SBingbu Cao 	{ 0x3c7f, 0x07 },
1528a89dc62SBingbu Cao 	{ 0x4d39, 0x0b },
1538a89dc62SBingbu Cao 	{ 0x4d41, 0x33 },
1548a89dc62SBingbu Cao 	{ 0x4d43, 0x0c },
1558a89dc62SBingbu Cao 	{ 0x4d49, 0x89 },
1568a89dc62SBingbu Cao 	{ 0x4e05, 0x0b },
1578a89dc62SBingbu Cao 	{ 0x4e0d, 0x33 },
1588a89dc62SBingbu Cao 	{ 0x4e0f, 0x0c },
1598a89dc62SBingbu Cao 	{ 0x4e15, 0x89 },
1608a89dc62SBingbu Cao 	{ 0x4e49, 0x2a },
1618a89dc62SBingbu Cao 	{ 0x4e51, 0x33 },
1628a89dc62SBingbu Cao 	{ 0x4e53, 0x0c },
1638a89dc62SBingbu Cao 	{ 0x4e59, 0x89 },
1648a89dc62SBingbu Cao 	{ 0x5601, 0x4f },
1658a89dc62SBingbu Cao 	{ 0x560b, 0x45 },
1668a89dc62SBingbu Cao 	{ 0x562f, 0x0a },
1678a89dc62SBingbu Cao 	{ 0x5643, 0x0a },
1688a89dc62SBingbu Cao 	{ 0x5645, 0x0c },
1698a89dc62SBingbu Cao 	{ 0x56ef, 0x51 },
1708a89dc62SBingbu Cao 	{ 0x586f, 0x33 },
1718a89dc62SBingbu Cao 	{ 0x5873, 0x89 },
1728a89dc62SBingbu Cao 	{ 0x5905, 0x33 },
1738a89dc62SBingbu Cao 	{ 0x5907, 0x89 },
1748a89dc62SBingbu Cao 	{ 0x590d, 0x33 },
1758a89dc62SBingbu Cao 	{ 0x590f, 0x89 },
1768a89dc62SBingbu Cao 	{ 0x5915, 0x33 },
1778a89dc62SBingbu Cao 	{ 0x5917, 0x89 },
1788a89dc62SBingbu Cao 	{ 0x5969, 0x1c },
1798a89dc62SBingbu Cao 	{ 0x596b, 0x72 },
1808a89dc62SBingbu Cao 	{ 0x5971, 0x33 },
1818a89dc62SBingbu Cao 	{ 0x5973, 0x89 },
1828a89dc62SBingbu Cao 	{ 0x5975, 0x33 },
1838a89dc62SBingbu Cao 	{ 0x5977, 0x89 },
1848a89dc62SBingbu Cao 	{ 0x5979, 0x1c },
1858a89dc62SBingbu Cao 	{ 0x597b, 0x72 },
1868a89dc62SBingbu Cao 	{ 0x5985, 0x33 },
1878a89dc62SBingbu Cao 	{ 0x5987, 0x89 },
1888a89dc62SBingbu Cao 	{ 0x5999, 0x1c },
1898a89dc62SBingbu Cao 	{ 0x599b, 0x72 },
1908a89dc62SBingbu Cao 	{ 0x59a5, 0x33 },
1918a89dc62SBingbu Cao 	{ 0x59a7, 0x89 },
1928a89dc62SBingbu Cao 	{ 0x7485, 0x08 },
1938a89dc62SBingbu Cao 	{ 0x7487, 0x0c },
1948a89dc62SBingbu Cao 	{ 0x7489, 0xc7 },
1958a89dc62SBingbu Cao 	{ 0x748b, 0x8b },
1968a89dc62SBingbu Cao 	{ 0x9004, 0x09 },
1978a89dc62SBingbu Cao 	{ 0x9200, 0x6a },
1988a89dc62SBingbu Cao 	{ 0x9201, 0x22 },
1998a89dc62SBingbu Cao 	{ 0x9202, 0x6a },
2008a89dc62SBingbu Cao 	{ 0x9203, 0x23 },
2018a89dc62SBingbu Cao 	{ 0x9204, 0x5f },
2028a89dc62SBingbu Cao 	{ 0x9205, 0x23 },
2038a89dc62SBingbu Cao 	{ 0x9206, 0x5f },
2048a89dc62SBingbu Cao 	{ 0x9207, 0x24 },
2058a89dc62SBingbu Cao 	{ 0x9208, 0x5f },
2068a89dc62SBingbu Cao 	{ 0x9209, 0x26 },
2078a89dc62SBingbu Cao 	{ 0x920a, 0x5f },
2088a89dc62SBingbu Cao 	{ 0x920b, 0x27 },
2098a89dc62SBingbu Cao 	{ 0x920c, 0x5f },
2108a89dc62SBingbu Cao 	{ 0x920d, 0x29 },
2118a89dc62SBingbu Cao 	{ 0x920e, 0x5f },
2128a89dc62SBingbu Cao 	{ 0x920f, 0x2a },
2138a89dc62SBingbu Cao 	{ 0x9210, 0x5f },
2148a89dc62SBingbu Cao 	{ 0x9211, 0x2c },
2158a89dc62SBingbu Cao 	{ 0xbc22, 0x1a },
2168a89dc62SBingbu Cao 	{ 0xf01f, 0x04 },
2178a89dc62SBingbu Cao 	{ 0xf021, 0x03 },
2188a89dc62SBingbu Cao 	{ 0xf023, 0x02 },
2198a89dc62SBingbu Cao 	{ 0xf03d, 0x05 },
2208a89dc62SBingbu Cao 	{ 0xf03f, 0x03 },
2218a89dc62SBingbu Cao 	{ 0xf041, 0x02 },
2228a89dc62SBingbu Cao 	{ 0xf0af, 0x04 },
2238a89dc62SBingbu Cao 	{ 0xf0b1, 0x03 },
2248a89dc62SBingbu Cao 	{ 0xf0b3, 0x02 },
2258a89dc62SBingbu Cao 	{ 0xf0cd, 0x05 },
2268a89dc62SBingbu Cao 	{ 0xf0cf, 0x03 },
2278a89dc62SBingbu Cao 	{ 0xf0d1, 0x02 },
2288a89dc62SBingbu Cao 	{ 0xf13f, 0x04 },
2298a89dc62SBingbu Cao 	{ 0xf141, 0x03 },
2308a89dc62SBingbu Cao 	{ 0xf143, 0x02 },
2318a89dc62SBingbu Cao 	{ 0xf15d, 0x05 },
2328a89dc62SBingbu Cao 	{ 0xf15f, 0x03 },
2338a89dc62SBingbu Cao 	{ 0xf161, 0x02 },
2348a89dc62SBingbu Cao 	{ 0xf1cf, 0x04 },
2358a89dc62SBingbu Cao 	{ 0xf1d1, 0x03 },
2368a89dc62SBingbu Cao 	{ 0xf1d3, 0x02 },
2378a89dc62SBingbu Cao 	{ 0xf1ed, 0x05 },
2388a89dc62SBingbu Cao 	{ 0xf1ef, 0x03 },
2398a89dc62SBingbu Cao 	{ 0xf1f1, 0x02 },
2408a89dc62SBingbu Cao 	{ 0xf287, 0x04 },
2418a89dc62SBingbu Cao 	{ 0xf289, 0x03 },
2428a89dc62SBingbu Cao 	{ 0xf28b, 0x02 },
2438a89dc62SBingbu Cao 	{ 0xf2a5, 0x05 },
2448a89dc62SBingbu Cao 	{ 0xf2a7, 0x03 },
2458a89dc62SBingbu Cao 	{ 0xf2a9, 0x02 },
2468a89dc62SBingbu Cao 	{ 0xf2b7, 0x04 },
2478a89dc62SBingbu Cao 	{ 0xf2b9, 0x03 },
2488a89dc62SBingbu Cao 	{ 0xf2bb, 0x02 },
2498a89dc62SBingbu Cao 	{ 0xf2d5, 0x05 },
2508a89dc62SBingbu Cao 	{ 0xf2d7, 0x03 },
2518a89dc62SBingbu Cao 	{ 0xf2d9, 0x02 },
2528a89dc62SBingbu Cao };
2538a89dc62SBingbu Cao 
2548a89dc62SBingbu Cao static const struct imx319_reg_list imx319_global_setting = {
2558a89dc62SBingbu Cao 	.num_of_regs = ARRAY_SIZE(imx319_global_regs),
2568a89dc62SBingbu Cao 	.regs = imx319_global_regs,
2578a89dc62SBingbu Cao };
2588a89dc62SBingbu Cao 
2598a89dc62SBingbu Cao static const struct imx319_reg mode_3264x2448_regs[] = {
2608a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
2618a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
2628a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
2638a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
2648a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
2658a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
2668a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
2678a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
2688a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
2698a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
2708a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
2718a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
2728a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
2738a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
2748a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
2758a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
2768a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
2778a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
2788a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
2798a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
2808a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
2818a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
2828a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
2838a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
2848a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
2858a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
2868a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
2878a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
2888a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
2898a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
2908a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
2918a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
2928a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
2938a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
2948a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
2958a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
2968a89dc62SBingbu Cao 	{ 0x0409, 0x08 },
2978a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
2988a89dc62SBingbu Cao 	{ 0x040b, 0x08 },
2998a89dc62SBingbu Cao 	{ 0x040c, 0x0c },
3008a89dc62SBingbu Cao 	{ 0x040d, 0xc0 },
3018a89dc62SBingbu Cao 	{ 0x040e, 0x09 },
3028a89dc62SBingbu Cao 	{ 0x040f, 0x90 },
3038a89dc62SBingbu Cao 	{ 0x034c, 0x0c },
3048a89dc62SBingbu Cao 	{ 0x034d, 0xc0 },
3058a89dc62SBingbu Cao 	{ 0x034e, 0x09 },
3068a89dc62SBingbu Cao 	{ 0x034f, 0x90 },
3078a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
3088a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
3098a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
3108a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
3118a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
3128a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
3138a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
3148a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
3158a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
3168a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
3178a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
3188a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
3198a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
3208a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
3218a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
3228a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
3238a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
3248a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
3258a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
3268a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
3278a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
3288a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
3298a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
3308a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
3318a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
3328a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
3338a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
3348a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
3358a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
3368a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
3378a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
3388a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
3398a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
3408a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
3418a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
3428a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
3438a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
3448a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
3458a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
3468a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
3478a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
3488a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
3498a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
3508a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
3518a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
3528a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
3538a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
3548a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
3558a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
3568a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
3578a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
3588a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
3598a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
3608a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
3618a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
3628a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
3638a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
3648a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
3658a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
3668a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
3678a89dc62SBingbu Cao 	{ 0x0202, 0x0a },
3688a89dc62SBingbu Cao 	{ 0x0203, 0x7a },
3698a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
3708a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
3718a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
3728a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
3738a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
3748a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
3758a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
3768a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
3778a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
3788a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
3798a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
3808a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
3818a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
3828a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
3838a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
3848a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
3858a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
3868a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
3878a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
3888a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
3898a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
3908a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
3918a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
3928a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
3938a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
3948a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
3958a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
3968a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
3978a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
3988a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
3998a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
4008a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
4018a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
4028a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
4038a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
4048a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
4058a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
4068a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
4078a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
4088a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
4098a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
4108a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
4118a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
4128a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
4138a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
4148a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
4158a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
4168a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
4178a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
4188a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
4198a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
4208a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
4218a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
4228a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
4238a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
4248a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
4258a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
4268a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
4278a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
4288a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
4298a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
4308a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
4318a89dc62SBingbu Cao };
4328a89dc62SBingbu Cao 
4338a89dc62SBingbu Cao static const struct imx319_reg mode_3280x2464_regs[] = {
4348a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
4358a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
4368a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
4378a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
4388a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
4398a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
4408a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
4418a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
4428a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
4438a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
4448a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
4458a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
4468a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
4478a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
4488a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
4498a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
4508a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
4518a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
4528a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
4538a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
4548a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
4558a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
4568a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
4578a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
4588a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
4598a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
4608a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
4618a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
4628a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
4638a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
4648a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
4658a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
4668a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
4678a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
4688a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
4698a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
4708a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
4718a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
4728a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
4738a89dc62SBingbu Cao 	{ 0x040c, 0x0c },
4748a89dc62SBingbu Cao 	{ 0x040d, 0xd0 },
4758a89dc62SBingbu Cao 	{ 0x040e, 0x09 },
4768a89dc62SBingbu Cao 	{ 0x040f, 0xa0 },
4778a89dc62SBingbu Cao 	{ 0x034c, 0x0c },
4788a89dc62SBingbu Cao 	{ 0x034d, 0xd0 },
4798a89dc62SBingbu Cao 	{ 0x034e, 0x09 },
4808a89dc62SBingbu Cao 	{ 0x034f, 0xa0 },
4818a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
4828a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
4838a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
4848a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
4858a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
4868a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
4878a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
4888a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
4898a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
4908a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
4918a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
4928a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
4938a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
4948a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
4958a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
4968a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
4978a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
4988a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
4998a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
5008a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
5018a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
5028a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
5038a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
5048a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
5058a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
5068a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
5078a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
5088a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
5098a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
5108a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
5118a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
5128a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
5138a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
5148a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
5158a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
5168a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
5178a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
5188a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
5198a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
5208a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
5218a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
5228a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
5238a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
5248a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
5258a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
5268a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
5278a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
5288a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
5298a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
5308a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
5318a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
5328a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
5338a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
5348a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
5358a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
5368a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
5378a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
5388a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
5398a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
5408a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
5418a89dc62SBingbu Cao 	{ 0x0202, 0x0a },
5428a89dc62SBingbu Cao 	{ 0x0203, 0x7a },
5438a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
5448a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
5458a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
5468a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
5478a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
5488a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
5498a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
5508a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
5518a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
5528a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
5538a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
5548a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
5558a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
5568a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
5578a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
5588a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
5598a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
5608a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
5618a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
5628a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
5638a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
5648a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
5658a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
5668a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
5678a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
5688a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
5698a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
5708a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
5718a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
5728a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
5738a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
5748a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
5758a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
5768a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
5778a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
5788a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
5798a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
5808a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
5818a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
5828a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
5838a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
5848a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
5858a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
5868a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
5878a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
5888a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
5898a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
5908a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
5918a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
5928a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
5938a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
5948a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
5958a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
5968a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
5978a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
5988a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
5998a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
6008a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
6018a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
6028a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
6038a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
6048a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
6058a89dc62SBingbu Cao };
6068a89dc62SBingbu Cao 
6078a89dc62SBingbu Cao static const struct imx319_reg mode_1936x1096_regs[] = {
6088a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
6098a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
6108a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
6118a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
6128a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
6138a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
6148a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
6158a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
6168a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
6178a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
6188a89dc62SBingbu Cao 	{ 0x0347, 0xac },
6198a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
6208a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
6218a89dc62SBingbu Cao 	{ 0x034a, 0x06 },
6228a89dc62SBingbu Cao 	{ 0x034b, 0xf3 },
6238a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
6248a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
6258a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
6268a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
6278a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
6288a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
6298a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
6308a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
6318a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
6328a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
6338a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
6348a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
6358a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
6368a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
6378a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
6388a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
6398a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
6408a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
6418a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
6428a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
6438a89dc62SBingbu Cao 	{ 0x0408, 0x02 },
6448a89dc62SBingbu Cao 	{ 0x0409, 0xa0 },
6458a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
6468a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
6478a89dc62SBingbu Cao 	{ 0x040c, 0x07 },
6488a89dc62SBingbu Cao 	{ 0x040d, 0x90 },
6498a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
6508a89dc62SBingbu Cao 	{ 0x040f, 0x48 },
6518a89dc62SBingbu Cao 	{ 0x034c, 0x07 },
6528a89dc62SBingbu Cao 	{ 0x034d, 0x90 },
6538a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
6548a89dc62SBingbu Cao 	{ 0x034f, 0x48 },
6558a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
6568a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
6578a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
6588a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
6598a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
6608a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
6618a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
6628a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
6638a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
6648a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
6658a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
6668a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
6678a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
6688a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
6698a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
6708a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
6718a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
6728a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
6738a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
6748a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
6758a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
6768a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
6778a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
6788a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
6798a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
6808a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
6818a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
6828a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
6838a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
6848a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
6858a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
6868a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
6878a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
6888a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
6898a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
6908a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
6918a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
6928a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
6938a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
6948a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
6958a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
6968a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
6978a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
6988a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
6998a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
7008a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
7018a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
7028a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
7038a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
7048a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
7058a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
7068a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
7078a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
7088a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
7098a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
7108a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
7118a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
7128a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
7138a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
7148a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
7158a89dc62SBingbu Cao 	{ 0x0202, 0x05 },
7168a89dc62SBingbu Cao 	{ 0x0203, 0x34 },
7178a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
7188a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
7198a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
7208a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
7218a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
7228a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
7238a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
7248a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
7258a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
7268a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
7278a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
7288a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
7298a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
7308a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
7318a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
7328a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
7338a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
7348a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
7358a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
7368a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
7378a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
7388a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
7398a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
7408a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
7418a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
7428a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
7438a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
7448a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
7458a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
7468a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
7478a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
7488a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
7498a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
7508a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
7518a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
7528a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
7538a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
7548a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
7558a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
7568a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
7578a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
7588a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
7598a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
7608a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
7618a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
7628a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
7638a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
7648a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
7658a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
7668a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
7678a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
7688a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
7698a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
7708a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
7718a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
7728a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
7738a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
7748a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
7758a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
7768a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
7778a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
7788a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
7798a89dc62SBingbu Cao };
7808a89dc62SBingbu Cao 
7818a89dc62SBingbu Cao static const struct imx319_reg mode_1920x1080_regs[] = {
7828a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
7838a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
7848a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
7858a89dc62SBingbu Cao 	{ 0x0342, 0x0f },
7868a89dc62SBingbu Cao 	{ 0x0343, 0x80 },
7878a89dc62SBingbu Cao 	{ 0x0340, 0x0c },
7888a89dc62SBingbu Cao 	{ 0x0341, 0xaa },
7898a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
7908a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
7918a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
7928a89dc62SBingbu Cao 	{ 0x0347, 0xb4 },
7938a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
7948a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
7958a89dc62SBingbu Cao 	{ 0x034a, 0x06 },
7968a89dc62SBingbu Cao 	{ 0x034b, 0xeb },
7978a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
7988a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
7998a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
8008a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
8018a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
8028a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
8038a89dc62SBingbu Cao 	{ 0x0900, 0x00 },
8048a89dc62SBingbu Cao 	{ 0x0901, 0x11 },
8058a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
8068a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
8078a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
8088a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
8098a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
8108a89dc62SBingbu Cao 	{ 0x3f3c, 0x01 },
8118a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
8128a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
8138a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
8148a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
8158a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
8168a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
8178a89dc62SBingbu Cao 	{ 0x0408, 0x02 },
8188a89dc62SBingbu Cao 	{ 0x0409, 0xa8 },
8198a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
8208a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
8218a89dc62SBingbu Cao 	{ 0x040c, 0x07 },
8228a89dc62SBingbu Cao 	{ 0x040d, 0x80 },
8238a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
8248a89dc62SBingbu Cao 	{ 0x040f, 0x38 },
8258a89dc62SBingbu Cao 	{ 0x034c, 0x07 },
8268a89dc62SBingbu Cao 	{ 0x034d, 0x80 },
8278a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
8288a89dc62SBingbu Cao 	{ 0x034f, 0x38 },
8298a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
8308a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
8318a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
8328a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
8338a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
8348a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
8358a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
8368a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
8378a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
8388a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
8398a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
8408a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
8418a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
8428a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
8438a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
8448a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
8458a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
8468a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
8478a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
8488a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
8498a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
8508a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
8518a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
8528a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
8538a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
8548a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
8558a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
8568a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
8578a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
8588a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
8598a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
8608a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
8618a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
8628a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
8638a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
8648a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
8658a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
8668a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
8678a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
8688a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
8698a89dc62SBingbu Cao 	{ 0x3c01, 0x48 },
8708a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
8718a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
8728a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
8738a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
8748a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
8758a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
8768a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
8778a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
8788a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
8798a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
8808a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
8818a89dc62SBingbu Cao 	{ 0x3f78, 0x01 },
8828a89dc62SBingbu Cao 	{ 0x3f79, 0x18 },
8838a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
8848a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
8858a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
8868a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
8878a89dc62SBingbu Cao 	{ 0xa081, 0x00 },
8888a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
8898a89dc62SBingbu Cao 	{ 0x0202, 0x05 },
8908a89dc62SBingbu Cao 	{ 0x0203, 0x34 },
8918a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
8928a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
8938a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
8948a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
8958a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
8968a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
8978a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
8988a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
8998a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
9008a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
9018a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
9028a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
9038a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
9048a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
9058a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
9068a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
9078a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
9088a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
9098a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
9108a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
9118a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
9128a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
9138a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
9148a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
9158a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
9168a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
9178a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
9188a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
9198a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
9208a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
9218a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
9228a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
9238a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
9248a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
9258a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
9268a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
9278a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
9288a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
9298a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
9308a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
9318a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
9328a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
9338a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
9348a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
9358a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
9368a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
9378a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
9388a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
9398a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
9408a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
9418a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
9428a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
9438a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
9448a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
9458a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
9468a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
9478a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
9488a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
9498a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
9508a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
9518a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
9528a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
9538a89dc62SBingbu Cao };
9548a89dc62SBingbu Cao 
9558a89dc62SBingbu Cao static const struct imx319_reg mode_1640x1232_regs[] = {
9568a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
9578a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
9588a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
9598a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
9608a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
9618a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
9628a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
9638a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
9648a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
9658a89dc62SBingbu Cao 	{ 0x0346, 0x00 },
9668a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
9678a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
9688a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
9698a89dc62SBingbu Cao 	{ 0x034a, 0x09 },
9708a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
9718a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
9728a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
9738a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
9748a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
9758a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
9768a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
9778a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
9788a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
9798a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
9808a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
9818a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
9828a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
9838a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
9848a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
9858a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
9868a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
9878a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
9888a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
9898a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
9908a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
9918a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
9928a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
9938a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
9948a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
9958a89dc62SBingbu Cao 	{ 0x040c, 0x06 },
9968a89dc62SBingbu Cao 	{ 0x040d, 0x68 },
9978a89dc62SBingbu Cao 	{ 0x040e, 0x04 },
9988a89dc62SBingbu Cao 	{ 0x040f, 0xd0 },
9998a89dc62SBingbu Cao 	{ 0x034c, 0x06 },
10008a89dc62SBingbu Cao 	{ 0x034d, 0x68 },
10018a89dc62SBingbu Cao 	{ 0x034e, 0x04 },
10028a89dc62SBingbu Cao 	{ 0x034f, 0xd0 },
10038a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
10048a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
10058a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
10068a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
10078a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
10088a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
10098a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
10108a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
10118a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
10128a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
10138a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
10148a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
10158a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
10168a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
10178a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
10188a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
10198a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
10208a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
10218a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
10228a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
10238a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
10248a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
10258a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
10268a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
10278a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
10288a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
10298a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
10308a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
10318a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
10328a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
10338a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
10348a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
10358a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
10368a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
10378a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
10388a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
10398a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
10408a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
10418a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
10428a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
10438a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
10448a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
10458a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
10468a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
10478a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
10488a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
10498a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
10508a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
10518a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
10528a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
10538a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
10548a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
10558a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
10568a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
10578a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
10588a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
10598a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
10608a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
10618a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
10628a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
10638a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
10648a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
10658a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
10668a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
10678a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
10688a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
10698a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
10708a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
10718a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
10728a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
10738a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
10748a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
10758a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
10768a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
10778a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
10788a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
10798a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
10808a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
10818a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
10828a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
10838a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
10848a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
10858a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
10868a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
10878a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
10888a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
10898a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
10908a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
10918a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
10928a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
10938a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
10948a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
10958a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
10968a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
10978a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
10988a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
10998a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
11008a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
11018a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
11028a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
11038a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
11048a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
11058a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
11068a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
11078a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
11088a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
11098a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
11108a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
11118a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
11128a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
11138a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
11148a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
11158a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
11168a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
11178a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
11188a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
11198a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
11208a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
11218a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
11228a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
11238a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
11248a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
11258a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
11268a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
11278a89dc62SBingbu Cao };
11288a89dc62SBingbu Cao 
11298a89dc62SBingbu Cao static const struct imx319_reg mode_1640x922_regs[] = {
11308a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
11318a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
11328a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
11338a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
11348a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
11358a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
11368a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
11378a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
11388a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
11398a89dc62SBingbu Cao 	{ 0x0346, 0x01 },
11408a89dc62SBingbu Cao 	{ 0x0347, 0x30 },
11418a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
11428a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
11438a89dc62SBingbu Cao 	{ 0x034a, 0x08 },
11448a89dc62SBingbu Cao 	{ 0x034b, 0x6f },
11458a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
11468a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
11478a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
11488a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
11498a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
11508a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
11518a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
11528a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
11538a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
11548a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
11558a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
11568a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
11578a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
11588a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
11598a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
11608a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
11618a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
11628a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
11638a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
11648a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
11658a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
11668a89dc62SBingbu Cao 	{ 0x0409, 0x00 },
11678a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
11688a89dc62SBingbu Cao 	{ 0x040b, 0x02 },
11698a89dc62SBingbu Cao 	{ 0x040c, 0x06 },
11708a89dc62SBingbu Cao 	{ 0x040d, 0x68 },
11718a89dc62SBingbu Cao 	{ 0x040e, 0x03 },
11728a89dc62SBingbu Cao 	{ 0x040f, 0x9a },
11738a89dc62SBingbu Cao 	{ 0x034c, 0x06 },
11748a89dc62SBingbu Cao 	{ 0x034d, 0x68 },
11758a89dc62SBingbu Cao 	{ 0x034e, 0x03 },
11768a89dc62SBingbu Cao 	{ 0x034f, 0x9a },
11778a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
11788a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
11798a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
11808a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
11818a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
11828a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
11838a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
11848a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
11858a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
11868a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
11878a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
11888a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
11898a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
11908a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
11918a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
11928a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
11938a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
11948a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
11958a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
11968a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
11978a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
11988a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
11998a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
12008a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
12018a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
12028a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
12038a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
12048a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
12058a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
12068a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
12078a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
12088a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
12098a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
12108a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
12118a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
12128a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
12138a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
12148a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
12158a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
12168a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
12178a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
12188a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
12198a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
12208a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
12218a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
12228a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
12238a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
12248a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
12258a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
12268a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
12278a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
12288a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
12298a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
12308a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
12318a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
12328a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
12338a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
12348a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
12358a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
12368a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
12378a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
12388a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
12398a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
12408a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
12418a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
12428a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
12438a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
12448a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
12458a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
12468a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
12478a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
12488a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
12498a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
12508a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
12518a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
12528a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
12538a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
12548a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
12558a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
12568a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
12578a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
12588a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
12598a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
12608a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
12618a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
12628a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
12638a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
12648a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
12658a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
12668a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
12678a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
12688a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
12698a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
12708a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
12718a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
12728a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
12738a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
12748a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
12758a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
12768a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
12778a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
12788a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
12798a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
12808a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
12818a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
12828a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
12838a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
12848a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
12858a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
12868a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
12878a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
12888a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
12898a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
12908a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
12918a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
12928a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
12938a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
12948a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
12958a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
12968a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
12978a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
12988a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
12998a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
13008a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
13018a89dc62SBingbu Cao };
13028a89dc62SBingbu Cao 
13038a89dc62SBingbu Cao static const struct imx319_reg mode_1296x736_regs[] = {
13048a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
13058a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
13068a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
13078a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
13088a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
13098a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
13108a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
13118a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
13128a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
13138a89dc62SBingbu Cao 	{ 0x0346, 0x01 },
13148a89dc62SBingbu Cao 	{ 0x0347, 0xf0 },
13158a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
13168a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
13178a89dc62SBingbu Cao 	{ 0x034a, 0x07 },
13188a89dc62SBingbu Cao 	{ 0x034b, 0xaf },
13198a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
13208a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
13218a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
13228a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
13238a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
13248a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
13258a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
13268a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
13278a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
13288a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
13298a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
13308a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
13318a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
13328a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
13338a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
13348a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
13358a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
13368a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
13378a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
13388a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
13398a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
13408a89dc62SBingbu Cao 	{ 0x0409, 0xac },
13418a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
13428a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
13438a89dc62SBingbu Cao 	{ 0x040c, 0x05 },
13448a89dc62SBingbu Cao 	{ 0x040d, 0x10 },
13458a89dc62SBingbu Cao 	{ 0x040e, 0x02 },
13468a89dc62SBingbu Cao 	{ 0x040f, 0xe0 },
13478a89dc62SBingbu Cao 	{ 0x034c, 0x05 },
13488a89dc62SBingbu Cao 	{ 0x034d, 0x10 },
13498a89dc62SBingbu Cao 	{ 0x034e, 0x02 },
13508a89dc62SBingbu Cao 	{ 0x034f, 0xe0 },
13518a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
13528a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
13538a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
13548a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
13558a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
13568a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
13578a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
13588a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
13598a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
13608a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
13618a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
13628a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
13638a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
13648a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
13658a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
13668a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
13678a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
13688a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
13698a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
13708a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
13718a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
13728a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
13738a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
13748a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
13758a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
13768a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
13778a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
13788a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
13798a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
13808a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
13818a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
13828a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
13838a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
13848a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
13858a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
13868a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
13878a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
13888a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
13898a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
13908a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
13918a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
13928a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
13938a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
13948a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
13958a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
13968a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
13978a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
13988a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
13998a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
14008a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
14018a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
14028a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
14038a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
14048a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
14058a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
14068a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
14078a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
14088a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
14098a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
14108a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
14118a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
14128a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
14138a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
14148a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
14158a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
14168a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
14178a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
14188a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
14198a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
14208a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
14218a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
14228a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
14238a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
14248a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
14258a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
14268a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
14278a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
14288a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
14298a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
14308a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
14318a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
14328a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
14338a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
14348a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
14358a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
14368a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
14378a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
14388a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
14398a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
14408a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
14418a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
14428a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
14438a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
14448a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
14458a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
14468a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
14478a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
14488a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
14498a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
14508a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
14518a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
14528a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
14538a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
14548a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
14558a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
14568a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
14578a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
14588a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
14598a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
14608a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
14618a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
14628a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
14638a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
14648a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
14658a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
14668a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
14678a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
14688a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
14698a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
14708a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
14718a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
14728a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
14738a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
14748a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
14758a89dc62SBingbu Cao };
14768a89dc62SBingbu Cao 
14778a89dc62SBingbu Cao static const struct imx319_reg mode_1280x720_regs[] = {
14788a89dc62SBingbu Cao 	{ 0x0112, 0x0a },
14798a89dc62SBingbu Cao 	{ 0x0113, 0x0a },
14808a89dc62SBingbu Cao 	{ 0x0114, 0x03 },
14818a89dc62SBingbu Cao 	{ 0x0342, 0x08 },
14828a89dc62SBingbu Cao 	{ 0x0343, 0x20 },
14838a89dc62SBingbu Cao 	{ 0x0340, 0x18 },
14848a89dc62SBingbu Cao 	{ 0x0341, 0x2a },
14858a89dc62SBingbu Cao 	{ 0x0344, 0x00 },
14868a89dc62SBingbu Cao 	{ 0x0345, 0x00 },
14878a89dc62SBingbu Cao 	{ 0x0346, 0x02 },
14888a89dc62SBingbu Cao 	{ 0x0347, 0x00 },
14898a89dc62SBingbu Cao 	{ 0x0348, 0x0c },
14908a89dc62SBingbu Cao 	{ 0x0349, 0xcf },
14918a89dc62SBingbu Cao 	{ 0x034a, 0x07 },
14928a89dc62SBingbu Cao 	{ 0x034b, 0x9f },
14938a89dc62SBingbu Cao 	{ 0x0220, 0x00 },
14948a89dc62SBingbu Cao 	{ 0x0221, 0x11 },
14958a89dc62SBingbu Cao 	{ 0x0381, 0x01 },
14968a89dc62SBingbu Cao 	{ 0x0383, 0x01 },
14978a89dc62SBingbu Cao 	{ 0x0385, 0x01 },
14988a89dc62SBingbu Cao 	{ 0x0387, 0x01 },
14998a89dc62SBingbu Cao 	{ 0x0900, 0x01 },
15008a89dc62SBingbu Cao 	{ 0x0901, 0x22 },
15018a89dc62SBingbu Cao 	{ 0x0902, 0x0a },
15028a89dc62SBingbu Cao 	{ 0x3140, 0x02 },
15038a89dc62SBingbu Cao 	{ 0x3141, 0x00 },
15048a89dc62SBingbu Cao 	{ 0x3f0d, 0x0a },
15058a89dc62SBingbu Cao 	{ 0x3f14, 0x01 },
15068a89dc62SBingbu Cao 	{ 0x3f3c, 0x02 },
15078a89dc62SBingbu Cao 	{ 0x3f4d, 0x01 },
15088a89dc62SBingbu Cao 	{ 0x3f4c, 0x01 },
15098a89dc62SBingbu Cao 	{ 0x4254, 0x7f },
15108a89dc62SBingbu Cao 	{ 0x0401, 0x00 },
15118a89dc62SBingbu Cao 	{ 0x0404, 0x00 },
15128a89dc62SBingbu Cao 	{ 0x0405, 0x10 },
15138a89dc62SBingbu Cao 	{ 0x0408, 0x00 },
15148a89dc62SBingbu Cao 	{ 0x0409, 0xb4 },
15158a89dc62SBingbu Cao 	{ 0x040a, 0x00 },
15168a89dc62SBingbu Cao 	{ 0x040b, 0x00 },
15178a89dc62SBingbu Cao 	{ 0x040c, 0x05 },
15188a89dc62SBingbu Cao 	{ 0x040d, 0x00 },
15198a89dc62SBingbu Cao 	{ 0x040e, 0x02 },
15208a89dc62SBingbu Cao 	{ 0x040f, 0xd0 },
15218a89dc62SBingbu Cao 	{ 0x034c, 0x05 },
15228a89dc62SBingbu Cao 	{ 0x034d, 0x00 },
15238a89dc62SBingbu Cao 	{ 0x034e, 0x02 },
15248a89dc62SBingbu Cao 	{ 0x034f, 0xd0 },
15258a89dc62SBingbu Cao 	{ 0x3261, 0x00 },
15268a89dc62SBingbu Cao 	{ 0x3264, 0x00 },
15278a89dc62SBingbu Cao 	{ 0x3265, 0x10 },
15288a89dc62SBingbu Cao 	{ 0x0301, 0x05 },
15298a89dc62SBingbu Cao 	{ 0x0303, 0x04 },
15308a89dc62SBingbu Cao 	{ 0x0305, 0x04 },
15318a89dc62SBingbu Cao 	{ 0x0306, 0x01 },
15328a89dc62SBingbu Cao 	{ 0x0307, 0x92 },
15338a89dc62SBingbu Cao 	{ 0x0309, 0x0a },
15348a89dc62SBingbu Cao 	{ 0x030b, 0x02 },
15358a89dc62SBingbu Cao 	{ 0x030d, 0x02 },
15368a89dc62SBingbu Cao 	{ 0x030e, 0x00 },
15378a89dc62SBingbu Cao 	{ 0x030f, 0xfa },
15388a89dc62SBingbu Cao 	{ 0x0310, 0x00 },
15398a89dc62SBingbu Cao 	{ 0x0820, 0x0f },
15408a89dc62SBingbu Cao 	{ 0x0821, 0x13 },
15418a89dc62SBingbu Cao 	{ 0x0822, 0x33 },
15428a89dc62SBingbu Cao 	{ 0x0823, 0x33 },
15438a89dc62SBingbu Cao 	{ 0x3e20, 0x01 },
15448a89dc62SBingbu Cao 	{ 0x3e37, 0x00 },
15458a89dc62SBingbu Cao 	{ 0x3e3b, 0x01 },
15468a89dc62SBingbu Cao 	{ 0x38a3, 0x01 },
15478a89dc62SBingbu Cao 	{ 0x38a8, 0x00 },
15488a89dc62SBingbu Cao 	{ 0x38a9, 0x00 },
15498a89dc62SBingbu Cao 	{ 0x38aa, 0x00 },
15508a89dc62SBingbu Cao 	{ 0x38ab, 0x00 },
15518a89dc62SBingbu Cao 	{ 0x3234, 0x00 },
15528a89dc62SBingbu Cao 	{ 0x3fc1, 0x00 },
15538a89dc62SBingbu Cao 	{ 0x3235, 0x00 },
15548a89dc62SBingbu Cao 	{ 0x3802, 0x00 },
15558a89dc62SBingbu Cao 	{ 0x3143, 0x04 },
15568a89dc62SBingbu Cao 	{ 0x360a, 0x00 },
15578a89dc62SBingbu Cao 	{ 0x0b00, 0x00 },
15588a89dc62SBingbu Cao 	{ 0x0106, 0x00 },
15598a89dc62SBingbu Cao 	{ 0x0b05, 0x01 },
15608a89dc62SBingbu Cao 	{ 0x0b06, 0x01 },
15618a89dc62SBingbu Cao 	{ 0x3230, 0x00 },
15628a89dc62SBingbu Cao 	{ 0x3602, 0x01 },
15638a89dc62SBingbu Cao 	{ 0x3607, 0x01 },
15648a89dc62SBingbu Cao 	{ 0x3c00, 0x00 },
15658a89dc62SBingbu Cao 	{ 0x3c01, 0xba },
15668a89dc62SBingbu Cao 	{ 0x3c02, 0xc8 },
15678a89dc62SBingbu Cao 	{ 0x3c03, 0xaa },
15688a89dc62SBingbu Cao 	{ 0x3c04, 0x91 },
15698a89dc62SBingbu Cao 	{ 0x3c05, 0x54 },
15708a89dc62SBingbu Cao 	{ 0x3c06, 0x26 },
15718a89dc62SBingbu Cao 	{ 0x3c07, 0x20 },
15728a89dc62SBingbu Cao 	{ 0x3c08, 0x51 },
15738a89dc62SBingbu Cao 	{ 0x3d80, 0x00 },
15748a89dc62SBingbu Cao 	{ 0x3f50, 0x00 },
15758a89dc62SBingbu Cao 	{ 0x3f56, 0x00 },
15768a89dc62SBingbu Cao 	{ 0x3f57, 0x30 },
15778a89dc62SBingbu Cao 	{ 0x3f78, 0x00 },
15788a89dc62SBingbu Cao 	{ 0x3f79, 0x34 },
15798a89dc62SBingbu Cao 	{ 0x3f7c, 0x00 },
15808a89dc62SBingbu Cao 	{ 0x3f7d, 0x00 },
15818a89dc62SBingbu Cao 	{ 0x3fba, 0x00 },
15828a89dc62SBingbu Cao 	{ 0x3fbb, 0x00 },
15838a89dc62SBingbu Cao 	{ 0xa081, 0x04 },
15848a89dc62SBingbu Cao 	{ 0xe014, 0x00 },
15858a89dc62SBingbu Cao 	{ 0x0202, 0x04 },
15868a89dc62SBingbu Cao 	{ 0x0203, 0xf6 },
15878a89dc62SBingbu Cao 	{ 0x0224, 0x01 },
15888a89dc62SBingbu Cao 	{ 0x0225, 0xf4 },
15898a89dc62SBingbu Cao 	{ 0x0204, 0x00 },
15908a89dc62SBingbu Cao 	{ 0x0205, 0x00 },
15918a89dc62SBingbu Cao 	{ 0x0216, 0x00 },
15928a89dc62SBingbu Cao 	{ 0x0217, 0x00 },
15938a89dc62SBingbu Cao 	{ 0x020e, 0x01 },
15948a89dc62SBingbu Cao 	{ 0x020f, 0x00 },
15958a89dc62SBingbu Cao 	{ 0x0210, 0x01 },
15968a89dc62SBingbu Cao 	{ 0x0211, 0x00 },
15978a89dc62SBingbu Cao 	{ 0x0212, 0x01 },
15988a89dc62SBingbu Cao 	{ 0x0213, 0x00 },
15998a89dc62SBingbu Cao 	{ 0x0214, 0x01 },
16008a89dc62SBingbu Cao 	{ 0x0215, 0x00 },
16018a89dc62SBingbu Cao 	{ 0x0218, 0x01 },
16028a89dc62SBingbu Cao 	{ 0x0219, 0x00 },
16038a89dc62SBingbu Cao 	{ 0x3614, 0x00 },
16048a89dc62SBingbu Cao 	{ 0x3616, 0x0d },
16058a89dc62SBingbu Cao 	{ 0x3617, 0x56 },
16068a89dc62SBingbu Cao 	{ 0xb612, 0x20 },
16078a89dc62SBingbu Cao 	{ 0xb613, 0x20 },
16088a89dc62SBingbu Cao 	{ 0xb614, 0x20 },
16098a89dc62SBingbu Cao 	{ 0xb615, 0x20 },
16108a89dc62SBingbu Cao 	{ 0xb616, 0x0a },
16118a89dc62SBingbu Cao 	{ 0xb617, 0x0a },
16128a89dc62SBingbu Cao 	{ 0xb618, 0x20 },
16138a89dc62SBingbu Cao 	{ 0xb619, 0x20 },
16148a89dc62SBingbu Cao 	{ 0xb61a, 0x20 },
16158a89dc62SBingbu Cao 	{ 0xb61b, 0x20 },
16168a89dc62SBingbu Cao 	{ 0xb61c, 0x0a },
16178a89dc62SBingbu Cao 	{ 0xb61d, 0x0a },
16188a89dc62SBingbu Cao 	{ 0xb666, 0x30 },
16198a89dc62SBingbu Cao 	{ 0xb667, 0x30 },
16208a89dc62SBingbu Cao 	{ 0xb668, 0x30 },
16218a89dc62SBingbu Cao 	{ 0xb669, 0x30 },
16228a89dc62SBingbu Cao 	{ 0xb66a, 0x14 },
16238a89dc62SBingbu Cao 	{ 0xb66b, 0x14 },
16248a89dc62SBingbu Cao 	{ 0xb66c, 0x20 },
16258a89dc62SBingbu Cao 	{ 0xb66d, 0x20 },
16268a89dc62SBingbu Cao 	{ 0xb66e, 0x20 },
16278a89dc62SBingbu Cao 	{ 0xb66f, 0x20 },
16288a89dc62SBingbu Cao 	{ 0xb670, 0x10 },
16298a89dc62SBingbu Cao 	{ 0xb671, 0x10 },
16308a89dc62SBingbu Cao 	{ 0x3237, 0x00 },
16318a89dc62SBingbu Cao 	{ 0x3900, 0x00 },
16328a89dc62SBingbu Cao 	{ 0x3901, 0x00 },
16338a89dc62SBingbu Cao 	{ 0x3902, 0x00 },
16348a89dc62SBingbu Cao 	{ 0x3904, 0x00 },
16358a89dc62SBingbu Cao 	{ 0x3905, 0x00 },
16368a89dc62SBingbu Cao 	{ 0x3906, 0x00 },
16378a89dc62SBingbu Cao 	{ 0x3907, 0x00 },
16388a89dc62SBingbu Cao 	{ 0x3908, 0x00 },
16398a89dc62SBingbu Cao 	{ 0x3909, 0x00 },
16408a89dc62SBingbu Cao 	{ 0x3912, 0x00 },
16418a89dc62SBingbu Cao 	{ 0x3930, 0x00 },
16428a89dc62SBingbu Cao 	{ 0x3931, 0x00 },
16438a89dc62SBingbu Cao 	{ 0x3933, 0x00 },
16448a89dc62SBingbu Cao 	{ 0x3934, 0x00 },
16458a89dc62SBingbu Cao 	{ 0x3935, 0x00 },
16468a89dc62SBingbu Cao 	{ 0x3936, 0x00 },
16478a89dc62SBingbu Cao 	{ 0x3937, 0x00 },
16488a89dc62SBingbu Cao 	{ 0x30ac, 0x00 },
16498a89dc62SBingbu Cao };
16508a89dc62SBingbu Cao 
16518a89dc62SBingbu Cao static const char * const imx319_test_pattern_menu[] = {
16528a89dc62SBingbu Cao 	"Disabled",
1653ce6ebeacSBingbu Cao 	"Solid Colour",
1654ce6ebeacSBingbu Cao 	"Eight Vertical Colour Bars",
1655ce6ebeacSBingbu Cao 	"Colour Bars With Fade to Grey",
1656ce6ebeacSBingbu Cao 	"Pseudorandom Sequence (PN9)",
16578a89dc62SBingbu Cao };
16588a89dc62SBingbu Cao 
16598a89dc62SBingbu Cao /* supported link frequencies */
16608a89dc62SBingbu Cao static const s64 link_freq_menu_items[] = {
16618a89dc62SBingbu Cao 	IMX319_LINK_FREQ_DEFAULT,
16628a89dc62SBingbu Cao };
16638a89dc62SBingbu Cao 
16648a89dc62SBingbu Cao /* Mode configs */
16658a89dc62SBingbu Cao static const struct imx319_mode supported_modes[] = {
16668a89dc62SBingbu Cao 	{
16678a89dc62SBingbu Cao 		.width = 3280,
16688a89dc62SBingbu Cao 		.height = 2464,
16698a89dc62SBingbu Cao 		.fll_def = 3242,
16708a89dc62SBingbu Cao 		.fll_min = 3242,
16718a89dc62SBingbu Cao 		.llp = 3968,
16728a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
16738a89dc62SBingbu Cao 		.reg_list = {
16748a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
16758a89dc62SBingbu Cao 			.regs = mode_3280x2464_regs,
16768a89dc62SBingbu Cao 		},
16778a89dc62SBingbu Cao 	},
16788a89dc62SBingbu Cao 	{
16798a89dc62SBingbu Cao 		.width = 3264,
16808a89dc62SBingbu Cao 		.height = 2448,
16818a89dc62SBingbu Cao 		.fll_def = 3242,
16828a89dc62SBingbu Cao 		.fll_min = 3242,
16838a89dc62SBingbu Cao 		.llp = 3968,
16848a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
16858a89dc62SBingbu Cao 		.reg_list = {
16868a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
16878a89dc62SBingbu Cao 			.regs = mode_3264x2448_regs,
16888a89dc62SBingbu Cao 		},
16898a89dc62SBingbu Cao 	},
16908a89dc62SBingbu Cao 	{
16918a89dc62SBingbu Cao 		.width = 1936,
16928a89dc62SBingbu Cao 		.height = 1096,
16938a89dc62SBingbu Cao 		.fll_def = 3242,
16948a89dc62SBingbu Cao 		.fll_min = 3242,
16958a89dc62SBingbu Cao 		.llp = 3968,
16968a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
16978a89dc62SBingbu Cao 		.reg_list = {
16988a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
16998a89dc62SBingbu Cao 			.regs = mode_1936x1096_regs,
17008a89dc62SBingbu Cao 		},
17018a89dc62SBingbu Cao 	},
17028a89dc62SBingbu Cao 	{
17038a89dc62SBingbu Cao 		.width = 1920,
17048a89dc62SBingbu Cao 		.height = 1080,
17058a89dc62SBingbu Cao 		.fll_def = 3242,
17068a89dc62SBingbu Cao 		.fll_min = 3242,
17078a89dc62SBingbu Cao 		.llp = 3968,
17088a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
17098a89dc62SBingbu Cao 		.reg_list = {
17108a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
17118a89dc62SBingbu Cao 			.regs = mode_1920x1080_regs,
17128a89dc62SBingbu Cao 		},
17138a89dc62SBingbu Cao 	},
17148a89dc62SBingbu Cao 	{
17158a89dc62SBingbu Cao 		.width = 1640,
17168a89dc62SBingbu Cao 		.height = 1232,
17178a89dc62SBingbu Cao 		.fll_def = 5146,
17188a89dc62SBingbu Cao 		.fll_min = 5146,
17198a89dc62SBingbu Cao 		.llp = 2500,
17208a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
17218a89dc62SBingbu Cao 		.reg_list = {
17228a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
17238a89dc62SBingbu Cao 			.regs = mode_1640x1232_regs,
17248a89dc62SBingbu Cao 		},
17258a89dc62SBingbu Cao 	},
17268a89dc62SBingbu Cao 	{
17278a89dc62SBingbu Cao 		.width = 1640,
17288a89dc62SBingbu Cao 		.height = 922,
17298a89dc62SBingbu Cao 		.fll_def = 5146,
17308a89dc62SBingbu Cao 		.fll_min = 5146,
17318a89dc62SBingbu Cao 		.llp = 2500,
17328a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
17338a89dc62SBingbu Cao 		.reg_list = {
17348a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
17358a89dc62SBingbu Cao 			.regs = mode_1640x922_regs,
17368a89dc62SBingbu Cao 		},
17378a89dc62SBingbu Cao 	},
17388a89dc62SBingbu Cao 	{
17398a89dc62SBingbu Cao 		.width = 1296,
17408a89dc62SBingbu Cao 		.height = 736,
17418a89dc62SBingbu Cao 		.fll_def = 5146,
17428a89dc62SBingbu Cao 		.fll_min = 5146,
17438a89dc62SBingbu Cao 		.llp = 2500,
17448a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
17458a89dc62SBingbu Cao 		.reg_list = {
17468a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
17478a89dc62SBingbu Cao 			.regs = mode_1296x736_regs,
17488a89dc62SBingbu Cao 		},
17498a89dc62SBingbu Cao 	},
17508a89dc62SBingbu Cao 	{
17518a89dc62SBingbu Cao 		.width = 1280,
17528a89dc62SBingbu Cao 		.height = 720,
17538a89dc62SBingbu Cao 		.fll_def = 5146,
17548a89dc62SBingbu Cao 		.fll_min = 5146,
17558a89dc62SBingbu Cao 		.llp = 2500,
17568a89dc62SBingbu Cao 		.link_freq_index = IMX319_LINK_FREQ_INDEX,
17578a89dc62SBingbu Cao 		.reg_list = {
17588a89dc62SBingbu Cao 			.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
17598a89dc62SBingbu Cao 			.regs = mode_1280x720_regs,
17608a89dc62SBingbu Cao 		},
17618a89dc62SBingbu Cao 	},
17628a89dc62SBingbu Cao };
17638a89dc62SBingbu Cao 
to_imx319(struct v4l2_subdev * _sd)17648a89dc62SBingbu Cao static inline struct imx319 *to_imx319(struct v4l2_subdev *_sd)
17658a89dc62SBingbu Cao {
17668a89dc62SBingbu Cao 	return container_of(_sd, struct imx319, sd);
17678a89dc62SBingbu Cao }
17688a89dc62SBingbu Cao 
17698a89dc62SBingbu Cao /* Get bayer order based on flip setting. */
imx319_get_format_code(struct imx319 * imx319)17708a89dc62SBingbu Cao static u32 imx319_get_format_code(struct imx319 *imx319)
17718a89dc62SBingbu Cao {
17728a89dc62SBingbu Cao 	/*
17738a89dc62SBingbu Cao 	 * Only one bayer order is supported.
17748a89dc62SBingbu Cao 	 * It depends on the flip settings.
17758a89dc62SBingbu Cao 	 */
17768a89dc62SBingbu Cao 	u32 code;
17778a89dc62SBingbu Cao 	static const u32 codes[2][2] = {
17788a89dc62SBingbu Cao 		{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
17798a89dc62SBingbu Cao 		{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
17808a89dc62SBingbu Cao 	};
17818a89dc62SBingbu Cao 
17828a89dc62SBingbu Cao 	lockdep_assert_held(&imx319->mutex);
17838a89dc62SBingbu Cao 	code = codes[imx319->vflip->val][imx319->hflip->val];
17848a89dc62SBingbu Cao 
17858a89dc62SBingbu Cao 	return code;
17868a89dc62SBingbu Cao }
17878a89dc62SBingbu Cao 
17888a89dc62SBingbu Cao /* Read registers up to 4 at a time */
imx319_read_reg(struct imx319 * imx319,u16 reg,u32 len,u32 * val)17898a89dc62SBingbu Cao static int imx319_read_reg(struct imx319 *imx319, u16 reg, u32 len, u32 *val)
17908a89dc62SBingbu Cao {
17918a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
17928a89dc62SBingbu Cao 	struct i2c_msg msgs[2];
17938a89dc62SBingbu Cao 	u8 addr_buf[2];
17948a89dc62SBingbu Cao 	u8 data_buf[4] = { 0 };
17958a89dc62SBingbu Cao 	int ret;
17968a89dc62SBingbu Cao 
17978a89dc62SBingbu Cao 	if (len > 4)
17988a89dc62SBingbu Cao 		return -EINVAL;
17998a89dc62SBingbu Cao 
18008a89dc62SBingbu Cao 	put_unaligned_be16(reg, addr_buf);
18018a89dc62SBingbu Cao 	/* Write register address */
18028a89dc62SBingbu Cao 	msgs[0].addr = client->addr;
18038a89dc62SBingbu Cao 	msgs[0].flags = 0;
18048a89dc62SBingbu Cao 	msgs[0].len = ARRAY_SIZE(addr_buf);
18058a89dc62SBingbu Cao 	msgs[0].buf = addr_buf;
18068a89dc62SBingbu Cao 
18078a89dc62SBingbu Cao 	/* Read data from register */
18088a89dc62SBingbu Cao 	msgs[1].addr = client->addr;
18098a89dc62SBingbu Cao 	msgs[1].flags = I2C_M_RD;
18108a89dc62SBingbu Cao 	msgs[1].len = len;
18118a89dc62SBingbu Cao 	msgs[1].buf = &data_buf[4 - len];
18128a89dc62SBingbu Cao 
18138a89dc62SBingbu Cao 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
18148a89dc62SBingbu Cao 	if (ret != ARRAY_SIZE(msgs))
18158a89dc62SBingbu Cao 		return -EIO;
18168a89dc62SBingbu Cao 
18178a89dc62SBingbu Cao 	*val = get_unaligned_be32(data_buf);
18188a89dc62SBingbu Cao 
18198a89dc62SBingbu Cao 	return 0;
18208a89dc62SBingbu Cao }
18218a89dc62SBingbu Cao 
18228a89dc62SBingbu Cao /* Write registers up to 4 at a time */
imx319_write_reg(struct imx319 * imx319,u16 reg,u32 len,u32 val)18238a89dc62SBingbu Cao static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
18248a89dc62SBingbu Cao {
18258a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
18268a89dc62SBingbu Cao 	u8 buf[6];
18278a89dc62SBingbu Cao 
18288a89dc62SBingbu Cao 	if (len > 4)
18298a89dc62SBingbu Cao 		return -EINVAL;
18308a89dc62SBingbu Cao 
18318a89dc62SBingbu Cao 	put_unaligned_be16(reg, buf);
18328a89dc62SBingbu Cao 	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
18338a89dc62SBingbu Cao 	if (i2c_master_send(client, buf, len + 2) != len + 2)
18348a89dc62SBingbu Cao 		return -EIO;
18358a89dc62SBingbu Cao 
18368a89dc62SBingbu Cao 	return 0;
18378a89dc62SBingbu Cao }
18388a89dc62SBingbu Cao 
18398a89dc62SBingbu Cao /* Write a list of registers */
imx319_write_regs(struct imx319 * imx319,const struct imx319_reg * regs,u32 len)18408a89dc62SBingbu Cao static int imx319_write_regs(struct imx319 *imx319,
18418a89dc62SBingbu Cao 			     const struct imx319_reg *regs, u32 len)
18428a89dc62SBingbu Cao {
18438a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
18448a89dc62SBingbu Cao 	int ret;
18458a89dc62SBingbu Cao 	u32 i;
18468a89dc62SBingbu Cao 
18478a89dc62SBingbu Cao 	for (i = 0; i < len; i++) {
18488a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
18498a89dc62SBingbu Cao 		if (ret) {
18508a89dc62SBingbu Cao 			dev_err_ratelimited(&client->dev,
18518a89dc62SBingbu Cao 					    "write reg 0x%4.4x return err %d",
18528a89dc62SBingbu Cao 					    regs[i].address, ret);
18538a89dc62SBingbu Cao 			return ret;
18548a89dc62SBingbu Cao 		}
18558a89dc62SBingbu Cao 	}
18568a89dc62SBingbu Cao 
18578a89dc62SBingbu Cao 	return 0;
18588a89dc62SBingbu Cao }
18598a89dc62SBingbu Cao 
18608a89dc62SBingbu Cao /* Open sub-device */
imx319_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)18618a89dc62SBingbu Cao static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
18628a89dc62SBingbu Cao {
18638a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
18648a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *try_fmt =
18650d346d2aSTomi Valkeinen 		v4l2_subdev_get_try_format(sd, fh->state, 0);
18668a89dc62SBingbu Cao 
18678a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
18688a89dc62SBingbu Cao 
18698a89dc62SBingbu Cao 	/* Initialize try_fmt */
18708a89dc62SBingbu Cao 	try_fmt->width = imx319->cur_mode->width;
18718a89dc62SBingbu Cao 	try_fmt->height = imx319->cur_mode->height;
18728a89dc62SBingbu Cao 	try_fmt->code = imx319_get_format_code(imx319);
18738a89dc62SBingbu Cao 	try_fmt->field = V4L2_FIELD_NONE;
18748a89dc62SBingbu Cao 
18758a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
18768a89dc62SBingbu Cao 
18778a89dc62SBingbu Cao 	return 0;
18788a89dc62SBingbu Cao }
18798a89dc62SBingbu Cao 
imx319_set_ctrl(struct v4l2_ctrl * ctrl)18808a89dc62SBingbu Cao static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
18818a89dc62SBingbu Cao {
18828a89dc62SBingbu Cao 	struct imx319 *imx319 = container_of(ctrl->handler,
18838a89dc62SBingbu Cao 					     struct imx319, ctrl_handler);
18848a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
18858a89dc62SBingbu Cao 	s64 max;
18868a89dc62SBingbu Cao 	int ret;
18878a89dc62SBingbu Cao 
18888a89dc62SBingbu Cao 	/* Propagate change of current control to all related controls */
18898a89dc62SBingbu Cao 	switch (ctrl->id) {
18908a89dc62SBingbu Cao 	case V4L2_CID_VBLANK:
18918a89dc62SBingbu Cao 		/* Update max exposure while meeting expected vblanking */
18928a89dc62SBingbu Cao 		max = imx319->cur_mode->height + ctrl->val - 18;
18938a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->exposure,
18948a89dc62SBingbu Cao 					 imx319->exposure->minimum,
18958a89dc62SBingbu Cao 					 max, imx319->exposure->step, max);
18968a89dc62SBingbu Cao 		break;
18978a89dc62SBingbu Cao 	}
18988a89dc62SBingbu Cao 
18998a89dc62SBingbu Cao 	/*
19008a89dc62SBingbu Cao 	 * Applying V4L2 control value only happens
19018a89dc62SBingbu Cao 	 * when power is up for streaming
19028a89dc62SBingbu Cao 	 */
19038a89dc62SBingbu Cao 	if (!pm_runtime_get_if_in_use(&client->dev))
19048a89dc62SBingbu Cao 		return 0;
19058a89dc62SBingbu Cao 
19068a89dc62SBingbu Cao 	switch (ctrl->id) {
19078a89dc62SBingbu Cao 	case V4L2_CID_ANALOGUE_GAIN:
19088a89dc62SBingbu Cao 		/* Analog gain = 1024/(1024 - ctrl->val) times */
19098a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_ANALOG_GAIN, 2,
19108a89dc62SBingbu Cao 				       ctrl->val);
19118a89dc62SBingbu Cao 		break;
19128a89dc62SBingbu Cao 	case V4L2_CID_DIGITAL_GAIN:
19138a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_DIG_GAIN_GLOBAL, 2,
19148a89dc62SBingbu Cao 				       ctrl->val);
19158a89dc62SBingbu Cao 		break;
19168a89dc62SBingbu Cao 	case V4L2_CID_EXPOSURE:
19178a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_EXPOSURE, 2,
19188a89dc62SBingbu Cao 				       ctrl->val);
19198a89dc62SBingbu Cao 		break;
19208a89dc62SBingbu Cao 	case V4L2_CID_VBLANK:
19218a89dc62SBingbu Cao 		/* Update FLL that meets expected vertical blanking */
19228a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_FLL, 2,
19238a89dc62SBingbu Cao 				       imx319->cur_mode->height + ctrl->val);
19248a89dc62SBingbu Cao 		break;
19258a89dc62SBingbu Cao 	case V4L2_CID_TEST_PATTERN:
19268a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_TEST_PATTERN,
19278a89dc62SBingbu Cao 				       2, ctrl->val);
19288a89dc62SBingbu Cao 		break;
19298a89dc62SBingbu Cao 	case V4L2_CID_HFLIP:
19308a89dc62SBingbu Cao 	case V4L2_CID_VFLIP:
19318a89dc62SBingbu Cao 		ret = imx319_write_reg(imx319, IMX319_REG_ORIENTATION, 1,
19328a89dc62SBingbu Cao 				       imx319->hflip->val |
19338a89dc62SBingbu Cao 				       imx319->vflip->val << 1);
19348a89dc62SBingbu Cao 		break;
19358a89dc62SBingbu Cao 	default:
19368a89dc62SBingbu Cao 		ret = -EINVAL;
19378a89dc62SBingbu Cao 		dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
19388a89dc62SBingbu Cao 			 ctrl->id, ctrl->val);
19398a89dc62SBingbu Cao 		break;
19408a89dc62SBingbu Cao 	}
19418a89dc62SBingbu Cao 
19428a89dc62SBingbu Cao 	pm_runtime_put(&client->dev);
19438a89dc62SBingbu Cao 
19448a89dc62SBingbu Cao 	return ret;
19458a89dc62SBingbu Cao }
19468a89dc62SBingbu Cao 
19478a89dc62SBingbu Cao static const struct v4l2_ctrl_ops imx319_ctrl_ops = {
19488a89dc62SBingbu Cao 	.s_ctrl = imx319_set_ctrl,
19498a89dc62SBingbu Cao };
19508a89dc62SBingbu Cao 
imx319_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_mbus_code_enum * code)19518a89dc62SBingbu Cao static int imx319_enum_mbus_code(struct v4l2_subdev *sd,
19520d346d2aSTomi Valkeinen 				 struct v4l2_subdev_state *sd_state,
19538a89dc62SBingbu Cao 				 struct v4l2_subdev_mbus_code_enum *code)
19548a89dc62SBingbu Cao {
19558a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
19568a89dc62SBingbu Cao 
19578a89dc62SBingbu Cao 	if (code->index > 0)
19588a89dc62SBingbu Cao 		return -EINVAL;
19598a89dc62SBingbu Cao 
19608a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
19618a89dc62SBingbu Cao 	code->code = imx319_get_format_code(imx319);
19628a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
19638a89dc62SBingbu Cao 
19648a89dc62SBingbu Cao 	return 0;
19658a89dc62SBingbu Cao }
19668a89dc62SBingbu Cao 
imx319_enum_frame_size(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_frame_size_enum * fse)19678a89dc62SBingbu Cao static int imx319_enum_frame_size(struct v4l2_subdev *sd,
19680d346d2aSTomi Valkeinen 				  struct v4l2_subdev_state *sd_state,
19698a89dc62SBingbu Cao 				  struct v4l2_subdev_frame_size_enum *fse)
19708a89dc62SBingbu Cao {
19718a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
19728a89dc62SBingbu Cao 
19738a89dc62SBingbu Cao 	if (fse->index >= ARRAY_SIZE(supported_modes))
19748a89dc62SBingbu Cao 		return -EINVAL;
19758a89dc62SBingbu Cao 
19768a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
19778a89dc62SBingbu Cao 	if (fse->code != imx319_get_format_code(imx319)) {
19788a89dc62SBingbu Cao 		mutex_unlock(&imx319->mutex);
19798a89dc62SBingbu Cao 		return -EINVAL;
19808a89dc62SBingbu Cao 	}
19818a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
19828a89dc62SBingbu Cao 
19838a89dc62SBingbu Cao 	fse->min_width = supported_modes[fse->index].width;
19848a89dc62SBingbu Cao 	fse->max_width = fse->min_width;
19858a89dc62SBingbu Cao 	fse->min_height = supported_modes[fse->index].height;
19868a89dc62SBingbu Cao 	fse->max_height = fse->min_height;
19878a89dc62SBingbu Cao 
19888a89dc62SBingbu Cao 	return 0;
19898a89dc62SBingbu Cao }
19908a89dc62SBingbu Cao 
imx319_update_pad_format(struct imx319 * imx319,const struct imx319_mode * mode,struct v4l2_subdev_format * fmt)19918a89dc62SBingbu Cao static void imx319_update_pad_format(struct imx319 *imx319,
19928a89dc62SBingbu Cao 				     const struct imx319_mode *mode,
19938a89dc62SBingbu Cao 				     struct v4l2_subdev_format *fmt)
19948a89dc62SBingbu Cao {
19958a89dc62SBingbu Cao 	fmt->format.width = mode->width;
19968a89dc62SBingbu Cao 	fmt->format.height = mode->height;
19978a89dc62SBingbu Cao 	fmt->format.code = imx319_get_format_code(imx319);
19988a89dc62SBingbu Cao 	fmt->format.field = V4L2_FIELD_NONE;
19998a89dc62SBingbu Cao }
20008a89dc62SBingbu Cao 
imx319_do_get_pad_format(struct imx319 * imx319,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)20018a89dc62SBingbu Cao static int imx319_do_get_pad_format(struct imx319 *imx319,
20020d346d2aSTomi Valkeinen 				    struct v4l2_subdev_state *sd_state,
20038a89dc62SBingbu Cao 				    struct v4l2_subdev_format *fmt)
20048a89dc62SBingbu Cao {
20058a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *framefmt;
20068a89dc62SBingbu Cao 	struct v4l2_subdev *sd = &imx319->sd;
20078a89dc62SBingbu Cao 
20088a89dc62SBingbu Cao 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
20090d346d2aSTomi Valkeinen 		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
20108a89dc62SBingbu Cao 		fmt->format = *framefmt;
20118a89dc62SBingbu Cao 	} else {
20128a89dc62SBingbu Cao 		imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
20138a89dc62SBingbu Cao 	}
20148a89dc62SBingbu Cao 
20158a89dc62SBingbu Cao 	return 0;
20168a89dc62SBingbu Cao }
20178a89dc62SBingbu Cao 
imx319_get_pad_format(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)20188a89dc62SBingbu Cao static int imx319_get_pad_format(struct v4l2_subdev *sd,
20190d346d2aSTomi Valkeinen 				 struct v4l2_subdev_state *sd_state,
20208a89dc62SBingbu Cao 				 struct v4l2_subdev_format *fmt)
20218a89dc62SBingbu Cao {
20228a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
20238a89dc62SBingbu Cao 	int ret;
20248a89dc62SBingbu Cao 
20258a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
20260d346d2aSTomi Valkeinen 	ret = imx319_do_get_pad_format(imx319, sd_state, fmt);
20278a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
20288a89dc62SBingbu Cao 
20298a89dc62SBingbu Cao 	return ret;
20308a89dc62SBingbu Cao }
20318a89dc62SBingbu Cao 
20328a89dc62SBingbu Cao static int
imx319_set_pad_format(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * fmt)20338a89dc62SBingbu Cao imx319_set_pad_format(struct v4l2_subdev *sd,
20340d346d2aSTomi Valkeinen 		      struct v4l2_subdev_state *sd_state,
20358a89dc62SBingbu Cao 		      struct v4l2_subdev_format *fmt)
20368a89dc62SBingbu Cao {
20378a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
20388a89dc62SBingbu Cao 	const struct imx319_mode *mode;
20398a89dc62SBingbu Cao 	struct v4l2_mbus_framefmt *framefmt;
20408a89dc62SBingbu Cao 	s32 vblank_def;
20418a89dc62SBingbu Cao 	s32 vblank_min;
20428a89dc62SBingbu Cao 	s64 h_blank;
20438a89dc62SBingbu Cao 	u64 pixel_rate;
20448a89dc62SBingbu Cao 	u32 height;
20458a89dc62SBingbu Cao 
20468a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
20478a89dc62SBingbu Cao 
20488a89dc62SBingbu Cao 	/*
20498a89dc62SBingbu Cao 	 * Only one bayer order is supported.
20508a89dc62SBingbu Cao 	 * It depends on the flip settings.
20518a89dc62SBingbu Cao 	 */
20528a89dc62SBingbu Cao 	fmt->format.code = imx319_get_format_code(imx319);
20538a89dc62SBingbu Cao 
20548a89dc62SBingbu Cao 	mode = v4l2_find_nearest_size(supported_modes,
20558a89dc62SBingbu Cao 				      ARRAY_SIZE(supported_modes),
20568a89dc62SBingbu Cao 				      width, height,
20578a89dc62SBingbu Cao 				      fmt->format.width, fmt->format.height);
20588a89dc62SBingbu Cao 	imx319_update_pad_format(imx319, mode, fmt);
20598a89dc62SBingbu Cao 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
20600d346d2aSTomi Valkeinen 		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
20618a89dc62SBingbu Cao 		*framefmt = fmt->format;
20628a89dc62SBingbu Cao 	} else {
20638a89dc62SBingbu Cao 		imx319->cur_mode = mode;
20648a89dc62SBingbu Cao 		pixel_rate = imx319->link_def_freq * 2 * 4;
20658a89dc62SBingbu Cao 		do_div(pixel_rate, 10);
20668a89dc62SBingbu Cao 		__v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
20678a89dc62SBingbu Cao 		/* Update limits and set FPS to default */
20688a89dc62SBingbu Cao 		height = imx319->cur_mode->height;
20698a89dc62SBingbu Cao 		vblank_def = imx319->cur_mode->fll_def - height;
20708a89dc62SBingbu Cao 		vblank_min = imx319->cur_mode->fll_min - height;
20718a89dc62SBingbu Cao 		height = IMX319_FLL_MAX - height;
20728a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->vblank, vblank_min, height, 1,
20738a89dc62SBingbu Cao 					 vblank_def);
20748a89dc62SBingbu Cao 		__v4l2_ctrl_s_ctrl(imx319->vblank, vblank_def);
20758a89dc62SBingbu Cao 		h_blank = mode->llp - imx319->cur_mode->width;
20768a89dc62SBingbu Cao 		/*
20778a89dc62SBingbu Cao 		 * Currently hblank is not changeable.
20788a89dc62SBingbu Cao 		 * So FPS control is done only by vblank.
20798a89dc62SBingbu Cao 		 */
20808a89dc62SBingbu Cao 		__v4l2_ctrl_modify_range(imx319->hblank, h_blank,
20818a89dc62SBingbu Cao 					 h_blank, 1, h_blank);
20828a89dc62SBingbu Cao 	}
20838a89dc62SBingbu Cao 
20848a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
20858a89dc62SBingbu Cao 
20868a89dc62SBingbu Cao 	return 0;
20878a89dc62SBingbu Cao }
20888a89dc62SBingbu Cao 
2089434aa74bSRajmohan Mani /* Verify chip ID */
imx319_identify_module(struct imx319 * imx319)2090434aa74bSRajmohan Mani static int imx319_identify_module(struct imx319 *imx319)
2091434aa74bSRajmohan Mani {
2092434aa74bSRajmohan Mani 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2093434aa74bSRajmohan Mani 	int ret;
2094434aa74bSRajmohan Mani 	u32 val;
2095434aa74bSRajmohan Mani 
2096434aa74bSRajmohan Mani 	if (imx319->identified)
2097434aa74bSRajmohan Mani 		return 0;
2098434aa74bSRajmohan Mani 
2099434aa74bSRajmohan Mani 	ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
2100434aa74bSRajmohan Mani 	if (ret)
2101434aa74bSRajmohan Mani 		return ret;
2102434aa74bSRajmohan Mani 
2103434aa74bSRajmohan Mani 	if (val != IMX319_CHIP_ID) {
2104434aa74bSRajmohan Mani 		dev_err(&client->dev, "chip id mismatch: %x!=%x",
2105434aa74bSRajmohan Mani 			IMX319_CHIP_ID, val);
2106434aa74bSRajmohan Mani 		return -EIO;
2107434aa74bSRajmohan Mani 	}
2108434aa74bSRajmohan Mani 
2109434aa74bSRajmohan Mani 	imx319->identified = true;
2110434aa74bSRajmohan Mani 
2111434aa74bSRajmohan Mani 	return 0;
2112434aa74bSRajmohan Mani }
2113434aa74bSRajmohan Mani 
21148a89dc62SBingbu Cao /* Start streaming */
imx319_start_streaming(struct imx319 * imx319)21158a89dc62SBingbu Cao static int imx319_start_streaming(struct imx319 *imx319)
21168a89dc62SBingbu Cao {
21178a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
21188a89dc62SBingbu Cao 	const struct imx319_reg_list *reg_list;
21198a89dc62SBingbu Cao 	int ret;
21208a89dc62SBingbu Cao 
2121434aa74bSRajmohan Mani 	ret = imx319_identify_module(imx319);
2122434aa74bSRajmohan Mani 	if (ret)
2123434aa74bSRajmohan Mani 		return ret;
2124434aa74bSRajmohan Mani 
21258a89dc62SBingbu Cao 	/* Global Setting */
21268a89dc62SBingbu Cao 	reg_list = &imx319_global_setting;
21278a89dc62SBingbu Cao 	ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
21288a89dc62SBingbu Cao 	if (ret) {
21298a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to set global settings");
21308a89dc62SBingbu Cao 		return ret;
21318a89dc62SBingbu Cao 	}
21328a89dc62SBingbu Cao 
21338a89dc62SBingbu Cao 	/* Apply default values of current mode */
21348a89dc62SBingbu Cao 	reg_list = &imx319->cur_mode->reg_list;
21358a89dc62SBingbu Cao 	ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
21368a89dc62SBingbu Cao 	if (ret) {
21378a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to set mode");
21388a89dc62SBingbu Cao 		return ret;
21398a89dc62SBingbu Cao 	}
21408a89dc62SBingbu Cao 
21418a89dc62SBingbu Cao 	/* set digital gain control to all color mode */
21428a89dc62SBingbu Cao 	ret = imx319_write_reg(imx319, IMX319_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
21438a89dc62SBingbu Cao 	if (ret)
21448a89dc62SBingbu Cao 		return ret;
21458a89dc62SBingbu Cao 
21468a89dc62SBingbu Cao 	/* Apply customized values from user */
21478a89dc62SBingbu Cao 	ret =  __v4l2_ctrl_handler_setup(imx319->sd.ctrl_handler);
21488a89dc62SBingbu Cao 	if (ret)
21498a89dc62SBingbu Cao 		return ret;
21508a89dc62SBingbu Cao 
21518a89dc62SBingbu Cao 	return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
21528a89dc62SBingbu Cao 				1, IMX319_MODE_STREAMING);
21538a89dc62SBingbu Cao }
21548a89dc62SBingbu Cao 
21558a89dc62SBingbu Cao /* Stop streaming */
imx319_stop_streaming(struct imx319 * imx319)21568a89dc62SBingbu Cao static int imx319_stop_streaming(struct imx319 *imx319)
21578a89dc62SBingbu Cao {
21588a89dc62SBingbu Cao 	return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
21598a89dc62SBingbu Cao 				1, IMX319_MODE_STANDBY);
21608a89dc62SBingbu Cao }
21618a89dc62SBingbu Cao 
imx319_set_stream(struct v4l2_subdev * sd,int enable)21628a89dc62SBingbu Cao static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
21638a89dc62SBingbu Cao {
21648a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
21658a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(sd);
21668a89dc62SBingbu Cao 	int ret = 0;
21678a89dc62SBingbu Cao 
21688a89dc62SBingbu Cao 	mutex_lock(&imx319->mutex);
21698a89dc62SBingbu Cao 	if (imx319->streaming == enable) {
21708a89dc62SBingbu Cao 		mutex_unlock(&imx319->mutex);
21718a89dc62SBingbu Cao 		return 0;
21728a89dc62SBingbu Cao 	}
21738a89dc62SBingbu Cao 
21748a89dc62SBingbu Cao 	if (enable) {
2175c0f8f1b6SMauro Carvalho Chehab 		ret = pm_runtime_resume_and_get(&client->dev);
2176c0f8f1b6SMauro Carvalho Chehab 		if (ret < 0)
21778a89dc62SBingbu Cao 			goto err_unlock;
21788a89dc62SBingbu Cao 
21798a89dc62SBingbu Cao 		/*
21808a89dc62SBingbu Cao 		 * Apply default & customized values
21818a89dc62SBingbu Cao 		 * and then start streaming.
21828a89dc62SBingbu Cao 		 */
21838a89dc62SBingbu Cao 		ret = imx319_start_streaming(imx319);
21848a89dc62SBingbu Cao 		if (ret)
21858a89dc62SBingbu Cao 			goto err_rpm_put;
21868a89dc62SBingbu Cao 	} else {
21878a89dc62SBingbu Cao 		imx319_stop_streaming(imx319);
21888a89dc62SBingbu Cao 		pm_runtime_put(&client->dev);
21898a89dc62SBingbu Cao 	}
21908a89dc62SBingbu Cao 
21918a89dc62SBingbu Cao 	imx319->streaming = enable;
21928a89dc62SBingbu Cao 
21938a89dc62SBingbu Cao 	/* vflip and hflip cannot change during streaming */
21948a89dc62SBingbu Cao 	__v4l2_ctrl_grab(imx319->vflip, enable);
21958a89dc62SBingbu Cao 	__v4l2_ctrl_grab(imx319->hflip, enable);
21968a89dc62SBingbu Cao 
21978a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
21988a89dc62SBingbu Cao 
21998a89dc62SBingbu Cao 	return ret;
22008a89dc62SBingbu Cao 
22018a89dc62SBingbu Cao err_rpm_put:
22028a89dc62SBingbu Cao 	pm_runtime_put(&client->dev);
22038a89dc62SBingbu Cao err_unlock:
22048a89dc62SBingbu Cao 	mutex_unlock(&imx319->mutex);
22058a89dc62SBingbu Cao 
22068a89dc62SBingbu Cao 	return ret;
22078a89dc62SBingbu Cao }
22088a89dc62SBingbu Cao 
imx319_suspend(struct device * dev)22098a89dc62SBingbu Cao static int __maybe_unused imx319_suspend(struct device *dev)
22108a89dc62SBingbu Cao {
221174290ac1SKrzysztof Kozlowski 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
22128a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
22138a89dc62SBingbu Cao 
22148a89dc62SBingbu Cao 	if (imx319->streaming)
22158a89dc62SBingbu Cao 		imx319_stop_streaming(imx319);
22168a89dc62SBingbu Cao 
22178a89dc62SBingbu Cao 	return 0;
22188a89dc62SBingbu Cao }
22198a89dc62SBingbu Cao 
imx319_resume(struct device * dev)22208a89dc62SBingbu Cao static int __maybe_unused imx319_resume(struct device *dev)
22218a89dc62SBingbu Cao {
222274290ac1SKrzysztof Kozlowski 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
22238a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
22248a89dc62SBingbu Cao 	int ret;
22258a89dc62SBingbu Cao 
22268a89dc62SBingbu Cao 	if (imx319->streaming) {
22278a89dc62SBingbu Cao 		ret = imx319_start_streaming(imx319);
22288a89dc62SBingbu Cao 		if (ret)
22298a89dc62SBingbu Cao 			goto error;
22308a89dc62SBingbu Cao 	}
22318a89dc62SBingbu Cao 
22328a89dc62SBingbu Cao 	return 0;
22338a89dc62SBingbu Cao 
22348a89dc62SBingbu Cao error:
22358a89dc62SBingbu Cao 	imx319_stop_streaming(imx319);
22368a89dc62SBingbu Cao 	imx319->streaming = 0;
22378a89dc62SBingbu Cao 	return ret;
22388a89dc62SBingbu Cao }
22398a89dc62SBingbu Cao 
22408a89dc62SBingbu Cao static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
22418a89dc62SBingbu Cao 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
22428a89dc62SBingbu Cao 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
22438a89dc62SBingbu Cao };
22448a89dc62SBingbu Cao 
22458a89dc62SBingbu Cao static const struct v4l2_subdev_video_ops imx319_video_ops = {
22468a89dc62SBingbu Cao 	.s_stream = imx319_set_stream,
22478a89dc62SBingbu Cao };
22488a89dc62SBingbu Cao 
22498a89dc62SBingbu Cao static const struct v4l2_subdev_pad_ops imx319_pad_ops = {
22508a89dc62SBingbu Cao 	.enum_mbus_code = imx319_enum_mbus_code,
22518a89dc62SBingbu Cao 	.get_fmt = imx319_get_pad_format,
22528a89dc62SBingbu Cao 	.set_fmt = imx319_set_pad_format,
22538a89dc62SBingbu Cao 	.enum_frame_size = imx319_enum_frame_size,
22548a89dc62SBingbu Cao };
22558a89dc62SBingbu Cao 
22568a89dc62SBingbu Cao static const struct v4l2_subdev_ops imx319_subdev_ops = {
22578a89dc62SBingbu Cao 	.core = &imx319_subdev_core_ops,
22588a89dc62SBingbu Cao 	.video = &imx319_video_ops,
22598a89dc62SBingbu Cao 	.pad = &imx319_pad_ops,
22608a89dc62SBingbu Cao };
22618a89dc62SBingbu Cao 
22628a89dc62SBingbu Cao static const struct media_entity_operations imx319_subdev_entity_ops = {
22638a89dc62SBingbu Cao 	.link_validate = v4l2_subdev_link_validate,
22648a89dc62SBingbu Cao };
22658a89dc62SBingbu Cao 
22668a89dc62SBingbu Cao static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
22678a89dc62SBingbu Cao 	.open = imx319_open,
22688a89dc62SBingbu Cao };
22698a89dc62SBingbu Cao 
22708a89dc62SBingbu Cao /* Initialize control handlers */
imx319_init_controls(struct imx319 * imx319)22718a89dc62SBingbu Cao static int imx319_init_controls(struct imx319 *imx319)
22728a89dc62SBingbu Cao {
22738a89dc62SBingbu Cao 	struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
22748a89dc62SBingbu Cao 	struct v4l2_ctrl_handler *ctrl_hdlr;
22758a89dc62SBingbu Cao 	s64 exposure_max;
22768a89dc62SBingbu Cao 	s64 vblank_def;
22778a89dc62SBingbu Cao 	s64 vblank_min;
22788a89dc62SBingbu Cao 	s64 hblank;
22798a89dc62SBingbu Cao 	u64 pixel_rate;
22808a89dc62SBingbu Cao 	const struct imx319_mode *mode;
22818a89dc62SBingbu Cao 	u32 max;
22828a89dc62SBingbu Cao 	int ret;
22838a89dc62SBingbu Cao 
22848a89dc62SBingbu Cao 	ctrl_hdlr = &imx319->ctrl_handler;
22858a89dc62SBingbu Cao 	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
22868a89dc62SBingbu Cao 	if (ret)
22878a89dc62SBingbu Cao 		return ret;
22888a89dc62SBingbu Cao 
22898a89dc62SBingbu Cao 	ctrl_hdlr->lock = &imx319->mutex;
22908a89dc62SBingbu Cao 	max = ARRAY_SIZE(link_freq_menu_items) - 1;
22918a89dc62SBingbu Cao 	imx319->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx319_ctrl_ops,
22928a89dc62SBingbu Cao 						   V4L2_CID_LINK_FREQ, max, 0,
22938a89dc62SBingbu Cao 						   link_freq_menu_items);
22948a89dc62SBingbu Cao 	if (imx319->link_freq)
22958a89dc62SBingbu Cao 		imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
22968a89dc62SBingbu Cao 
22978a89dc62SBingbu Cao 	/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
22988a89dc62SBingbu Cao 	pixel_rate = imx319->link_def_freq * 2 * 4;
22998a89dc62SBingbu Cao 	do_div(pixel_rate, 10);
23008a89dc62SBingbu Cao 	/* By default, PIXEL_RATE is read only */
23018a89dc62SBingbu Cao 	imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23028a89dc62SBingbu Cao 					       V4L2_CID_PIXEL_RATE, pixel_rate,
23038a89dc62SBingbu Cao 					       pixel_rate, 1, pixel_rate);
23048a89dc62SBingbu Cao 
23058a89dc62SBingbu Cao 	/* Initial vblank/hblank/exposure parameters based on current mode */
23068a89dc62SBingbu Cao 	mode = imx319->cur_mode;
23078a89dc62SBingbu Cao 	vblank_def = mode->fll_def - mode->height;
23088a89dc62SBingbu Cao 	vblank_min = mode->fll_min - mode->height;
23098a89dc62SBingbu Cao 	imx319->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23108a89dc62SBingbu Cao 					   V4L2_CID_VBLANK, vblank_min,
23118a89dc62SBingbu Cao 					   IMX319_FLL_MAX - mode->height,
23128a89dc62SBingbu Cao 					   1, vblank_def);
23138a89dc62SBingbu Cao 
23148a89dc62SBingbu Cao 	hblank = mode->llp - mode->width;
23158a89dc62SBingbu Cao 	imx319->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23168a89dc62SBingbu Cao 					   V4L2_CID_HBLANK, hblank, hblank,
23178a89dc62SBingbu Cao 					   1, hblank);
23188a89dc62SBingbu Cao 	if (imx319->hblank)
23198a89dc62SBingbu Cao 		imx319->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
23208a89dc62SBingbu Cao 
23218a89dc62SBingbu Cao 	/* fll >= exposure time + adjust parameter (default value is 18) */
23228a89dc62SBingbu Cao 	exposure_max = mode->fll_def - 18;
23238a89dc62SBingbu Cao 	imx319->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23248a89dc62SBingbu Cao 					     V4L2_CID_EXPOSURE,
23258a89dc62SBingbu Cao 					     IMX319_EXPOSURE_MIN, exposure_max,
23268a89dc62SBingbu Cao 					     IMX319_EXPOSURE_STEP,
23278a89dc62SBingbu Cao 					     IMX319_EXPOSURE_DEFAULT);
23288a89dc62SBingbu Cao 
23298a89dc62SBingbu Cao 	imx319->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23308a89dc62SBingbu Cao 					  V4L2_CID_HFLIP, 0, 1, 1, 0);
2331bdf24018SDave Stevenson 	if (imx319->hflip)
2332bdf24018SDave Stevenson 		imx319->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
23338a89dc62SBingbu Cao 	imx319->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
23348a89dc62SBingbu Cao 					  V4L2_CID_VFLIP, 0, 1, 1, 0);
2335bdf24018SDave Stevenson 	if (imx319->vflip)
2336bdf24018SDave Stevenson 		imx319->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
23378a89dc62SBingbu Cao 
23388a89dc62SBingbu Cao 	v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
23398a89dc62SBingbu Cao 			  IMX319_ANA_GAIN_MIN, IMX319_ANA_GAIN_MAX,
23408a89dc62SBingbu Cao 			  IMX319_ANA_GAIN_STEP, IMX319_ANA_GAIN_DEFAULT);
23418a89dc62SBingbu Cao 
23428a89dc62SBingbu Cao 	/* Digital gain */
23438a89dc62SBingbu Cao 	v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
23448a89dc62SBingbu Cao 			  IMX319_DGTL_GAIN_MIN, IMX319_DGTL_GAIN_MAX,
23458a89dc62SBingbu Cao 			  IMX319_DGTL_GAIN_STEP, IMX319_DGTL_GAIN_DEFAULT);
23468a89dc62SBingbu Cao 
23478a89dc62SBingbu Cao 	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx319_ctrl_ops,
23488a89dc62SBingbu Cao 				     V4L2_CID_TEST_PATTERN,
23498a89dc62SBingbu Cao 				     ARRAY_SIZE(imx319_test_pattern_menu) - 1,
23508a89dc62SBingbu Cao 				     0, 0, imx319_test_pattern_menu);
23518a89dc62SBingbu Cao 	if (ctrl_hdlr->error) {
23528a89dc62SBingbu Cao 		ret = ctrl_hdlr->error;
23538a89dc62SBingbu Cao 		dev_err(&client->dev, "control init failed: %d", ret);
23548a89dc62SBingbu Cao 		goto error;
23558a89dc62SBingbu Cao 	}
23568a89dc62SBingbu Cao 
23578a89dc62SBingbu Cao 	imx319->sd.ctrl_handler = ctrl_hdlr;
23588a89dc62SBingbu Cao 
23598a89dc62SBingbu Cao 	return 0;
23608a89dc62SBingbu Cao 
23618a89dc62SBingbu Cao error:
23628a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(ctrl_hdlr);
23638a89dc62SBingbu Cao 
23648a89dc62SBingbu Cao 	return ret;
23658a89dc62SBingbu Cao }
23668a89dc62SBingbu Cao 
imx319_get_hwcfg(struct device * dev)23678a89dc62SBingbu Cao static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
23688a89dc62SBingbu Cao {
23698a89dc62SBingbu Cao 	struct imx319_hwcfg *cfg;
23708a89dc62SBingbu Cao 	struct v4l2_fwnode_endpoint bus_cfg = {
23718a89dc62SBingbu Cao 		.bus_type = V4L2_MBUS_CSI2_DPHY
23728a89dc62SBingbu Cao 	};
23738a89dc62SBingbu Cao 	struct fwnode_handle *ep;
23748a89dc62SBingbu Cao 	struct fwnode_handle *fwnode = dev_fwnode(dev);
23758a89dc62SBingbu Cao 	unsigned int i;
23768a89dc62SBingbu Cao 	int ret;
23778a89dc62SBingbu Cao 
23788a89dc62SBingbu Cao 	if (!fwnode)
23798a89dc62SBingbu Cao 		return NULL;
23808a89dc62SBingbu Cao 
23818a89dc62SBingbu Cao 	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
23828a89dc62SBingbu Cao 	if (!ep)
23838a89dc62SBingbu Cao 		return NULL;
23848a89dc62SBingbu Cao 
23858a89dc62SBingbu Cao 	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
23868a89dc62SBingbu Cao 	if (ret)
23878a89dc62SBingbu Cao 		goto out_err;
23888a89dc62SBingbu Cao 
23898a89dc62SBingbu Cao 	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
23908a89dc62SBingbu Cao 	if (!cfg)
23918a89dc62SBingbu Cao 		goto out_err;
23928a89dc62SBingbu Cao 
23938a89dc62SBingbu Cao 	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
23948a89dc62SBingbu Cao 				       &cfg->ext_clk);
23958a89dc62SBingbu Cao 	if (ret) {
23968a89dc62SBingbu Cao 		dev_err(dev, "can't get clock frequency");
23978a89dc62SBingbu Cao 		goto out_err;
23988a89dc62SBingbu Cao 	}
23998a89dc62SBingbu Cao 
24008a89dc62SBingbu Cao 	dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
24018a89dc62SBingbu Cao 	if (cfg->ext_clk != IMX319_EXT_CLK) {
24028a89dc62SBingbu Cao 		dev_err(dev, "external clock %d is not supported",
24038a89dc62SBingbu Cao 			cfg->ext_clk);
24048a89dc62SBingbu Cao 		goto out_err;
24058a89dc62SBingbu Cao 	}
24068a89dc62SBingbu Cao 
24078a89dc62SBingbu Cao 	dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
24088a89dc62SBingbu Cao 	if (!bus_cfg.nr_of_link_frequencies) {
24098a89dc62SBingbu Cao 		dev_warn(dev, "no link frequencies defined");
24108a89dc62SBingbu Cao 		goto out_err;
24118a89dc62SBingbu Cao 	}
24128a89dc62SBingbu Cao 
24138a89dc62SBingbu Cao 	cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
241470d8fa7cSMauro Carvalho Chehab 	cfg->link_freqs = devm_kcalloc(dev,
241570d8fa7cSMauro Carvalho Chehab 				       bus_cfg.nr_of_link_frequencies + 1,
24168a89dc62SBingbu Cao 				       sizeof(*cfg->link_freqs), GFP_KERNEL);
24178a89dc62SBingbu Cao 	if (!cfg->link_freqs)
24188a89dc62SBingbu Cao 		goto out_err;
24198a89dc62SBingbu Cao 
24208a89dc62SBingbu Cao 	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
24218a89dc62SBingbu Cao 		cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
24228a89dc62SBingbu Cao 		dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
24238a89dc62SBingbu Cao 	}
24248a89dc62SBingbu Cao 
24258a89dc62SBingbu Cao 	v4l2_fwnode_endpoint_free(&bus_cfg);
24268a89dc62SBingbu Cao 	fwnode_handle_put(ep);
24278a89dc62SBingbu Cao 	return cfg;
24288a89dc62SBingbu Cao 
24298a89dc62SBingbu Cao out_err:
24308a89dc62SBingbu Cao 	v4l2_fwnode_endpoint_free(&bus_cfg);
24318a89dc62SBingbu Cao 	fwnode_handle_put(ep);
24328a89dc62SBingbu Cao 	return NULL;
24338a89dc62SBingbu Cao }
24348a89dc62SBingbu Cao 
imx319_probe(struct i2c_client * client)24358a89dc62SBingbu Cao static int imx319_probe(struct i2c_client *client)
24368a89dc62SBingbu Cao {
24378a89dc62SBingbu Cao 	struct imx319 *imx319;
2438434aa74bSRajmohan Mani 	bool full_power;
24398a89dc62SBingbu Cao 	int ret;
24408a89dc62SBingbu Cao 	u32 i;
24418a89dc62SBingbu Cao 
24428a89dc62SBingbu Cao 	imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
24438a89dc62SBingbu Cao 	if (!imx319)
24448a89dc62SBingbu Cao 		return -ENOMEM;
24458a89dc62SBingbu Cao 
24468a89dc62SBingbu Cao 	mutex_init(&imx319->mutex);
24478a89dc62SBingbu Cao 
24488a89dc62SBingbu Cao 	/* Initialize subdev */
24498a89dc62SBingbu Cao 	v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
24508a89dc62SBingbu Cao 
2451434aa74bSRajmohan Mani 	full_power = acpi_dev_state_d0(&client->dev);
2452434aa74bSRajmohan Mani 	if (full_power) {
24538a89dc62SBingbu Cao 		/* Check module identity */
24548a89dc62SBingbu Cao 		ret = imx319_identify_module(imx319);
24558a89dc62SBingbu Cao 		if (ret) {
24568a89dc62SBingbu Cao 			dev_err(&client->dev, "failed to find sensor: %d", ret);
24578a89dc62SBingbu Cao 			goto error_probe;
24588a89dc62SBingbu Cao 		}
2459434aa74bSRajmohan Mani 	}
24608a89dc62SBingbu Cao 
24618a89dc62SBingbu Cao 	imx319->hwcfg = imx319_get_hwcfg(&client->dev);
24628a89dc62SBingbu Cao 	if (!imx319->hwcfg) {
24638a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to get hwcfg");
24648a89dc62SBingbu Cao 		ret = -ENODEV;
24658a89dc62SBingbu Cao 		goto error_probe;
24668a89dc62SBingbu Cao 	}
24678a89dc62SBingbu Cao 
24688a89dc62SBingbu Cao 	imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
24698a89dc62SBingbu Cao 	for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
24708a89dc62SBingbu Cao 		if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
24718a89dc62SBingbu Cao 			dev_dbg(&client->dev, "link freq index %d matched", i);
24728a89dc62SBingbu Cao 			break;
24738a89dc62SBingbu Cao 		}
24748a89dc62SBingbu Cao 	}
24758a89dc62SBingbu Cao 
24768a89dc62SBingbu Cao 	if (i == imx319->hwcfg->nr_of_link_freqs) {
24778a89dc62SBingbu Cao 		dev_err(&client->dev, "no link frequency supported");
24788a89dc62SBingbu Cao 		ret = -EINVAL;
24798a89dc62SBingbu Cao 		goto error_probe;
24808a89dc62SBingbu Cao 	}
24818a89dc62SBingbu Cao 
24828a89dc62SBingbu Cao 	/* Set default mode to max resolution */
24838a89dc62SBingbu Cao 	imx319->cur_mode = &supported_modes[0];
24848a89dc62SBingbu Cao 
24858a89dc62SBingbu Cao 	ret = imx319_init_controls(imx319);
24868a89dc62SBingbu Cao 	if (ret) {
24878a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to init controls: %d", ret);
24888a89dc62SBingbu Cao 		goto error_probe;
24898a89dc62SBingbu Cao 	}
24908a89dc62SBingbu Cao 
24918a89dc62SBingbu Cao 	/* Initialize subdev */
24928a89dc62SBingbu Cao 	imx319->sd.internal_ops = &imx319_internal_ops;
24938a89dc62SBingbu Cao 	imx319->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
24948a89dc62SBingbu Cao 		V4L2_SUBDEV_FL_HAS_EVENTS;
24958a89dc62SBingbu Cao 	imx319->sd.entity.ops = &imx319_subdev_entity_ops;
24968a89dc62SBingbu Cao 	imx319->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
24978a89dc62SBingbu Cao 
24988a89dc62SBingbu Cao 	/* Initialize source pad */
24998a89dc62SBingbu Cao 	imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
25008a89dc62SBingbu Cao 	ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
25018a89dc62SBingbu Cao 	if (ret) {
25028a89dc62SBingbu Cao 		dev_err(&client->dev, "failed to init entity pads: %d", ret);
25038a89dc62SBingbu Cao 		goto error_handler_free;
25048a89dc62SBingbu Cao 	}
25058a89dc62SBingbu Cao 
250615786f7bSSakari Ailus 	ret = v4l2_async_register_subdev_sensor(&imx319->sd);
25078a89dc62SBingbu Cao 	if (ret < 0)
25088a89dc62SBingbu Cao 		goto error_media_entity;
25098a89dc62SBingbu Cao 
2510434aa74bSRajmohan Mani 	/* Set the device's state to active if it's in D0 state. */
2511434aa74bSRajmohan Mani 	if (full_power)
25128a89dc62SBingbu Cao 		pm_runtime_set_active(&client->dev);
25138a89dc62SBingbu Cao 	pm_runtime_enable(&client->dev);
25148a89dc62SBingbu Cao 	pm_runtime_idle(&client->dev);
25158a89dc62SBingbu Cao 
25168a89dc62SBingbu Cao 	return 0;
25178a89dc62SBingbu Cao 
25188a89dc62SBingbu Cao error_media_entity:
25198a89dc62SBingbu Cao 	media_entity_cleanup(&imx319->sd.entity);
25208a89dc62SBingbu Cao 
25218a89dc62SBingbu Cao error_handler_free:
25228a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(imx319->sd.ctrl_handler);
25238a89dc62SBingbu Cao 
25248a89dc62SBingbu Cao error_probe:
25258a89dc62SBingbu Cao 	mutex_destroy(&imx319->mutex);
25268a89dc62SBingbu Cao 
25278a89dc62SBingbu Cao 	return ret;
25288a89dc62SBingbu Cao }
25298a89dc62SBingbu Cao 
imx319_remove(struct i2c_client * client)2530ed5c2f5fSUwe Kleine-König static void imx319_remove(struct i2c_client *client)
25318a89dc62SBingbu Cao {
25328a89dc62SBingbu Cao 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
25338a89dc62SBingbu Cao 	struct imx319 *imx319 = to_imx319(sd);
25348a89dc62SBingbu Cao 
25358a89dc62SBingbu Cao 	v4l2_async_unregister_subdev(sd);
25368a89dc62SBingbu Cao 	media_entity_cleanup(&sd->entity);
25378a89dc62SBingbu Cao 	v4l2_ctrl_handler_free(sd->ctrl_handler);
25388a89dc62SBingbu Cao 
25398a89dc62SBingbu Cao 	pm_runtime_disable(&client->dev);
25408a89dc62SBingbu Cao 	pm_runtime_set_suspended(&client->dev);
25418a89dc62SBingbu Cao 
25428a89dc62SBingbu Cao 	mutex_destroy(&imx319->mutex);
25438a89dc62SBingbu Cao }
25448a89dc62SBingbu Cao 
25458a89dc62SBingbu Cao static const struct dev_pm_ops imx319_pm_ops = {
25468a89dc62SBingbu Cao 	SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
25478a89dc62SBingbu Cao };
25488a89dc62SBingbu Cao 
25495347e1edSKrzysztof Kozlowski static const struct acpi_device_id imx319_acpi_ids[] __maybe_unused = {
25508a89dc62SBingbu Cao 	{ "SONY319A" },
25518a89dc62SBingbu Cao 	{ /* sentinel */ }
25528a89dc62SBingbu Cao };
25538a89dc62SBingbu Cao MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
25548a89dc62SBingbu Cao 
25558a89dc62SBingbu Cao static struct i2c_driver imx319_i2c_driver = {
25568a89dc62SBingbu Cao 	.driver = {
25578a89dc62SBingbu Cao 		.name = "imx319",
25588a89dc62SBingbu Cao 		.pm = &imx319_pm_ops,
25598a89dc62SBingbu Cao 		.acpi_match_table = ACPI_PTR(imx319_acpi_ids),
25608a89dc62SBingbu Cao 	},
2561aaeb31c0SUwe Kleine-König 	.probe = imx319_probe,
25628a89dc62SBingbu Cao 	.remove = imx319_remove,
2563434aa74bSRajmohan Mani 	.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
25648a89dc62SBingbu Cao };
25658a89dc62SBingbu Cao module_i2c_driver(imx319_i2c_driver);
25668a89dc62SBingbu Cao 
25678a89dc62SBingbu Cao MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
2568*4106cd72SSakari Ailus MODULE_AUTHOR("Rapolu, Chiranjeevi");
25698a89dc62SBingbu Cao MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
25705fcec420SSakari Ailus MODULE_AUTHOR("Yang, Hyungwoo");
25718a89dc62SBingbu Cao MODULE_DESCRIPTION("Sony imx319 sensor driver");
25728a89dc62SBingbu Cao MODULE_LICENSE("GPL v2");
2573