Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2018 Intel Corporation
0003 
0004 #include <asm/unaligned.h>
0005 #include <linux/acpi.h>
0006 #include <linux/i2c.h>
0007 #include <linux/module.h>
0008 #include <linux/pm_runtime.h>
0009 #include <media/v4l2-ctrls.h>
0010 #include <media/v4l2-device.h>
0011 #include <media/v4l2-event.h>
0012 #include <media/v4l2-fwnode.h>
0013 
0014 #define IMX319_REG_MODE_SELECT      0x0100
0015 #define IMX319_MODE_STANDBY     0x00
0016 #define IMX319_MODE_STREAMING       0x01
0017 
0018 /* Chip ID */
0019 #define IMX319_REG_CHIP_ID      0x0016
0020 #define IMX319_CHIP_ID          0x0319
0021 
0022 /* V_TIMING internal */
0023 #define IMX319_REG_FLL          0x0340
0024 #define IMX319_FLL_MAX          0xffff
0025 
0026 /* Exposure control */
0027 #define IMX319_REG_EXPOSURE     0x0202
0028 #define IMX319_EXPOSURE_MIN     1
0029 #define IMX319_EXPOSURE_STEP        1
0030 #define IMX319_EXPOSURE_DEFAULT     0x04f6
0031 
0032 /*
0033  *  the digital control register for all color control looks like:
0034  *  +-----------------+------------------+
0035  *  |      [7:0]      |       [15:8]     |
0036  *  +-----------------+------------------+
0037  *  |     0x020f      |       0x020e     |
0038  *  --------------------------------------
0039  *  it is used to calculate the digital gain times value(integral + fractional)
0040  *  the [15:8] bits is the fractional part and [7:0] bits is the integral
0041  *  calculation equation is:
0042  *      gain value (unit: times) = REG[15:8] + REG[7:0]/0x100
0043  *  Only value in 0x0100 ~ 0x0FFF range is allowed.
0044  *  Analog gain use 10 bits in the registers and allowed range is 0 ~ 960
0045  */
0046 /* Analog gain control */
0047 #define IMX319_REG_ANALOG_GAIN      0x0204
0048 #define IMX319_ANA_GAIN_MIN     0
0049 #define IMX319_ANA_GAIN_MAX     960
0050 #define IMX319_ANA_GAIN_STEP        1
0051 #define IMX319_ANA_GAIN_DEFAULT     0
0052 
0053 /* Digital gain control */
0054 #define IMX319_REG_DPGA_USE_GLOBAL_GAIN 0x3ff9
0055 #define IMX319_REG_DIG_GAIN_GLOBAL  0x020e
0056 #define IMX319_DGTL_GAIN_MIN        256
0057 #define IMX319_DGTL_GAIN_MAX        4095
0058 #define IMX319_DGTL_GAIN_STEP       1
0059 #define IMX319_DGTL_GAIN_DEFAULT    256
0060 
0061 /* Test Pattern Control */
0062 #define IMX319_REG_TEST_PATTERN     0x0600
0063 #define IMX319_TEST_PATTERN_DISABLED        0
0064 #define IMX319_TEST_PATTERN_SOLID_COLOR     1
0065 #define IMX319_TEST_PATTERN_COLOR_BARS      2
0066 #define IMX319_TEST_PATTERN_GRAY_COLOR_BARS 3
0067 #define IMX319_TEST_PATTERN_PN9         4
0068 
0069 /* Flip Control */
0070 #define IMX319_REG_ORIENTATION      0x0101
0071 
0072 /* default link frequency and external clock */
0073 #define IMX319_LINK_FREQ_DEFAULT    482400000
0074 #define IMX319_EXT_CLK          19200000
0075 #define IMX319_LINK_FREQ_INDEX      0
0076 
0077 struct imx319_reg {
0078     u16 address;
0079     u8 val;
0080 };
0081 
0082 struct imx319_reg_list {
0083     u32 num_of_regs;
0084     const struct imx319_reg *regs;
0085 };
0086 
0087 /* Mode : resolution and related config&values */
0088 struct imx319_mode {
0089     /* Frame width */
0090     u32 width;
0091     /* Frame height */
0092     u32 height;
0093 
0094     /* V-timing */
0095     u32 fll_def;
0096     u32 fll_min;
0097 
0098     /* H-timing */
0099     u32 llp;
0100 
0101     /* index of link frequency */
0102     u32 link_freq_index;
0103 
0104     /* Default register values */
0105     struct imx319_reg_list reg_list;
0106 };
0107 
0108 struct imx319_hwcfg {
0109     u32 ext_clk;            /* sensor external clk */
0110     s64 *link_freqs;        /* CSI-2 link frequencies */
0111     unsigned int nr_of_link_freqs;
0112 };
0113 
0114 struct imx319 {
0115     struct v4l2_subdev sd;
0116     struct media_pad pad;
0117 
0118     struct v4l2_ctrl_handler ctrl_handler;
0119     /* V4L2 Controls */
0120     struct v4l2_ctrl *link_freq;
0121     struct v4l2_ctrl *pixel_rate;
0122     struct v4l2_ctrl *vblank;
0123     struct v4l2_ctrl *hblank;
0124     struct v4l2_ctrl *exposure;
0125     struct v4l2_ctrl *vflip;
0126     struct v4l2_ctrl *hflip;
0127 
0128     /* Current mode */
0129     const struct imx319_mode *cur_mode;
0130 
0131     struct imx319_hwcfg *hwcfg;
0132     s64 link_def_freq;  /* CSI-2 link default frequency */
0133 
0134     /*
0135      * Mutex for serialized access:
0136      * Protect sensor set pad format and start/stop streaming safely.
0137      * Protect access to sensor v4l2 controls.
0138      */
0139     struct mutex mutex;
0140 
0141     /* Streaming on/off */
0142     bool streaming;
0143     /* True if the device has been identified */
0144     bool identified;
0145 };
0146 
0147 static const struct imx319_reg imx319_global_regs[] = {
0148     { 0x0136, 0x13 },
0149     { 0x0137, 0x33 },
0150     { 0x3c7e, 0x05 },
0151     { 0x3c7f, 0x07 },
0152     { 0x4d39, 0x0b },
0153     { 0x4d41, 0x33 },
0154     { 0x4d43, 0x0c },
0155     { 0x4d49, 0x89 },
0156     { 0x4e05, 0x0b },
0157     { 0x4e0d, 0x33 },
0158     { 0x4e0f, 0x0c },
0159     { 0x4e15, 0x89 },
0160     { 0x4e49, 0x2a },
0161     { 0x4e51, 0x33 },
0162     { 0x4e53, 0x0c },
0163     { 0x4e59, 0x89 },
0164     { 0x5601, 0x4f },
0165     { 0x560b, 0x45 },
0166     { 0x562f, 0x0a },
0167     { 0x5643, 0x0a },
0168     { 0x5645, 0x0c },
0169     { 0x56ef, 0x51 },
0170     { 0x586f, 0x33 },
0171     { 0x5873, 0x89 },
0172     { 0x5905, 0x33 },
0173     { 0x5907, 0x89 },
0174     { 0x590d, 0x33 },
0175     { 0x590f, 0x89 },
0176     { 0x5915, 0x33 },
0177     { 0x5917, 0x89 },
0178     { 0x5969, 0x1c },
0179     { 0x596b, 0x72 },
0180     { 0x5971, 0x33 },
0181     { 0x5973, 0x89 },
0182     { 0x5975, 0x33 },
0183     { 0x5977, 0x89 },
0184     { 0x5979, 0x1c },
0185     { 0x597b, 0x72 },
0186     { 0x5985, 0x33 },
0187     { 0x5987, 0x89 },
0188     { 0x5999, 0x1c },
0189     { 0x599b, 0x72 },
0190     { 0x59a5, 0x33 },
0191     { 0x59a7, 0x89 },
0192     { 0x7485, 0x08 },
0193     { 0x7487, 0x0c },
0194     { 0x7489, 0xc7 },
0195     { 0x748b, 0x8b },
0196     { 0x9004, 0x09 },
0197     { 0x9200, 0x6a },
0198     { 0x9201, 0x22 },
0199     { 0x9202, 0x6a },
0200     { 0x9203, 0x23 },
0201     { 0x9204, 0x5f },
0202     { 0x9205, 0x23 },
0203     { 0x9206, 0x5f },
0204     { 0x9207, 0x24 },
0205     { 0x9208, 0x5f },
0206     { 0x9209, 0x26 },
0207     { 0x920a, 0x5f },
0208     { 0x920b, 0x27 },
0209     { 0x920c, 0x5f },
0210     { 0x920d, 0x29 },
0211     { 0x920e, 0x5f },
0212     { 0x920f, 0x2a },
0213     { 0x9210, 0x5f },
0214     { 0x9211, 0x2c },
0215     { 0xbc22, 0x1a },
0216     { 0xf01f, 0x04 },
0217     { 0xf021, 0x03 },
0218     { 0xf023, 0x02 },
0219     { 0xf03d, 0x05 },
0220     { 0xf03f, 0x03 },
0221     { 0xf041, 0x02 },
0222     { 0xf0af, 0x04 },
0223     { 0xf0b1, 0x03 },
0224     { 0xf0b3, 0x02 },
0225     { 0xf0cd, 0x05 },
0226     { 0xf0cf, 0x03 },
0227     { 0xf0d1, 0x02 },
0228     { 0xf13f, 0x04 },
0229     { 0xf141, 0x03 },
0230     { 0xf143, 0x02 },
0231     { 0xf15d, 0x05 },
0232     { 0xf15f, 0x03 },
0233     { 0xf161, 0x02 },
0234     { 0xf1cf, 0x04 },
0235     { 0xf1d1, 0x03 },
0236     { 0xf1d3, 0x02 },
0237     { 0xf1ed, 0x05 },
0238     { 0xf1ef, 0x03 },
0239     { 0xf1f1, 0x02 },
0240     { 0xf287, 0x04 },
0241     { 0xf289, 0x03 },
0242     { 0xf28b, 0x02 },
0243     { 0xf2a5, 0x05 },
0244     { 0xf2a7, 0x03 },
0245     { 0xf2a9, 0x02 },
0246     { 0xf2b7, 0x04 },
0247     { 0xf2b9, 0x03 },
0248     { 0xf2bb, 0x02 },
0249     { 0xf2d5, 0x05 },
0250     { 0xf2d7, 0x03 },
0251     { 0xf2d9, 0x02 },
0252 };
0253 
0254 static const struct imx319_reg_list imx319_global_setting = {
0255     .num_of_regs = ARRAY_SIZE(imx319_global_regs),
0256     .regs = imx319_global_regs,
0257 };
0258 
0259 static const struct imx319_reg mode_3264x2448_regs[] = {
0260     { 0x0112, 0x0a },
0261     { 0x0113, 0x0a },
0262     { 0x0114, 0x03 },
0263     { 0x0342, 0x0f },
0264     { 0x0343, 0x80 },
0265     { 0x0340, 0x0c },
0266     { 0x0341, 0xaa },
0267     { 0x0344, 0x00 },
0268     { 0x0345, 0x00 },
0269     { 0x0346, 0x00 },
0270     { 0x0347, 0x00 },
0271     { 0x0348, 0x0c },
0272     { 0x0349, 0xcf },
0273     { 0x034a, 0x09 },
0274     { 0x034b, 0x9f },
0275     { 0x0220, 0x00 },
0276     { 0x0221, 0x11 },
0277     { 0x0381, 0x01 },
0278     { 0x0383, 0x01 },
0279     { 0x0385, 0x01 },
0280     { 0x0387, 0x01 },
0281     { 0x0900, 0x00 },
0282     { 0x0901, 0x11 },
0283     { 0x0902, 0x0a },
0284     { 0x3140, 0x02 },
0285     { 0x3141, 0x00 },
0286     { 0x3f0d, 0x0a },
0287     { 0x3f14, 0x01 },
0288     { 0x3f3c, 0x01 },
0289     { 0x3f4d, 0x01 },
0290     { 0x3f4c, 0x01 },
0291     { 0x4254, 0x7f },
0292     { 0x0401, 0x00 },
0293     { 0x0404, 0x00 },
0294     { 0x0405, 0x10 },
0295     { 0x0408, 0x00 },
0296     { 0x0409, 0x08 },
0297     { 0x040a, 0x00 },
0298     { 0x040b, 0x08 },
0299     { 0x040c, 0x0c },
0300     { 0x040d, 0xc0 },
0301     { 0x040e, 0x09 },
0302     { 0x040f, 0x90 },
0303     { 0x034c, 0x0c },
0304     { 0x034d, 0xc0 },
0305     { 0x034e, 0x09 },
0306     { 0x034f, 0x90 },
0307     { 0x3261, 0x00 },
0308     { 0x3264, 0x00 },
0309     { 0x3265, 0x10 },
0310     { 0x0301, 0x05 },
0311     { 0x0303, 0x04 },
0312     { 0x0305, 0x04 },
0313     { 0x0306, 0x01 },
0314     { 0x0307, 0x92 },
0315     { 0x0309, 0x0a },
0316     { 0x030b, 0x02 },
0317     { 0x030d, 0x02 },
0318     { 0x030e, 0x00 },
0319     { 0x030f, 0xfa },
0320     { 0x0310, 0x00 },
0321     { 0x0820, 0x0f },
0322     { 0x0821, 0x13 },
0323     { 0x0822, 0x33 },
0324     { 0x0823, 0x33 },
0325     { 0x3e20, 0x01 },
0326     { 0x3e37, 0x00 },
0327     { 0x3e3b, 0x01 },
0328     { 0x38a3, 0x01 },
0329     { 0x38a8, 0x00 },
0330     { 0x38a9, 0x00 },
0331     { 0x38aa, 0x00 },
0332     { 0x38ab, 0x00 },
0333     { 0x3234, 0x00 },
0334     { 0x3fc1, 0x00 },
0335     { 0x3235, 0x00 },
0336     { 0x3802, 0x00 },
0337     { 0x3143, 0x04 },
0338     { 0x360a, 0x00 },
0339     { 0x0b00, 0x00 },
0340     { 0x0106, 0x00 },
0341     { 0x0b05, 0x01 },
0342     { 0x0b06, 0x01 },
0343     { 0x3230, 0x00 },
0344     { 0x3602, 0x01 },
0345     { 0x3607, 0x01 },
0346     { 0x3c00, 0x00 },
0347     { 0x3c01, 0x48 },
0348     { 0x3c02, 0xc8 },
0349     { 0x3c03, 0xaa },
0350     { 0x3c04, 0x91 },
0351     { 0x3c05, 0x54 },
0352     { 0x3c06, 0x26 },
0353     { 0x3c07, 0x20 },
0354     { 0x3c08, 0x51 },
0355     { 0x3d80, 0x00 },
0356     { 0x3f50, 0x00 },
0357     { 0x3f56, 0x00 },
0358     { 0x3f57, 0x30 },
0359     { 0x3f78, 0x01 },
0360     { 0x3f79, 0x18 },
0361     { 0x3f7c, 0x00 },
0362     { 0x3f7d, 0x00 },
0363     { 0x3fba, 0x00 },
0364     { 0x3fbb, 0x00 },
0365     { 0xa081, 0x00 },
0366     { 0xe014, 0x00 },
0367     { 0x0202, 0x0a },
0368     { 0x0203, 0x7a },
0369     { 0x0224, 0x01 },
0370     { 0x0225, 0xf4 },
0371     { 0x0204, 0x00 },
0372     { 0x0205, 0x00 },
0373     { 0x0216, 0x00 },
0374     { 0x0217, 0x00 },
0375     { 0x020e, 0x01 },
0376     { 0x020f, 0x00 },
0377     { 0x0210, 0x01 },
0378     { 0x0211, 0x00 },
0379     { 0x0212, 0x01 },
0380     { 0x0213, 0x00 },
0381     { 0x0214, 0x01 },
0382     { 0x0215, 0x00 },
0383     { 0x0218, 0x01 },
0384     { 0x0219, 0x00 },
0385     { 0x3614, 0x00 },
0386     { 0x3616, 0x0d },
0387     { 0x3617, 0x56 },
0388     { 0xb612, 0x20 },
0389     { 0xb613, 0x20 },
0390     { 0xb614, 0x20 },
0391     { 0xb615, 0x20 },
0392     { 0xb616, 0x0a },
0393     { 0xb617, 0x0a },
0394     { 0xb618, 0x20 },
0395     { 0xb619, 0x20 },
0396     { 0xb61a, 0x20 },
0397     { 0xb61b, 0x20 },
0398     { 0xb61c, 0x0a },
0399     { 0xb61d, 0x0a },
0400     { 0xb666, 0x30 },
0401     { 0xb667, 0x30 },
0402     { 0xb668, 0x30 },
0403     { 0xb669, 0x30 },
0404     { 0xb66a, 0x14 },
0405     { 0xb66b, 0x14 },
0406     { 0xb66c, 0x20 },
0407     { 0xb66d, 0x20 },
0408     { 0xb66e, 0x20 },
0409     { 0xb66f, 0x20 },
0410     { 0xb670, 0x10 },
0411     { 0xb671, 0x10 },
0412     { 0x3237, 0x00 },
0413     { 0x3900, 0x00 },
0414     { 0x3901, 0x00 },
0415     { 0x3902, 0x00 },
0416     { 0x3904, 0x00 },
0417     { 0x3905, 0x00 },
0418     { 0x3906, 0x00 },
0419     { 0x3907, 0x00 },
0420     { 0x3908, 0x00 },
0421     { 0x3909, 0x00 },
0422     { 0x3912, 0x00 },
0423     { 0x3930, 0x00 },
0424     { 0x3931, 0x00 },
0425     { 0x3933, 0x00 },
0426     { 0x3934, 0x00 },
0427     { 0x3935, 0x00 },
0428     { 0x3936, 0x00 },
0429     { 0x3937, 0x00 },
0430     { 0x30ac, 0x00 },
0431 };
0432 
0433 static const struct imx319_reg mode_3280x2464_regs[] = {
0434     { 0x0112, 0x0a },
0435     { 0x0113, 0x0a },
0436     { 0x0114, 0x03 },
0437     { 0x0342, 0x0f },
0438     { 0x0343, 0x80 },
0439     { 0x0340, 0x0c },
0440     { 0x0341, 0xaa },
0441     { 0x0344, 0x00 },
0442     { 0x0345, 0x00 },
0443     { 0x0346, 0x00 },
0444     { 0x0347, 0x00 },
0445     { 0x0348, 0x0c },
0446     { 0x0349, 0xcf },
0447     { 0x034a, 0x09 },
0448     { 0x034b, 0x9f },
0449     { 0x0220, 0x00 },
0450     { 0x0221, 0x11 },
0451     { 0x0381, 0x01 },
0452     { 0x0383, 0x01 },
0453     { 0x0385, 0x01 },
0454     { 0x0387, 0x01 },
0455     { 0x0900, 0x00 },
0456     { 0x0901, 0x11 },
0457     { 0x0902, 0x0a },
0458     { 0x3140, 0x02 },
0459     { 0x3141, 0x00 },
0460     { 0x3f0d, 0x0a },
0461     { 0x3f14, 0x01 },
0462     { 0x3f3c, 0x01 },
0463     { 0x3f4d, 0x01 },
0464     { 0x3f4c, 0x01 },
0465     { 0x4254, 0x7f },
0466     { 0x0401, 0x00 },
0467     { 0x0404, 0x00 },
0468     { 0x0405, 0x10 },
0469     { 0x0408, 0x00 },
0470     { 0x0409, 0x00 },
0471     { 0x040a, 0x00 },
0472     { 0x040b, 0x00 },
0473     { 0x040c, 0x0c },
0474     { 0x040d, 0xd0 },
0475     { 0x040e, 0x09 },
0476     { 0x040f, 0xa0 },
0477     { 0x034c, 0x0c },
0478     { 0x034d, 0xd0 },
0479     { 0x034e, 0x09 },
0480     { 0x034f, 0xa0 },
0481     { 0x3261, 0x00 },
0482     { 0x3264, 0x00 },
0483     { 0x3265, 0x10 },
0484     { 0x0301, 0x05 },
0485     { 0x0303, 0x04 },
0486     { 0x0305, 0x04 },
0487     { 0x0306, 0x01 },
0488     { 0x0307, 0x92 },
0489     { 0x0309, 0x0a },
0490     { 0x030b, 0x02 },
0491     { 0x030d, 0x02 },
0492     { 0x030e, 0x00 },
0493     { 0x030f, 0xfa },
0494     { 0x0310, 0x00 },
0495     { 0x0820, 0x0f },
0496     { 0x0821, 0x13 },
0497     { 0x0822, 0x33 },
0498     { 0x0823, 0x33 },
0499     { 0x3e20, 0x01 },
0500     { 0x3e37, 0x00 },
0501     { 0x3e3b, 0x01 },
0502     { 0x38a3, 0x01 },
0503     { 0x38a8, 0x00 },
0504     { 0x38a9, 0x00 },
0505     { 0x38aa, 0x00 },
0506     { 0x38ab, 0x00 },
0507     { 0x3234, 0x00 },
0508     { 0x3fc1, 0x00 },
0509     { 0x3235, 0x00 },
0510     { 0x3802, 0x00 },
0511     { 0x3143, 0x04 },
0512     { 0x360a, 0x00 },
0513     { 0x0b00, 0x00 },
0514     { 0x0106, 0x00 },
0515     { 0x0b05, 0x01 },
0516     { 0x0b06, 0x01 },
0517     { 0x3230, 0x00 },
0518     { 0x3602, 0x01 },
0519     { 0x3607, 0x01 },
0520     { 0x3c00, 0x00 },
0521     { 0x3c01, 0x48 },
0522     { 0x3c02, 0xc8 },
0523     { 0x3c03, 0xaa },
0524     { 0x3c04, 0x91 },
0525     { 0x3c05, 0x54 },
0526     { 0x3c06, 0x26 },
0527     { 0x3c07, 0x20 },
0528     { 0x3c08, 0x51 },
0529     { 0x3d80, 0x00 },
0530     { 0x3f50, 0x00 },
0531     { 0x3f56, 0x00 },
0532     { 0x3f57, 0x30 },
0533     { 0x3f78, 0x01 },
0534     { 0x3f79, 0x18 },
0535     { 0x3f7c, 0x00 },
0536     { 0x3f7d, 0x00 },
0537     { 0x3fba, 0x00 },
0538     { 0x3fbb, 0x00 },
0539     { 0xa081, 0x00 },
0540     { 0xe014, 0x00 },
0541     { 0x0202, 0x0a },
0542     { 0x0203, 0x7a },
0543     { 0x0224, 0x01 },
0544     { 0x0225, 0xf4 },
0545     { 0x0204, 0x00 },
0546     { 0x0205, 0x00 },
0547     { 0x0216, 0x00 },
0548     { 0x0217, 0x00 },
0549     { 0x020e, 0x01 },
0550     { 0x020f, 0x00 },
0551     { 0x0210, 0x01 },
0552     { 0x0211, 0x00 },
0553     { 0x0212, 0x01 },
0554     { 0x0213, 0x00 },
0555     { 0x0214, 0x01 },
0556     { 0x0215, 0x00 },
0557     { 0x0218, 0x01 },
0558     { 0x0219, 0x00 },
0559     { 0x3614, 0x00 },
0560     { 0x3616, 0x0d },
0561     { 0x3617, 0x56 },
0562     { 0xb612, 0x20 },
0563     { 0xb613, 0x20 },
0564     { 0xb614, 0x20 },
0565     { 0xb615, 0x20 },
0566     { 0xb616, 0x0a },
0567     { 0xb617, 0x0a },
0568     { 0xb618, 0x20 },
0569     { 0xb619, 0x20 },
0570     { 0xb61a, 0x20 },
0571     { 0xb61b, 0x20 },
0572     { 0xb61c, 0x0a },
0573     { 0xb61d, 0x0a },
0574     { 0xb666, 0x30 },
0575     { 0xb667, 0x30 },
0576     { 0xb668, 0x30 },
0577     { 0xb669, 0x30 },
0578     { 0xb66a, 0x14 },
0579     { 0xb66b, 0x14 },
0580     { 0xb66c, 0x20 },
0581     { 0xb66d, 0x20 },
0582     { 0xb66e, 0x20 },
0583     { 0xb66f, 0x20 },
0584     { 0xb670, 0x10 },
0585     { 0xb671, 0x10 },
0586     { 0x3237, 0x00 },
0587     { 0x3900, 0x00 },
0588     { 0x3901, 0x00 },
0589     { 0x3902, 0x00 },
0590     { 0x3904, 0x00 },
0591     { 0x3905, 0x00 },
0592     { 0x3906, 0x00 },
0593     { 0x3907, 0x00 },
0594     { 0x3908, 0x00 },
0595     { 0x3909, 0x00 },
0596     { 0x3912, 0x00 },
0597     { 0x3930, 0x00 },
0598     { 0x3931, 0x00 },
0599     { 0x3933, 0x00 },
0600     { 0x3934, 0x00 },
0601     { 0x3935, 0x00 },
0602     { 0x3936, 0x00 },
0603     { 0x3937, 0x00 },
0604     { 0x30ac, 0x00 },
0605 };
0606 
0607 static const struct imx319_reg mode_1936x1096_regs[] = {
0608     { 0x0112, 0x0a },
0609     { 0x0113, 0x0a },
0610     { 0x0114, 0x03 },
0611     { 0x0342, 0x0f },
0612     { 0x0343, 0x80 },
0613     { 0x0340, 0x0c },
0614     { 0x0341, 0xaa },
0615     { 0x0344, 0x00 },
0616     { 0x0345, 0x00 },
0617     { 0x0346, 0x02 },
0618     { 0x0347, 0xac },
0619     { 0x0348, 0x0c },
0620     { 0x0349, 0xcf },
0621     { 0x034a, 0x06 },
0622     { 0x034b, 0xf3 },
0623     { 0x0220, 0x00 },
0624     { 0x0221, 0x11 },
0625     { 0x0381, 0x01 },
0626     { 0x0383, 0x01 },
0627     { 0x0385, 0x01 },
0628     { 0x0387, 0x01 },
0629     { 0x0900, 0x00 },
0630     { 0x0901, 0x11 },
0631     { 0x0902, 0x0a },
0632     { 0x3140, 0x02 },
0633     { 0x3141, 0x00 },
0634     { 0x3f0d, 0x0a },
0635     { 0x3f14, 0x01 },
0636     { 0x3f3c, 0x01 },
0637     { 0x3f4d, 0x01 },
0638     { 0x3f4c, 0x01 },
0639     { 0x4254, 0x7f },
0640     { 0x0401, 0x00 },
0641     { 0x0404, 0x00 },
0642     { 0x0405, 0x10 },
0643     { 0x0408, 0x02 },
0644     { 0x0409, 0xa0 },
0645     { 0x040a, 0x00 },
0646     { 0x040b, 0x00 },
0647     { 0x040c, 0x07 },
0648     { 0x040d, 0x90 },
0649     { 0x040e, 0x04 },
0650     { 0x040f, 0x48 },
0651     { 0x034c, 0x07 },
0652     { 0x034d, 0x90 },
0653     { 0x034e, 0x04 },
0654     { 0x034f, 0x48 },
0655     { 0x3261, 0x00 },
0656     { 0x3264, 0x00 },
0657     { 0x3265, 0x10 },
0658     { 0x0301, 0x05 },
0659     { 0x0303, 0x04 },
0660     { 0x0305, 0x04 },
0661     { 0x0306, 0x01 },
0662     { 0x0307, 0x92 },
0663     { 0x0309, 0x0a },
0664     { 0x030b, 0x02 },
0665     { 0x030d, 0x02 },
0666     { 0x030e, 0x00 },
0667     { 0x030f, 0xfa },
0668     { 0x0310, 0x00 },
0669     { 0x0820, 0x0f },
0670     { 0x0821, 0x13 },
0671     { 0x0822, 0x33 },
0672     { 0x0823, 0x33 },
0673     { 0x3e20, 0x01 },
0674     { 0x3e37, 0x00 },
0675     { 0x3e3b, 0x01 },
0676     { 0x38a3, 0x01 },
0677     { 0x38a8, 0x00 },
0678     { 0x38a9, 0x00 },
0679     { 0x38aa, 0x00 },
0680     { 0x38ab, 0x00 },
0681     { 0x3234, 0x00 },
0682     { 0x3fc1, 0x00 },
0683     { 0x3235, 0x00 },
0684     { 0x3802, 0x00 },
0685     { 0x3143, 0x04 },
0686     { 0x360a, 0x00 },
0687     { 0x0b00, 0x00 },
0688     { 0x0106, 0x00 },
0689     { 0x0b05, 0x01 },
0690     { 0x0b06, 0x01 },
0691     { 0x3230, 0x00 },
0692     { 0x3602, 0x01 },
0693     { 0x3607, 0x01 },
0694     { 0x3c00, 0x00 },
0695     { 0x3c01, 0x48 },
0696     { 0x3c02, 0xc8 },
0697     { 0x3c03, 0xaa },
0698     { 0x3c04, 0x91 },
0699     { 0x3c05, 0x54 },
0700     { 0x3c06, 0x26 },
0701     { 0x3c07, 0x20 },
0702     { 0x3c08, 0x51 },
0703     { 0x3d80, 0x00 },
0704     { 0x3f50, 0x00 },
0705     { 0x3f56, 0x00 },
0706     { 0x3f57, 0x30 },
0707     { 0x3f78, 0x01 },
0708     { 0x3f79, 0x18 },
0709     { 0x3f7c, 0x00 },
0710     { 0x3f7d, 0x00 },
0711     { 0x3fba, 0x00 },
0712     { 0x3fbb, 0x00 },
0713     { 0xa081, 0x00 },
0714     { 0xe014, 0x00 },
0715     { 0x0202, 0x05 },
0716     { 0x0203, 0x34 },
0717     { 0x0224, 0x01 },
0718     { 0x0225, 0xf4 },
0719     { 0x0204, 0x00 },
0720     { 0x0205, 0x00 },
0721     { 0x0216, 0x00 },
0722     { 0x0217, 0x00 },
0723     { 0x020e, 0x01 },
0724     { 0x020f, 0x00 },
0725     { 0x0210, 0x01 },
0726     { 0x0211, 0x00 },
0727     { 0x0212, 0x01 },
0728     { 0x0213, 0x00 },
0729     { 0x0214, 0x01 },
0730     { 0x0215, 0x00 },
0731     { 0x0218, 0x01 },
0732     { 0x0219, 0x00 },
0733     { 0x3614, 0x00 },
0734     { 0x3616, 0x0d },
0735     { 0x3617, 0x56 },
0736     { 0xb612, 0x20 },
0737     { 0xb613, 0x20 },
0738     { 0xb614, 0x20 },
0739     { 0xb615, 0x20 },
0740     { 0xb616, 0x0a },
0741     { 0xb617, 0x0a },
0742     { 0xb618, 0x20 },
0743     { 0xb619, 0x20 },
0744     { 0xb61a, 0x20 },
0745     { 0xb61b, 0x20 },
0746     { 0xb61c, 0x0a },
0747     { 0xb61d, 0x0a },
0748     { 0xb666, 0x30 },
0749     { 0xb667, 0x30 },
0750     { 0xb668, 0x30 },
0751     { 0xb669, 0x30 },
0752     { 0xb66a, 0x14 },
0753     { 0xb66b, 0x14 },
0754     { 0xb66c, 0x20 },
0755     { 0xb66d, 0x20 },
0756     { 0xb66e, 0x20 },
0757     { 0xb66f, 0x20 },
0758     { 0xb670, 0x10 },
0759     { 0xb671, 0x10 },
0760     { 0x3237, 0x00 },
0761     { 0x3900, 0x00 },
0762     { 0x3901, 0x00 },
0763     { 0x3902, 0x00 },
0764     { 0x3904, 0x00 },
0765     { 0x3905, 0x00 },
0766     { 0x3906, 0x00 },
0767     { 0x3907, 0x00 },
0768     { 0x3908, 0x00 },
0769     { 0x3909, 0x00 },
0770     { 0x3912, 0x00 },
0771     { 0x3930, 0x00 },
0772     { 0x3931, 0x00 },
0773     { 0x3933, 0x00 },
0774     { 0x3934, 0x00 },
0775     { 0x3935, 0x00 },
0776     { 0x3936, 0x00 },
0777     { 0x3937, 0x00 },
0778     { 0x30ac, 0x00 },
0779 };
0780 
0781 static const struct imx319_reg mode_1920x1080_regs[] = {
0782     { 0x0112, 0x0a },
0783     { 0x0113, 0x0a },
0784     { 0x0114, 0x03 },
0785     { 0x0342, 0x0f },
0786     { 0x0343, 0x80 },
0787     { 0x0340, 0x0c },
0788     { 0x0341, 0xaa },
0789     { 0x0344, 0x00 },
0790     { 0x0345, 0x00 },
0791     { 0x0346, 0x02 },
0792     { 0x0347, 0xb4 },
0793     { 0x0348, 0x0c },
0794     { 0x0349, 0xcf },
0795     { 0x034a, 0x06 },
0796     { 0x034b, 0xeb },
0797     { 0x0220, 0x00 },
0798     { 0x0221, 0x11 },
0799     { 0x0381, 0x01 },
0800     { 0x0383, 0x01 },
0801     { 0x0385, 0x01 },
0802     { 0x0387, 0x01 },
0803     { 0x0900, 0x00 },
0804     { 0x0901, 0x11 },
0805     { 0x0902, 0x0a },
0806     { 0x3140, 0x02 },
0807     { 0x3141, 0x00 },
0808     { 0x3f0d, 0x0a },
0809     { 0x3f14, 0x01 },
0810     { 0x3f3c, 0x01 },
0811     { 0x3f4d, 0x01 },
0812     { 0x3f4c, 0x01 },
0813     { 0x4254, 0x7f },
0814     { 0x0401, 0x00 },
0815     { 0x0404, 0x00 },
0816     { 0x0405, 0x10 },
0817     { 0x0408, 0x02 },
0818     { 0x0409, 0xa8 },
0819     { 0x040a, 0x00 },
0820     { 0x040b, 0x00 },
0821     { 0x040c, 0x07 },
0822     { 0x040d, 0x80 },
0823     { 0x040e, 0x04 },
0824     { 0x040f, 0x38 },
0825     { 0x034c, 0x07 },
0826     { 0x034d, 0x80 },
0827     { 0x034e, 0x04 },
0828     { 0x034f, 0x38 },
0829     { 0x3261, 0x00 },
0830     { 0x3264, 0x00 },
0831     { 0x3265, 0x10 },
0832     { 0x0301, 0x05 },
0833     { 0x0303, 0x04 },
0834     { 0x0305, 0x04 },
0835     { 0x0306, 0x01 },
0836     { 0x0307, 0x92 },
0837     { 0x0309, 0x0a },
0838     { 0x030b, 0x02 },
0839     { 0x030d, 0x02 },
0840     { 0x030e, 0x00 },
0841     { 0x030f, 0xfa },
0842     { 0x0310, 0x00 },
0843     { 0x0820, 0x0f },
0844     { 0x0821, 0x13 },
0845     { 0x0822, 0x33 },
0846     { 0x0823, 0x33 },
0847     { 0x3e20, 0x01 },
0848     { 0x3e37, 0x00 },
0849     { 0x3e3b, 0x01 },
0850     { 0x38a3, 0x01 },
0851     { 0x38a8, 0x00 },
0852     { 0x38a9, 0x00 },
0853     { 0x38aa, 0x00 },
0854     { 0x38ab, 0x00 },
0855     { 0x3234, 0x00 },
0856     { 0x3fc1, 0x00 },
0857     { 0x3235, 0x00 },
0858     { 0x3802, 0x00 },
0859     { 0x3143, 0x04 },
0860     { 0x360a, 0x00 },
0861     { 0x0b00, 0x00 },
0862     { 0x0106, 0x00 },
0863     { 0x0b05, 0x01 },
0864     { 0x0b06, 0x01 },
0865     { 0x3230, 0x00 },
0866     { 0x3602, 0x01 },
0867     { 0x3607, 0x01 },
0868     { 0x3c00, 0x00 },
0869     { 0x3c01, 0x48 },
0870     { 0x3c02, 0xc8 },
0871     { 0x3c03, 0xaa },
0872     { 0x3c04, 0x91 },
0873     { 0x3c05, 0x54 },
0874     { 0x3c06, 0x26 },
0875     { 0x3c07, 0x20 },
0876     { 0x3c08, 0x51 },
0877     { 0x3d80, 0x00 },
0878     { 0x3f50, 0x00 },
0879     { 0x3f56, 0x00 },
0880     { 0x3f57, 0x30 },
0881     { 0x3f78, 0x01 },
0882     { 0x3f79, 0x18 },
0883     { 0x3f7c, 0x00 },
0884     { 0x3f7d, 0x00 },
0885     { 0x3fba, 0x00 },
0886     { 0x3fbb, 0x00 },
0887     { 0xa081, 0x00 },
0888     { 0xe014, 0x00 },
0889     { 0x0202, 0x05 },
0890     { 0x0203, 0x34 },
0891     { 0x0224, 0x01 },
0892     { 0x0225, 0xf4 },
0893     { 0x0204, 0x00 },
0894     { 0x0205, 0x00 },
0895     { 0x0216, 0x00 },
0896     { 0x0217, 0x00 },
0897     { 0x020e, 0x01 },
0898     { 0x020f, 0x00 },
0899     { 0x0210, 0x01 },
0900     { 0x0211, 0x00 },
0901     { 0x0212, 0x01 },
0902     { 0x0213, 0x00 },
0903     { 0x0214, 0x01 },
0904     { 0x0215, 0x00 },
0905     { 0x0218, 0x01 },
0906     { 0x0219, 0x00 },
0907     { 0x3614, 0x00 },
0908     { 0x3616, 0x0d },
0909     { 0x3617, 0x56 },
0910     { 0xb612, 0x20 },
0911     { 0xb613, 0x20 },
0912     { 0xb614, 0x20 },
0913     { 0xb615, 0x20 },
0914     { 0xb616, 0x0a },
0915     { 0xb617, 0x0a },
0916     { 0xb618, 0x20 },
0917     { 0xb619, 0x20 },
0918     { 0xb61a, 0x20 },
0919     { 0xb61b, 0x20 },
0920     { 0xb61c, 0x0a },
0921     { 0xb61d, 0x0a },
0922     { 0xb666, 0x30 },
0923     { 0xb667, 0x30 },
0924     { 0xb668, 0x30 },
0925     { 0xb669, 0x30 },
0926     { 0xb66a, 0x14 },
0927     { 0xb66b, 0x14 },
0928     { 0xb66c, 0x20 },
0929     { 0xb66d, 0x20 },
0930     { 0xb66e, 0x20 },
0931     { 0xb66f, 0x20 },
0932     { 0xb670, 0x10 },
0933     { 0xb671, 0x10 },
0934     { 0x3237, 0x00 },
0935     { 0x3900, 0x00 },
0936     { 0x3901, 0x00 },
0937     { 0x3902, 0x00 },
0938     { 0x3904, 0x00 },
0939     { 0x3905, 0x00 },
0940     { 0x3906, 0x00 },
0941     { 0x3907, 0x00 },
0942     { 0x3908, 0x00 },
0943     { 0x3909, 0x00 },
0944     { 0x3912, 0x00 },
0945     { 0x3930, 0x00 },
0946     { 0x3931, 0x00 },
0947     { 0x3933, 0x00 },
0948     { 0x3934, 0x00 },
0949     { 0x3935, 0x00 },
0950     { 0x3936, 0x00 },
0951     { 0x3937, 0x00 },
0952     { 0x30ac, 0x00 },
0953 };
0954 
0955 static const struct imx319_reg mode_1640x1232_regs[] = {
0956     { 0x0112, 0x0a },
0957     { 0x0113, 0x0a },
0958     { 0x0114, 0x03 },
0959     { 0x0342, 0x08 },
0960     { 0x0343, 0x20 },
0961     { 0x0340, 0x18 },
0962     { 0x0341, 0x2a },
0963     { 0x0344, 0x00 },
0964     { 0x0345, 0x00 },
0965     { 0x0346, 0x00 },
0966     { 0x0347, 0x00 },
0967     { 0x0348, 0x0c },
0968     { 0x0349, 0xcf },
0969     { 0x034a, 0x09 },
0970     { 0x034b, 0x9f },
0971     { 0x0220, 0x00 },
0972     { 0x0221, 0x11 },
0973     { 0x0381, 0x01 },
0974     { 0x0383, 0x01 },
0975     { 0x0385, 0x01 },
0976     { 0x0387, 0x01 },
0977     { 0x0900, 0x01 },
0978     { 0x0901, 0x22 },
0979     { 0x0902, 0x0a },
0980     { 0x3140, 0x02 },
0981     { 0x3141, 0x00 },
0982     { 0x3f0d, 0x0a },
0983     { 0x3f14, 0x01 },
0984     { 0x3f3c, 0x02 },
0985     { 0x3f4d, 0x01 },
0986     { 0x3f4c, 0x01 },
0987     { 0x4254, 0x7f },
0988     { 0x0401, 0x00 },
0989     { 0x0404, 0x00 },
0990     { 0x0405, 0x10 },
0991     { 0x0408, 0x00 },
0992     { 0x0409, 0x00 },
0993     { 0x040a, 0x00 },
0994     { 0x040b, 0x00 },
0995     { 0x040c, 0x06 },
0996     { 0x040d, 0x68 },
0997     { 0x040e, 0x04 },
0998     { 0x040f, 0xd0 },
0999     { 0x034c, 0x06 },
1000     { 0x034d, 0x68 },
1001     { 0x034e, 0x04 },
1002     { 0x034f, 0xd0 },
1003     { 0x3261, 0x00 },
1004     { 0x3264, 0x00 },
1005     { 0x3265, 0x10 },
1006     { 0x0301, 0x05 },
1007     { 0x0303, 0x04 },
1008     { 0x0305, 0x04 },
1009     { 0x0306, 0x01 },
1010     { 0x0307, 0x92 },
1011     { 0x0309, 0x0a },
1012     { 0x030b, 0x02 },
1013     { 0x030d, 0x02 },
1014     { 0x030e, 0x00 },
1015     { 0x030f, 0xfa },
1016     { 0x0310, 0x00 },
1017     { 0x0820, 0x0f },
1018     { 0x0821, 0x13 },
1019     { 0x0822, 0x33 },
1020     { 0x0823, 0x33 },
1021     { 0x3e20, 0x01 },
1022     { 0x3e37, 0x00 },
1023     { 0x3e3b, 0x01 },
1024     { 0x38a3, 0x01 },
1025     { 0x38a8, 0x00 },
1026     { 0x38a9, 0x00 },
1027     { 0x38aa, 0x00 },
1028     { 0x38ab, 0x00 },
1029     { 0x3234, 0x00 },
1030     { 0x3fc1, 0x00 },
1031     { 0x3235, 0x00 },
1032     { 0x3802, 0x00 },
1033     { 0x3143, 0x04 },
1034     { 0x360a, 0x00 },
1035     { 0x0b00, 0x00 },
1036     { 0x0106, 0x00 },
1037     { 0x0b05, 0x01 },
1038     { 0x0b06, 0x01 },
1039     { 0x3230, 0x00 },
1040     { 0x3602, 0x01 },
1041     { 0x3607, 0x01 },
1042     { 0x3c00, 0x00 },
1043     { 0x3c01, 0xba },
1044     { 0x3c02, 0xc8 },
1045     { 0x3c03, 0xaa },
1046     { 0x3c04, 0x91 },
1047     { 0x3c05, 0x54 },
1048     { 0x3c06, 0x26 },
1049     { 0x3c07, 0x20 },
1050     { 0x3c08, 0x51 },
1051     { 0x3d80, 0x00 },
1052     { 0x3f50, 0x00 },
1053     { 0x3f56, 0x00 },
1054     { 0x3f57, 0x30 },
1055     { 0x3f78, 0x00 },
1056     { 0x3f79, 0x34 },
1057     { 0x3f7c, 0x00 },
1058     { 0x3f7d, 0x00 },
1059     { 0x3fba, 0x00 },
1060     { 0x3fbb, 0x00 },
1061     { 0xa081, 0x04 },
1062     { 0xe014, 0x00 },
1063     { 0x0202, 0x04 },
1064     { 0x0203, 0xf6 },
1065     { 0x0224, 0x01 },
1066     { 0x0225, 0xf4 },
1067     { 0x0204, 0x00 },
1068     { 0x0205, 0x00 },
1069     { 0x0216, 0x00 },
1070     { 0x0217, 0x00 },
1071     { 0x020e, 0x01 },
1072     { 0x020f, 0x00 },
1073     { 0x0210, 0x01 },
1074     { 0x0211, 0x00 },
1075     { 0x0212, 0x01 },
1076     { 0x0213, 0x00 },
1077     { 0x0214, 0x01 },
1078     { 0x0215, 0x00 },
1079     { 0x0218, 0x01 },
1080     { 0x0219, 0x00 },
1081     { 0x3614, 0x00 },
1082     { 0x3616, 0x0d },
1083     { 0x3617, 0x56 },
1084     { 0xb612, 0x20 },
1085     { 0xb613, 0x20 },
1086     { 0xb614, 0x20 },
1087     { 0xb615, 0x20 },
1088     { 0xb616, 0x0a },
1089     { 0xb617, 0x0a },
1090     { 0xb618, 0x20 },
1091     { 0xb619, 0x20 },
1092     { 0xb61a, 0x20 },
1093     { 0xb61b, 0x20 },
1094     { 0xb61c, 0x0a },
1095     { 0xb61d, 0x0a },
1096     { 0xb666, 0x30 },
1097     { 0xb667, 0x30 },
1098     { 0xb668, 0x30 },
1099     { 0xb669, 0x30 },
1100     { 0xb66a, 0x14 },
1101     { 0xb66b, 0x14 },
1102     { 0xb66c, 0x20 },
1103     { 0xb66d, 0x20 },
1104     { 0xb66e, 0x20 },
1105     { 0xb66f, 0x20 },
1106     { 0xb670, 0x10 },
1107     { 0xb671, 0x10 },
1108     { 0x3237, 0x00 },
1109     { 0x3900, 0x00 },
1110     { 0x3901, 0x00 },
1111     { 0x3902, 0x00 },
1112     { 0x3904, 0x00 },
1113     { 0x3905, 0x00 },
1114     { 0x3906, 0x00 },
1115     { 0x3907, 0x00 },
1116     { 0x3908, 0x00 },
1117     { 0x3909, 0x00 },
1118     { 0x3912, 0x00 },
1119     { 0x3930, 0x00 },
1120     { 0x3931, 0x00 },
1121     { 0x3933, 0x00 },
1122     { 0x3934, 0x00 },
1123     { 0x3935, 0x00 },
1124     { 0x3936, 0x00 },
1125     { 0x3937, 0x00 },
1126     { 0x30ac, 0x00 },
1127 };
1128 
1129 static const struct imx319_reg mode_1640x922_regs[] = {
1130     { 0x0112, 0x0a },
1131     { 0x0113, 0x0a },
1132     { 0x0114, 0x03 },
1133     { 0x0342, 0x08 },
1134     { 0x0343, 0x20 },
1135     { 0x0340, 0x18 },
1136     { 0x0341, 0x2a },
1137     { 0x0344, 0x00 },
1138     { 0x0345, 0x00 },
1139     { 0x0346, 0x01 },
1140     { 0x0347, 0x30 },
1141     { 0x0348, 0x0c },
1142     { 0x0349, 0xcf },
1143     { 0x034a, 0x08 },
1144     { 0x034b, 0x6f },
1145     { 0x0220, 0x00 },
1146     { 0x0221, 0x11 },
1147     { 0x0381, 0x01 },
1148     { 0x0383, 0x01 },
1149     { 0x0385, 0x01 },
1150     { 0x0387, 0x01 },
1151     { 0x0900, 0x01 },
1152     { 0x0901, 0x22 },
1153     { 0x0902, 0x0a },
1154     { 0x3140, 0x02 },
1155     { 0x3141, 0x00 },
1156     { 0x3f0d, 0x0a },
1157     { 0x3f14, 0x01 },
1158     { 0x3f3c, 0x02 },
1159     { 0x3f4d, 0x01 },
1160     { 0x3f4c, 0x01 },
1161     { 0x4254, 0x7f },
1162     { 0x0401, 0x00 },
1163     { 0x0404, 0x00 },
1164     { 0x0405, 0x10 },
1165     { 0x0408, 0x00 },
1166     { 0x0409, 0x00 },
1167     { 0x040a, 0x00 },
1168     { 0x040b, 0x02 },
1169     { 0x040c, 0x06 },
1170     { 0x040d, 0x68 },
1171     { 0x040e, 0x03 },
1172     { 0x040f, 0x9a },
1173     { 0x034c, 0x06 },
1174     { 0x034d, 0x68 },
1175     { 0x034e, 0x03 },
1176     { 0x034f, 0x9a },
1177     { 0x3261, 0x00 },
1178     { 0x3264, 0x00 },
1179     { 0x3265, 0x10 },
1180     { 0x0301, 0x05 },
1181     { 0x0303, 0x04 },
1182     { 0x0305, 0x04 },
1183     { 0x0306, 0x01 },
1184     { 0x0307, 0x92 },
1185     { 0x0309, 0x0a },
1186     { 0x030b, 0x02 },
1187     { 0x030d, 0x02 },
1188     { 0x030e, 0x00 },
1189     { 0x030f, 0xfa },
1190     { 0x0310, 0x00 },
1191     { 0x0820, 0x0f },
1192     { 0x0821, 0x13 },
1193     { 0x0822, 0x33 },
1194     { 0x0823, 0x33 },
1195     { 0x3e20, 0x01 },
1196     { 0x3e37, 0x00 },
1197     { 0x3e3b, 0x01 },
1198     { 0x38a3, 0x01 },
1199     { 0x38a8, 0x00 },
1200     { 0x38a9, 0x00 },
1201     { 0x38aa, 0x00 },
1202     { 0x38ab, 0x00 },
1203     { 0x3234, 0x00 },
1204     { 0x3fc1, 0x00 },
1205     { 0x3235, 0x00 },
1206     { 0x3802, 0x00 },
1207     { 0x3143, 0x04 },
1208     { 0x360a, 0x00 },
1209     { 0x0b00, 0x00 },
1210     { 0x0106, 0x00 },
1211     { 0x0b05, 0x01 },
1212     { 0x0b06, 0x01 },
1213     { 0x3230, 0x00 },
1214     { 0x3602, 0x01 },
1215     { 0x3607, 0x01 },
1216     { 0x3c00, 0x00 },
1217     { 0x3c01, 0xba },
1218     { 0x3c02, 0xc8 },
1219     { 0x3c03, 0xaa },
1220     { 0x3c04, 0x91 },
1221     { 0x3c05, 0x54 },
1222     { 0x3c06, 0x26 },
1223     { 0x3c07, 0x20 },
1224     { 0x3c08, 0x51 },
1225     { 0x3d80, 0x00 },
1226     { 0x3f50, 0x00 },
1227     { 0x3f56, 0x00 },
1228     { 0x3f57, 0x30 },
1229     { 0x3f78, 0x00 },
1230     { 0x3f79, 0x34 },
1231     { 0x3f7c, 0x00 },
1232     { 0x3f7d, 0x00 },
1233     { 0x3fba, 0x00 },
1234     { 0x3fbb, 0x00 },
1235     { 0xa081, 0x04 },
1236     { 0xe014, 0x00 },
1237     { 0x0202, 0x04 },
1238     { 0x0203, 0xf6 },
1239     { 0x0224, 0x01 },
1240     { 0x0225, 0xf4 },
1241     { 0x0204, 0x00 },
1242     { 0x0205, 0x00 },
1243     { 0x0216, 0x00 },
1244     { 0x0217, 0x00 },
1245     { 0x020e, 0x01 },
1246     { 0x020f, 0x00 },
1247     { 0x0210, 0x01 },
1248     { 0x0211, 0x00 },
1249     { 0x0212, 0x01 },
1250     { 0x0213, 0x00 },
1251     { 0x0214, 0x01 },
1252     { 0x0215, 0x00 },
1253     { 0x0218, 0x01 },
1254     { 0x0219, 0x00 },
1255     { 0x3614, 0x00 },
1256     { 0x3616, 0x0d },
1257     { 0x3617, 0x56 },
1258     { 0xb612, 0x20 },
1259     { 0xb613, 0x20 },
1260     { 0xb614, 0x20 },
1261     { 0xb615, 0x20 },
1262     { 0xb616, 0x0a },
1263     { 0xb617, 0x0a },
1264     { 0xb618, 0x20 },
1265     { 0xb619, 0x20 },
1266     { 0xb61a, 0x20 },
1267     { 0xb61b, 0x20 },
1268     { 0xb61c, 0x0a },
1269     { 0xb61d, 0x0a },
1270     { 0xb666, 0x30 },
1271     { 0xb667, 0x30 },
1272     { 0xb668, 0x30 },
1273     { 0xb669, 0x30 },
1274     { 0xb66a, 0x14 },
1275     { 0xb66b, 0x14 },
1276     { 0xb66c, 0x20 },
1277     { 0xb66d, 0x20 },
1278     { 0xb66e, 0x20 },
1279     { 0xb66f, 0x20 },
1280     { 0xb670, 0x10 },
1281     { 0xb671, 0x10 },
1282     { 0x3237, 0x00 },
1283     { 0x3900, 0x00 },
1284     { 0x3901, 0x00 },
1285     { 0x3902, 0x00 },
1286     { 0x3904, 0x00 },
1287     { 0x3905, 0x00 },
1288     { 0x3906, 0x00 },
1289     { 0x3907, 0x00 },
1290     { 0x3908, 0x00 },
1291     { 0x3909, 0x00 },
1292     { 0x3912, 0x00 },
1293     { 0x3930, 0x00 },
1294     { 0x3931, 0x00 },
1295     { 0x3933, 0x00 },
1296     { 0x3934, 0x00 },
1297     { 0x3935, 0x00 },
1298     { 0x3936, 0x00 },
1299     { 0x3937, 0x00 },
1300     { 0x30ac, 0x00 },
1301 };
1302 
1303 static const struct imx319_reg mode_1296x736_regs[] = {
1304     { 0x0112, 0x0a },
1305     { 0x0113, 0x0a },
1306     { 0x0114, 0x03 },
1307     { 0x0342, 0x08 },
1308     { 0x0343, 0x20 },
1309     { 0x0340, 0x18 },
1310     { 0x0341, 0x2a },
1311     { 0x0344, 0x00 },
1312     { 0x0345, 0x00 },
1313     { 0x0346, 0x01 },
1314     { 0x0347, 0xf0 },
1315     { 0x0348, 0x0c },
1316     { 0x0349, 0xcf },
1317     { 0x034a, 0x07 },
1318     { 0x034b, 0xaf },
1319     { 0x0220, 0x00 },
1320     { 0x0221, 0x11 },
1321     { 0x0381, 0x01 },
1322     { 0x0383, 0x01 },
1323     { 0x0385, 0x01 },
1324     { 0x0387, 0x01 },
1325     { 0x0900, 0x01 },
1326     { 0x0901, 0x22 },
1327     { 0x0902, 0x0a },
1328     { 0x3140, 0x02 },
1329     { 0x3141, 0x00 },
1330     { 0x3f0d, 0x0a },
1331     { 0x3f14, 0x01 },
1332     { 0x3f3c, 0x02 },
1333     { 0x3f4d, 0x01 },
1334     { 0x3f4c, 0x01 },
1335     { 0x4254, 0x7f },
1336     { 0x0401, 0x00 },
1337     { 0x0404, 0x00 },
1338     { 0x0405, 0x10 },
1339     { 0x0408, 0x00 },
1340     { 0x0409, 0xac },
1341     { 0x040a, 0x00 },
1342     { 0x040b, 0x00 },
1343     { 0x040c, 0x05 },
1344     { 0x040d, 0x10 },
1345     { 0x040e, 0x02 },
1346     { 0x040f, 0xe0 },
1347     { 0x034c, 0x05 },
1348     { 0x034d, 0x10 },
1349     { 0x034e, 0x02 },
1350     { 0x034f, 0xe0 },
1351     { 0x3261, 0x00 },
1352     { 0x3264, 0x00 },
1353     { 0x3265, 0x10 },
1354     { 0x0301, 0x05 },
1355     { 0x0303, 0x04 },
1356     { 0x0305, 0x04 },
1357     { 0x0306, 0x01 },
1358     { 0x0307, 0x92 },
1359     { 0x0309, 0x0a },
1360     { 0x030b, 0x02 },
1361     { 0x030d, 0x02 },
1362     { 0x030e, 0x00 },
1363     { 0x030f, 0xfa },
1364     { 0x0310, 0x00 },
1365     { 0x0820, 0x0f },
1366     { 0x0821, 0x13 },
1367     { 0x0822, 0x33 },
1368     { 0x0823, 0x33 },
1369     { 0x3e20, 0x01 },
1370     { 0x3e37, 0x00 },
1371     { 0x3e3b, 0x01 },
1372     { 0x38a3, 0x01 },
1373     { 0x38a8, 0x00 },
1374     { 0x38a9, 0x00 },
1375     { 0x38aa, 0x00 },
1376     { 0x38ab, 0x00 },
1377     { 0x3234, 0x00 },
1378     { 0x3fc1, 0x00 },
1379     { 0x3235, 0x00 },
1380     { 0x3802, 0x00 },
1381     { 0x3143, 0x04 },
1382     { 0x360a, 0x00 },
1383     { 0x0b00, 0x00 },
1384     { 0x0106, 0x00 },
1385     { 0x0b05, 0x01 },
1386     { 0x0b06, 0x01 },
1387     { 0x3230, 0x00 },
1388     { 0x3602, 0x01 },
1389     { 0x3607, 0x01 },
1390     { 0x3c00, 0x00 },
1391     { 0x3c01, 0xba },
1392     { 0x3c02, 0xc8 },
1393     { 0x3c03, 0xaa },
1394     { 0x3c04, 0x91 },
1395     { 0x3c05, 0x54 },
1396     { 0x3c06, 0x26 },
1397     { 0x3c07, 0x20 },
1398     { 0x3c08, 0x51 },
1399     { 0x3d80, 0x00 },
1400     { 0x3f50, 0x00 },
1401     { 0x3f56, 0x00 },
1402     { 0x3f57, 0x30 },
1403     { 0x3f78, 0x00 },
1404     { 0x3f79, 0x34 },
1405     { 0x3f7c, 0x00 },
1406     { 0x3f7d, 0x00 },
1407     { 0x3fba, 0x00 },
1408     { 0x3fbb, 0x00 },
1409     { 0xa081, 0x04 },
1410     { 0xe014, 0x00 },
1411     { 0x0202, 0x04 },
1412     { 0x0203, 0xf6 },
1413     { 0x0224, 0x01 },
1414     { 0x0225, 0xf4 },
1415     { 0x0204, 0x00 },
1416     { 0x0205, 0x00 },
1417     { 0x0216, 0x00 },
1418     { 0x0217, 0x00 },
1419     { 0x020e, 0x01 },
1420     { 0x020f, 0x00 },
1421     { 0x0210, 0x01 },
1422     { 0x0211, 0x00 },
1423     { 0x0212, 0x01 },
1424     { 0x0213, 0x00 },
1425     { 0x0214, 0x01 },
1426     { 0x0215, 0x00 },
1427     { 0x0218, 0x01 },
1428     { 0x0219, 0x00 },
1429     { 0x3614, 0x00 },
1430     { 0x3616, 0x0d },
1431     { 0x3617, 0x56 },
1432     { 0xb612, 0x20 },
1433     { 0xb613, 0x20 },
1434     { 0xb614, 0x20 },
1435     { 0xb615, 0x20 },
1436     { 0xb616, 0x0a },
1437     { 0xb617, 0x0a },
1438     { 0xb618, 0x20 },
1439     { 0xb619, 0x20 },
1440     { 0xb61a, 0x20 },
1441     { 0xb61b, 0x20 },
1442     { 0xb61c, 0x0a },
1443     { 0xb61d, 0x0a },
1444     { 0xb666, 0x30 },
1445     { 0xb667, 0x30 },
1446     { 0xb668, 0x30 },
1447     { 0xb669, 0x30 },
1448     { 0xb66a, 0x14 },
1449     { 0xb66b, 0x14 },
1450     { 0xb66c, 0x20 },
1451     { 0xb66d, 0x20 },
1452     { 0xb66e, 0x20 },
1453     { 0xb66f, 0x20 },
1454     { 0xb670, 0x10 },
1455     { 0xb671, 0x10 },
1456     { 0x3237, 0x00 },
1457     { 0x3900, 0x00 },
1458     { 0x3901, 0x00 },
1459     { 0x3902, 0x00 },
1460     { 0x3904, 0x00 },
1461     { 0x3905, 0x00 },
1462     { 0x3906, 0x00 },
1463     { 0x3907, 0x00 },
1464     { 0x3908, 0x00 },
1465     { 0x3909, 0x00 },
1466     { 0x3912, 0x00 },
1467     { 0x3930, 0x00 },
1468     { 0x3931, 0x00 },
1469     { 0x3933, 0x00 },
1470     { 0x3934, 0x00 },
1471     { 0x3935, 0x00 },
1472     { 0x3936, 0x00 },
1473     { 0x3937, 0x00 },
1474     { 0x30ac, 0x00 },
1475 };
1476 
1477 static const struct imx319_reg mode_1280x720_regs[] = {
1478     { 0x0112, 0x0a },
1479     { 0x0113, 0x0a },
1480     { 0x0114, 0x03 },
1481     { 0x0342, 0x08 },
1482     { 0x0343, 0x20 },
1483     { 0x0340, 0x18 },
1484     { 0x0341, 0x2a },
1485     { 0x0344, 0x00 },
1486     { 0x0345, 0x00 },
1487     { 0x0346, 0x02 },
1488     { 0x0347, 0x00 },
1489     { 0x0348, 0x0c },
1490     { 0x0349, 0xcf },
1491     { 0x034a, 0x07 },
1492     { 0x034b, 0x9f },
1493     { 0x0220, 0x00 },
1494     { 0x0221, 0x11 },
1495     { 0x0381, 0x01 },
1496     { 0x0383, 0x01 },
1497     { 0x0385, 0x01 },
1498     { 0x0387, 0x01 },
1499     { 0x0900, 0x01 },
1500     { 0x0901, 0x22 },
1501     { 0x0902, 0x0a },
1502     { 0x3140, 0x02 },
1503     { 0x3141, 0x00 },
1504     { 0x3f0d, 0x0a },
1505     { 0x3f14, 0x01 },
1506     { 0x3f3c, 0x02 },
1507     { 0x3f4d, 0x01 },
1508     { 0x3f4c, 0x01 },
1509     { 0x4254, 0x7f },
1510     { 0x0401, 0x00 },
1511     { 0x0404, 0x00 },
1512     { 0x0405, 0x10 },
1513     { 0x0408, 0x00 },
1514     { 0x0409, 0xb4 },
1515     { 0x040a, 0x00 },
1516     { 0x040b, 0x00 },
1517     { 0x040c, 0x05 },
1518     { 0x040d, 0x00 },
1519     { 0x040e, 0x02 },
1520     { 0x040f, 0xd0 },
1521     { 0x034c, 0x05 },
1522     { 0x034d, 0x00 },
1523     { 0x034e, 0x02 },
1524     { 0x034f, 0xd0 },
1525     { 0x3261, 0x00 },
1526     { 0x3264, 0x00 },
1527     { 0x3265, 0x10 },
1528     { 0x0301, 0x05 },
1529     { 0x0303, 0x04 },
1530     { 0x0305, 0x04 },
1531     { 0x0306, 0x01 },
1532     { 0x0307, 0x92 },
1533     { 0x0309, 0x0a },
1534     { 0x030b, 0x02 },
1535     { 0x030d, 0x02 },
1536     { 0x030e, 0x00 },
1537     { 0x030f, 0xfa },
1538     { 0x0310, 0x00 },
1539     { 0x0820, 0x0f },
1540     { 0x0821, 0x13 },
1541     { 0x0822, 0x33 },
1542     { 0x0823, 0x33 },
1543     { 0x3e20, 0x01 },
1544     { 0x3e37, 0x00 },
1545     { 0x3e3b, 0x01 },
1546     { 0x38a3, 0x01 },
1547     { 0x38a8, 0x00 },
1548     { 0x38a9, 0x00 },
1549     { 0x38aa, 0x00 },
1550     { 0x38ab, 0x00 },
1551     { 0x3234, 0x00 },
1552     { 0x3fc1, 0x00 },
1553     { 0x3235, 0x00 },
1554     { 0x3802, 0x00 },
1555     { 0x3143, 0x04 },
1556     { 0x360a, 0x00 },
1557     { 0x0b00, 0x00 },
1558     { 0x0106, 0x00 },
1559     { 0x0b05, 0x01 },
1560     { 0x0b06, 0x01 },
1561     { 0x3230, 0x00 },
1562     { 0x3602, 0x01 },
1563     { 0x3607, 0x01 },
1564     { 0x3c00, 0x00 },
1565     { 0x3c01, 0xba },
1566     { 0x3c02, 0xc8 },
1567     { 0x3c03, 0xaa },
1568     { 0x3c04, 0x91 },
1569     { 0x3c05, 0x54 },
1570     { 0x3c06, 0x26 },
1571     { 0x3c07, 0x20 },
1572     { 0x3c08, 0x51 },
1573     { 0x3d80, 0x00 },
1574     { 0x3f50, 0x00 },
1575     { 0x3f56, 0x00 },
1576     { 0x3f57, 0x30 },
1577     { 0x3f78, 0x00 },
1578     { 0x3f79, 0x34 },
1579     { 0x3f7c, 0x00 },
1580     { 0x3f7d, 0x00 },
1581     { 0x3fba, 0x00 },
1582     { 0x3fbb, 0x00 },
1583     { 0xa081, 0x04 },
1584     { 0xe014, 0x00 },
1585     { 0x0202, 0x04 },
1586     { 0x0203, 0xf6 },
1587     { 0x0224, 0x01 },
1588     { 0x0225, 0xf4 },
1589     { 0x0204, 0x00 },
1590     { 0x0205, 0x00 },
1591     { 0x0216, 0x00 },
1592     { 0x0217, 0x00 },
1593     { 0x020e, 0x01 },
1594     { 0x020f, 0x00 },
1595     { 0x0210, 0x01 },
1596     { 0x0211, 0x00 },
1597     { 0x0212, 0x01 },
1598     { 0x0213, 0x00 },
1599     { 0x0214, 0x01 },
1600     { 0x0215, 0x00 },
1601     { 0x0218, 0x01 },
1602     { 0x0219, 0x00 },
1603     { 0x3614, 0x00 },
1604     { 0x3616, 0x0d },
1605     { 0x3617, 0x56 },
1606     { 0xb612, 0x20 },
1607     { 0xb613, 0x20 },
1608     { 0xb614, 0x20 },
1609     { 0xb615, 0x20 },
1610     { 0xb616, 0x0a },
1611     { 0xb617, 0x0a },
1612     { 0xb618, 0x20 },
1613     { 0xb619, 0x20 },
1614     { 0xb61a, 0x20 },
1615     { 0xb61b, 0x20 },
1616     { 0xb61c, 0x0a },
1617     { 0xb61d, 0x0a },
1618     { 0xb666, 0x30 },
1619     { 0xb667, 0x30 },
1620     { 0xb668, 0x30 },
1621     { 0xb669, 0x30 },
1622     { 0xb66a, 0x14 },
1623     { 0xb66b, 0x14 },
1624     { 0xb66c, 0x20 },
1625     { 0xb66d, 0x20 },
1626     { 0xb66e, 0x20 },
1627     { 0xb66f, 0x20 },
1628     { 0xb670, 0x10 },
1629     { 0xb671, 0x10 },
1630     { 0x3237, 0x00 },
1631     { 0x3900, 0x00 },
1632     { 0x3901, 0x00 },
1633     { 0x3902, 0x00 },
1634     { 0x3904, 0x00 },
1635     { 0x3905, 0x00 },
1636     { 0x3906, 0x00 },
1637     { 0x3907, 0x00 },
1638     { 0x3908, 0x00 },
1639     { 0x3909, 0x00 },
1640     { 0x3912, 0x00 },
1641     { 0x3930, 0x00 },
1642     { 0x3931, 0x00 },
1643     { 0x3933, 0x00 },
1644     { 0x3934, 0x00 },
1645     { 0x3935, 0x00 },
1646     { 0x3936, 0x00 },
1647     { 0x3937, 0x00 },
1648     { 0x30ac, 0x00 },
1649 };
1650 
1651 static const char * const imx319_test_pattern_menu[] = {
1652     "Disabled",
1653     "Solid Colour",
1654     "Eight Vertical Colour Bars",
1655     "Colour Bars With Fade to Grey",
1656     "Pseudorandom Sequence (PN9)",
1657 };
1658 
1659 /* supported link frequencies */
1660 static const s64 link_freq_menu_items[] = {
1661     IMX319_LINK_FREQ_DEFAULT,
1662 };
1663 
1664 /* Mode configs */
1665 static const struct imx319_mode supported_modes[] = {
1666     {
1667         .width = 3280,
1668         .height = 2464,
1669         .fll_def = 3242,
1670         .fll_min = 3242,
1671         .llp = 3968,
1672         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1673         .reg_list = {
1674             .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
1675             .regs = mode_3280x2464_regs,
1676         },
1677     },
1678     {
1679         .width = 3264,
1680         .height = 2448,
1681         .fll_def = 3242,
1682         .fll_min = 3242,
1683         .llp = 3968,
1684         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1685         .reg_list = {
1686             .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
1687             .regs = mode_3264x2448_regs,
1688         },
1689     },
1690     {
1691         .width = 1936,
1692         .height = 1096,
1693         .fll_def = 3242,
1694         .fll_min = 3242,
1695         .llp = 3968,
1696         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1697         .reg_list = {
1698             .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
1699             .regs = mode_1936x1096_regs,
1700         },
1701     },
1702     {
1703         .width = 1920,
1704         .height = 1080,
1705         .fll_def = 3242,
1706         .fll_min = 3242,
1707         .llp = 3968,
1708         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1709         .reg_list = {
1710             .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
1711             .regs = mode_1920x1080_regs,
1712         },
1713     },
1714     {
1715         .width = 1640,
1716         .height = 1232,
1717         .fll_def = 5146,
1718         .fll_min = 5146,
1719         .llp = 2500,
1720         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1721         .reg_list = {
1722             .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
1723             .regs = mode_1640x1232_regs,
1724         },
1725     },
1726     {
1727         .width = 1640,
1728         .height = 922,
1729         .fll_def = 5146,
1730         .fll_min = 5146,
1731         .llp = 2500,
1732         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1733         .reg_list = {
1734             .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
1735             .regs = mode_1640x922_regs,
1736         },
1737     },
1738     {
1739         .width = 1296,
1740         .height = 736,
1741         .fll_def = 5146,
1742         .fll_min = 5146,
1743         .llp = 2500,
1744         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1745         .reg_list = {
1746             .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
1747             .regs = mode_1296x736_regs,
1748         },
1749     },
1750     {
1751         .width = 1280,
1752         .height = 720,
1753         .fll_def = 5146,
1754         .fll_min = 5146,
1755         .llp = 2500,
1756         .link_freq_index = IMX319_LINK_FREQ_INDEX,
1757         .reg_list = {
1758             .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
1759             .regs = mode_1280x720_regs,
1760         },
1761     },
1762 };
1763 
1764 static inline struct imx319 *to_imx319(struct v4l2_subdev *_sd)
1765 {
1766     return container_of(_sd, struct imx319, sd);
1767 }
1768 
1769 /* Get bayer order based on flip setting. */
1770 static u32 imx319_get_format_code(struct imx319 *imx319)
1771 {
1772     /*
1773      * Only one bayer order is supported.
1774      * It depends on the flip settings.
1775      */
1776     u32 code;
1777     static const u32 codes[2][2] = {
1778         { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
1779         { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
1780     };
1781 
1782     lockdep_assert_held(&imx319->mutex);
1783     code = codes[imx319->vflip->val][imx319->hflip->val];
1784 
1785     return code;
1786 }
1787 
1788 /* Read registers up to 4 at a time */
1789 static int imx319_read_reg(struct imx319 *imx319, u16 reg, u32 len, u32 *val)
1790 {
1791     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1792     struct i2c_msg msgs[2];
1793     u8 addr_buf[2];
1794     u8 data_buf[4] = { 0 };
1795     int ret;
1796 
1797     if (len > 4)
1798         return -EINVAL;
1799 
1800     put_unaligned_be16(reg, addr_buf);
1801     /* Write register address */
1802     msgs[0].addr = client->addr;
1803     msgs[0].flags = 0;
1804     msgs[0].len = ARRAY_SIZE(addr_buf);
1805     msgs[0].buf = addr_buf;
1806 
1807     /* Read data from register */
1808     msgs[1].addr = client->addr;
1809     msgs[1].flags = I2C_M_RD;
1810     msgs[1].len = len;
1811     msgs[1].buf = &data_buf[4 - len];
1812 
1813     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1814     if (ret != ARRAY_SIZE(msgs))
1815         return -EIO;
1816 
1817     *val = get_unaligned_be32(data_buf);
1818 
1819     return 0;
1820 }
1821 
1822 /* Write registers up to 4 at a time */
1823 static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
1824 {
1825     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1826     u8 buf[6];
1827 
1828     if (len > 4)
1829         return -EINVAL;
1830 
1831     put_unaligned_be16(reg, buf);
1832     put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1833     if (i2c_master_send(client, buf, len + 2) != len + 2)
1834         return -EIO;
1835 
1836     return 0;
1837 }
1838 
1839 /* Write a list of registers */
1840 static int imx319_write_regs(struct imx319 *imx319,
1841                  const struct imx319_reg *regs, u32 len)
1842 {
1843     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1844     int ret;
1845     u32 i;
1846 
1847     for (i = 0; i < len; i++) {
1848         ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
1849         if (ret) {
1850             dev_err_ratelimited(&client->dev,
1851                         "write reg 0x%4.4x return err %d",
1852                         regs[i].address, ret);
1853             return ret;
1854         }
1855     }
1856 
1857     return 0;
1858 }
1859 
1860 /* Open sub-device */
1861 static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1862 {
1863     struct imx319 *imx319 = to_imx319(sd);
1864     struct v4l2_mbus_framefmt *try_fmt =
1865         v4l2_subdev_get_try_format(sd, fh->state, 0);
1866 
1867     mutex_lock(&imx319->mutex);
1868 
1869     /* Initialize try_fmt */
1870     try_fmt->width = imx319->cur_mode->width;
1871     try_fmt->height = imx319->cur_mode->height;
1872     try_fmt->code = imx319_get_format_code(imx319);
1873     try_fmt->field = V4L2_FIELD_NONE;
1874 
1875     mutex_unlock(&imx319->mutex);
1876 
1877     return 0;
1878 }
1879 
1880 static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
1881 {
1882     struct imx319 *imx319 = container_of(ctrl->handler,
1883                          struct imx319, ctrl_handler);
1884     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
1885     s64 max;
1886     int ret;
1887 
1888     /* Propagate change of current control to all related controls */
1889     switch (ctrl->id) {
1890     case V4L2_CID_VBLANK:
1891         /* Update max exposure while meeting expected vblanking */
1892         max = imx319->cur_mode->height + ctrl->val - 18;
1893         __v4l2_ctrl_modify_range(imx319->exposure,
1894                      imx319->exposure->minimum,
1895                      max, imx319->exposure->step, max);
1896         break;
1897     }
1898 
1899     /*
1900      * Applying V4L2 control value only happens
1901      * when power is up for streaming
1902      */
1903     if (!pm_runtime_get_if_in_use(&client->dev))
1904         return 0;
1905 
1906     switch (ctrl->id) {
1907     case V4L2_CID_ANALOGUE_GAIN:
1908         /* Analog gain = 1024/(1024 - ctrl->val) times */
1909         ret = imx319_write_reg(imx319, IMX319_REG_ANALOG_GAIN, 2,
1910                        ctrl->val);
1911         break;
1912     case V4L2_CID_DIGITAL_GAIN:
1913         ret = imx319_write_reg(imx319, IMX319_REG_DIG_GAIN_GLOBAL, 2,
1914                        ctrl->val);
1915         break;
1916     case V4L2_CID_EXPOSURE:
1917         ret = imx319_write_reg(imx319, IMX319_REG_EXPOSURE, 2,
1918                        ctrl->val);
1919         break;
1920     case V4L2_CID_VBLANK:
1921         /* Update FLL that meets expected vertical blanking */
1922         ret = imx319_write_reg(imx319, IMX319_REG_FLL, 2,
1923                        imx319->cur_mode->height + ctrl->val);
1924         break;
1925     case V4L2_CID_TEST_PATTERN:
1926         ret = imx319_write_reg(imx319, IMX319_REG_TEST_PATTERN,
1927                        2, ctrl->val);
1928         break;
1929     case V4L2_CID_HFLIP:
1930     case V4L2_CID_VFLIP:
1931         ret = imx319_write_reg(imx319, IMX319_REG_ORIENTATION, 1,
1932                        imx319->hflip->val |
1933                        imx319->vflip->val << 1);
1934         break;
1935     default:
1936         ret = -EINVAL;
1937         dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
1938              ctrl->id, ctrl->val);
1939         break;
1940     }
1941 
1942     pm_runtime_put(&client->dev);
1943 
1944     return ret;
1945 }
1946 
1947 static const struct v4l2_ctrl_ops imx319_ctrl_ops = {
1948     .s_ctrl = imx319_set_ctrl,
1949 };
1950 
1951 static int imx319_enum_mbus_code(struct v4l2_subdev *sd,
1952                  struct v4l2_subdev_state *sd_state,
1953                  struct v4l2_subdev_mbus_code_enum *code)
1954 {
1955     struct imx319 *imx319 = to_imx319(sd);
1956 
1957     if (code->index > 0)
1958         return -EINVAL;
1959 
1960     mutex_lock(&imx319->mutex);
1961     code->code = imx319_get_format_code(imx319);
1962     mutex_unlock(&imx319->mutex);
1963 
1964     return 0;
1965 }
1966 
1967 static int imx319_enum_frame_size(struct v4l2_subdev *sd,
1968                   struct v4l2_subdev_state *sd_state,
1969                   struct v4l2_subdev_frame_size_enum *fse)
1970 {
1971     struct imx319 *imx319 = to_imx319(sd);
1972 
1973     if (fse->index >= ARRAY_SIZE(supported_modes))
1974         return -EINVAL;
1975 
1976     mutex_lock(&imx319->mutex);
1977     if (fse->code != imx319_get_format_code(imx319)) {
1978         mutex_unlock(&imx319->mutex);
1979         return -EINVAL;
1980     }
1981     mutex_unlock(&imx319->mutex);
1982 
1983     fse->min_width = supported_modes[fse->index].width;
1984     fse->max_width = fse->min_width;
1985     fse->min_height = supported_modes[fse->index].height;
1986     fse->max_height = fse->min_height;
1987 
1988     return 0;
1989 }
1990 
1991 static void imx319_update_pad_format(struct imx319 *imx319,
1992                      const struct imx319_mode *mode,
1993                      struct v4l2_subdev_format *fmt)
1994 {
1995     fmt->format.width = mode->width;
1996     fmt->format.height = mode->height;
1997     fmt->format.code = imx319_get_format_code(imx319);
1998     fmt->format.field = V4L2_FIELD_NONE;
1999 }
2000 
2001 static int imx319_do_get_pad_format(struct imx319 *imx319,
2002                     struct v4l2_subdev_state *sd_state,
2003                     struct v4l2_subdev_format *fmt)
2004 {
2005     struct v4l2_mbus_framefmt *framefmt;
2006     struct v4l2_subdev *sd = &imx319->sd;
2007 
2008     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2009         framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
2010         fmt->format = *framefmt;
2011     } else {
2012         imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
2013     }
2014 
2015     return 0;
2016 }
2017 
2018 static int imx319_get_pad_format(struct v4l2_subdev *sd,
2019                  struct v4l2_subdev_state *sd_state,
2020                  struct v4l2_subdev_format *fmt)
2021 {
2022     struct imx319 *imx319 = to_imx319(sd);
2023     int ret;
2024 
2025     mutex_lock(&imx319->mutex);
2026     ret = imx319_do_get_pad_format(imx319, sd_state, fmt);
2027     mutex_unlock(&imx319->mutex);
2028 
2029     return ret;
2030 }
2031 
2032 static int
2033 imx319_set_pad_format(struct v4l2_subdev *sd,
2034               struct v4l2_subdev_state *sd_state,
2035               struct v4l2_subdev_format *fmt)
2036 {
2037     struct imx319 *imx319 = to_imx319(sd);
2038     const struct imx319_mode *mode;
2039     struct v4l2_mbus_framefmt *framefmt;
2040     s32 vblank_def;
2041     s32 vblank_min;
2042     s64 h_blank;
2043     u64 pixel_rate;
2044     u32 height;
2045 
2046     mutex_lock(&imx319->mutex);
2047 
2048     /*
2049      * Only one bayer order is supported.
2050      * It depends on the flip settings.
2051      */
2052     fmt->format.code = imx319_get_format_code(imx319);
2053 
2054     mode = v4l2_find_nearest_size(supported_modes,
2055                       ARRAY_SIZE(supported_modes),
2056                       width, height,
2057                       fmt->format.width, fmt->format.height);
2058     imx319_update_pad_format(imx319, mode, fmt);
2059     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2060         framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
2061         *framefmt = fmt->format;
2062     } else {
2063         imx319->cur_mode = mode;
2064         pixel_rate = imx319->link_def_freq * 2 * 4;
2065         do_div(pixel_rate, 10);
2066         __v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
2067         /* Update limits and set FPS to default */
2068         height = imx319->cur_mode->height;
2069         vblank_def = imx319->cur_mode->fll_def - height;
2070         vblank_min = imx319->cur_mode->fll_min - height;
2071         height = IMX319_FLL_MAX - height;
2072         __v4l2_ctrl_modify_range(imx319->vblank, vblank_min, height, 1,
2073                      vblank_def);
2074         __v4l2_ctrl_s_ctrl(imx319->vblank, vblank_def);
2075         h_blank = mode->llp - imx319->cur_mode->width;
2076         /*
2077          * Currently hblank is not changeable.
2078          * So FPS control is done only by vblank.
2079          */
2080         __v4l2_ctrl_modify_range(imx319->hblank, h_blank,
2081                      h_blank, 1, h_blank);
2082     }
2083 
2084     mutex_unlock(&imx319->mutex);
2085 
2086     return 0;
2087 }
2088 
2089 /* Verify chip ID */
2090 static int imx319_identify_module(struct imx319 *imx319)
2091 {
2092     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2093     int ret;
2094     u32 val;
2095 
2096     if (imx319->identified)
2097         return 0;
2098 
2099     ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
2100     if (ret)
2101         return ret;
2102 
2103     if (val != IMX319_CHIP_ID) {
2104         dev_err(&client->dev, "chip id mismatch: %x!=%x",
2105             IMX319_CHIP_ID, val);
2106         return -EIO;
2107     }
2108 
2109     imx319->identified = true;
2110 
2111     return 0;
2112 }
2113 
2114 /* Start streaming */
2115 static int imx319_start_streaming(struct imx319 *imx319)
2116 {
2117     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2118     const struct imx319_reg_list *reg_list;
2119     int ret;
2120 
2121     ret = imx319_identify_module(imx319);
2122     if (ret)
2123         return ret;
2124 
2125     /* Global Setting */
2126     reg_list = &imx319_global_setting;
2127     ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
2128     if (ret) {
2129         dev_err(&client->dev, "failed to set global settings");
2130         return ret;
2131     }
2132 
2133     /* Apply default values of current mode */
2134     reg_list = &imx319->cur_mode->reg_list;
2135     ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
2136     if (ret) {
2137         dev_err(&client->dev, "failed to set mode");
2138         return ret;
2139     }
2140 
2141     /* set digital gain control to all color mode */
2142     ret = imx319_write_reg(imx319, IMX319_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
2143     if (ret)
2144         return ret;
2145 
2146     /* Apply customized values from user */
2147     ret =  __v4l2_ctrl_handler_setup(imx319->sd.ctrl_handler);
2148     if (ret)
2149         return ret;
2150 
2151     return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
2152                 1, IMX319_MODE_STREAMING);
2153 }
2154 
2155 /* Stop streaming */
2156 static int imx319_stop_streaming(struct imx319 *imx319)
2157 {
2158     return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
2159                 1, IMX319_MODE_STANDBY);
2160 }
2161 
2162 static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
2163 {
2164     struct imx319 *imx319 = to_imx319(sd);
2165     struct i2c_client *client = v4l2_get_subdevdata(sd);
2166     int ret = 0;
2167 
2168     mutex_lock(&imx319->mutex);
2169     if (imx319->streaming == enable) {
2170         mutex_unlock(&imx319->mutex);
2171         return 0;
2172     }
2173 
2174     if (enable) {
2175         ret = pm_runtime_resume_and_get(&client->dev);
2176         if (ret < 0)
2177             goto err_unlock;
2178 
2179         /*
2180          * Apply default & customized values
2181          * and then start streaming.
2182          */
2183         ret = imx319_start_streaming(imx319);
2184         if (ret)
2185             goto err_rpm_put;
2186     } else {
2187         imx319_stop_streaming(imx319);
2188         pm_runtime_put(&client->dev);
2189     }
2190 
2191     imx319->streaming = enable;
2192 
2193     /* vflip and hflip cannot change during streaming */
2194     __v4l2_ctrl_grab(imx319->vflip, enable);
2195     __v4l2_ctrl_grab(imx319->hflip, enable);
2196 
2197     mutex_unlock(&imx319->mutex);
2198 
2199     return ret;
2200 
2201 err_rpm_put:
2202     pm_runtime_put(&client->dev);
2203 err_unlock:
2204     mutex_unlock(&imx319->mutex);
2205 
2206     return ret;
2207 }
2208 
2209 static int __maybe_unused imx319_suspend(struct device *dev)
2210 {
2211     struct v4l2_subdev *sd = dev_get_drvdata(dev);
2212     struct imx319 *imx319 = to_imx319(sd);
2213 
2214     if (imx319->streaming)
2215         imx319_stop_streaming(imx319);
2216 
2217     return 0;
2218 }
2219 
2220 static int __maybe_unused imx319_resume(struct device *dev)
2221 {
2222     struct v4l2_subdev *sd = dev_get_drvdata(dev);
2223     struct imx319 *imx319 = to_imx319(sd);
2224     int ret;
2225 
2226     if (imx319->streaming) {
2227         ret = imx319_start_streaming(imx319);
2228         if (ret)
2229             goto error;
2230     }
2231 
2232     return 0;
2233 
2234 error:
2235     imx319_stop_streaming(imx319);
2236     imx319->streaming = 0;
2237     return ret;
2238 }
2239 
2240 static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
2241     .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
2242     .unsubscribe_event = v4l2_event_subdev_unsubscribe,
2243 };
2244 
2245 static const struct v4l2_subdev_video_ops imx319_video_ops = {
2246     .s_stream = imx319_set_stream,
2247 };
2248 
2249 static const struct v4l2_subdev_pad_ops imx319_pad_ops = {
2250     .enum_mbus_code = imx319_enum_mbus_code,
2251     .get_fmt = imx319_get_pad_format,
2252     .set_fmt = imx319_set_pad_format,
2253     .enum_frame_size = imx319_enum_frame_size,
2254 };
2255 
2256 static const struct v4l2_subdev_ops imx319_subdev_ops = {
2257     .core = &imx319_subdev_core_ops,
2258     .video = &imx319_video_ops,
2259     .pad = &imx319_pad_ops,
2260 };
2261 
2262 static const struct media_entity_operations imx319_subdev_entity_ops = {
2263     .link_validate = v4l2_subdev_link_validate,
2264 };
2265 
2266 static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
2267     .open = imx319_open,
2268 };
2269 
2270 /* Initialize control handlers */
2271 static int imx319_init_controls(struct imx319 *imx319)
2272 {
2273     struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
2274     struct v4l2_ctrl_handler *ctrl_hdlr;
2275     s64 exposure_max;
2276     s64 vblank_def;
2277     s64 vblank_min;
2278     s64 hblank;
2279     u64 pixel_rate;
2280     const struct imx319_mode *mode;
2281     u32 max;
2282     int ret;
2283 
2284     ctrl_hdlr = &imx319->ctrl_handler;
2285     ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
2286     if (ret)
2287         return ret;
2288 
2289     ctrl_hdlr->lock = &imx319->mutex;
2290     max = ARRAY_SIZE(link_freq_menu_items) - 1;
2291     imx319->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx319_ctrl_ops,
2292                            V4L2_CID_LINK_FREQ, max, 0,
2293                            link_freq_menu_items);
2294     if (imx319->link_freq)
2295         imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2296 
2297     /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
2298     pixel_rate = imx319->link_def_freq * 2 * 4;
2299     do_div(pixel_rate, 10);
2300     /* By default, PIXEL_RATE is read only */
2301     imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2302                            V4L2_CID_PIXEL_RATE, pixel_rate,
2303                            pixel_rate, 1, pixel_rate);
2304 
2305     /* Initial vblank/hblank/exposure parameters based on current mode */
2306     mode = imx319->cur_mode;
2307     vblank_def = mode->fll_def - mode->height;
2308     vblank_min = mode->fll_min - mode->height;
2309     imx319->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2310                        V4L2_CID_VBLANK, vblank_min,
2311                        IMX319_FLL_MAX - mode->height,
2312                        1, vblank_def);
2313 
2314     hblank = mode->llp - mode->width;
2315     imx319->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2316                        V4L2_CID_HBLANK, hblank, hblank,
2317                        1, hblank);
2318     if (imx319->hblank)
2319         imx319->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2320 
2321     /* fll >= exposure time + adjust parameter (default value is 18) */
2322     exposure_max = mode->fll_def - 18;
2323     imx319->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2324                          V4L2_CID_EXPOSURE,
2325                          IMX319_EXPOSURE_MIN, exposure_max,
2326                          IMX319_EXPOSURE_STEP,
2327                          IMX319_EXPOSURE_DEFAULT);
2328 
2329     imx319->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2330                       V4L2_CID_HFLIP, 0, 1, 1, 0);
2331     imx319->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
2332                       V4L2_CID_VFLIP, 0, 1, 1, 0);
2333 
2334     v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
2335               IMX319_ANA_GAIN_MIN, IMX319_ANA_GAIN_MAX,
2336               IMX319_ANA_GAIN_STEP, IMX319_ANA_GAIN_DEFAULT);
2337 
2338     /* Digital gain */
2339     v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
2340               IMX319_DGTL_GAIN_MIN, IMX319_DGTL_GAIN_MAX,
2341               IMX319_DGTL_GAIN_STEP, IMX319_DGTL_GAIN_DEFAULT);
2342 
2343     v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx319_ctrl_ops,
2344                      V4L2_CID_TEST_PATTERN,
2345                      ARRAY_SIZE(imx319_test_pattern_menu) - 1,
2346                      0, 0, imx319_test_pattern_menu);
2347     if (ctrl_hdlr->error) {
2348         ret = ctrl_hdlr->error;
2349         dev_err(&client->dev, "control init failed: %d", ret);
2350         goto error;
2351     }
2352 
2353     imx319->sd.ctrl_handler = ctrl_hdlr;
2354 
2355     return 0;
2356 
2357 error:
2358     v4l2_ctrl_handler_free(ctrl_hdlr);
2359 
2360     return ret;
2361 }
2362 
2363 static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
2364 {
2365     struct imx319_hwcfg *cfg;
2366     struct v4l2_fwnode_endpoint bus_cfg = {
2367         .bus_type = V4L2_MBUS_CSI2_DPHY
2368     };
2369     struct fwnode_handle *ep;
2370     struct fwnode_handle *fwnode = dev_fwnode(dev);
2371     unsigned int i;
2372     int ret;
2373 
2374     if (!fwnode)
2375         return NULL;
2376 
2377     ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
2378     if (!ep)
2379         return NULL;
2380 
2381     ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
2382     if (ret)
2383         goto out_err;
2384 
2385     cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
2386     if (!cfg)
2387         goto out_err;
2388 
2389     ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
2390                        &cfg->ext_clk);
2391     if (ret) {
2392         dev_err(dev, "can't get clock frequency");
2393         goto out_err;
2394     }
2395 
2396     dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
2397     if (cfg->ext_clk != IMX319_EXT_CLK) {
2398         dev_err(dev, "external clock %d is not supported",
2399             cfg->ext_clk);
2400         goto out_err;
2401     }
2402 
2403     dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
2404     if (!bus_cfg.nr_of_link_frequencies) {
2405         dev_warn(dev, "no link frequencies defined");
2406         goto out_err;
2407     }
2408 
2409     cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
2410     cfg->link_freqs = devm_kcalloc(dev,
2411                        bus_cfg.nr_of_link_frequencies + 1,
2412                        sizeof(*cfg->link_freqs), GFP_KERNEL);
2413     if (!cfg->link_freqs)
2414         goto out_err;
2415 
2416     for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
2417         cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
2418         dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
2419     }
2420 
2421     v4l2_fwnode_endpoint_free(&bus_cfg);
2422     fwnode_handle_put(ep);
2423     return cfg;
2424 
2425 out_err:
2426     v4l2_fwnode_endpoint_free(&bus_cfg);
2427     fwnode_handle_put(ep);
2428     return NULL;
2429 }
2430 
2431 static int imx319_probe(struct i2c_client *client)
2432 {
2433     struct imx319 *imx319;
2434     bool full_power;
2435     int ret;
2436     u32 i;
2437 
2438     imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
2439     if (!imx319)
2440         return -ENOMEM;
2441 
2442     mutex_init(&imx319->mutex);
2443 
2444     /* Initialize subdev */
2445     v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
2446 
2447     full_power = acpi_dev_state_d0(&client->dev);
2448     if (full_power) {
2449         /* Check module identity */
2450         ret = imx319_identify_module(imx319);
2451         if (ret) {
2452             dev_err(&client->dev, "failed to find sensor: %d", ret);
2453             goto error_probe;
2454         }
2455     }
2456 
2457     imx319->hwcfg = imx319_get_hwcfg(&client->dev);
2458     if (!imx319->hwcfg) {
2459         dev_err(&client->dev, "failed to get hwcfg");
2460         ret = -ENODEV;
2461         goto error_probe;
2462     }
2463 
2464     imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
2465     for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
2466         if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
2467             dev_dbg(&client->dev, "link freq index %d matched", i);
2468             break;
2469         }
2470     }
2471 
2472     if (i == imx319->hwcfg->nr_of_link_freqs) {
2473         dev_err(&client->dev, "no link frequency supported");
2474         ret = -EINVAL;
2475         goto error_probe;
2476     }
2477 
2478     /* Set default mode to max resolution */
2479     imx319->cur_mode = &supported_modes[0];
2480 
2481     ret = imx319_init_controls(imx319);
2482     if (ret) {
2483         dev_err(&client->dev, "failed to init controls: %d", ret);
2484         goto error_probe;
2485     }
2486 
2487     /* Initialize subdev */
2488     imx319->sd.internal_ops = &imx319_internal_ops;
2489     imx319->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
2490         V4L2_SUBDEV_FL_HAS_EVENTS;
2491     imx319->sd.entity.ops = &imx319_subdev_entity_ops;
2492     imx319->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
2493 
2494     /* Initialize source pad */
2495     imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
2496     ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
2497     if (ret) {
2498         dev_err(&client->dev, "failed to init entity pads: %d", ret);
2499         goto error_handler_free;
2500     }
2501 
2502     ret = v4l2_async_register_subdev_sensor(&imx319->sd);
2503     if (ret < 0)
2504         goto error_media_entity;
2505 
2506     /* Set the device's state to active if it's in D0 state. */
2507     if (full_power)
2508         pm_runtime_set_active(&client->dev);
2509     pm_runtime_enable(&client->dev);
2510     pm_runtime_idle(&client->dev);
2511 
2512     return 0;
2513 
2514 error_media_entity:
2515     media_entity_cleanup(&imx319->sd.entity);
2516 
2517 error_handler_free:
2518     v4l2_ctrl_handler_free(imx319->sd.ctrl_handler);
2519 
2520 error_probe:
2521     mutex_destroy(&imx319->mutex);
2522 
2523     return ret;
2524 }
2525 
2526 static int imx319_remove(struct i2c_client *client)
2527 {
2528     struct v4l2_subdev *sd = i2c_get_clientdata(client);
2529     struct imx319 *imx319 = to_imx319(sd);
2530 
2531     v4l2_async_unregister_subdev(sd);
2532     media_entity_cleanup(&sd->entity);
2533     v4l2_ctrl_handler_free(sd->ctrl_handler);
2534 
2535     pm_runtime_disable(&client->dev);
2536     pm_runtime_set_suspended(&client->dev);
2537 
2538     mutex_destroy(&imx319->mutex);
2539 
2540     return 0;
2541 }
2542 
2543 static const struct dev_pm_ops imx319_pm_ops = {
2544     SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
2545 };
2546 
2547 static const struct acpi_device_id imx319_acpi_ids[] __maybe_unused = {
2548     { "SONY319A" },
2549     { /* sentinel */ }
2550 };
2551 MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
2552 
2553 static struct i2c_driver imx319_i2c_driver = {
2554     .driver = {
2555         .name = "imx319",
2556         .pm = &imx319_pm_ops,
2557         .acpi_match_table = ACPI_PTR(imx319_acpi_ids),
2558     },
2559     .probe_new = imx319_probe,
2560     .remove = imx319_remove,
2561     .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
2562 };
2563 module_i2c_driver(imx319_i2c_driver);
2564 
2565 MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
2566 MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
2567 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
2568 MODULE_AUTHOR("Yang, Hyungwoo");
2569 MODULE_DESCRIPTION("Sony imx319 sensor driver");
2570 MODULE_LICENSE("GPL v2");