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 IMX355_REG_MODE_SELECT      0x0100
0015 #define IMX355_MODE_STANDBY     0x00
0016 #define IMX355_MODE_STREAMING       0x01
0017 
0018 /* Chip ID */
0019 #define IMX355_REG_CHIP_ID      0x0016
0020 #define IMX355_CHIP_ID          0x0355
0021 
0022 /* V_TIMING internal */
0023 #define IMX355_REG_FLL          0x0340
0024 #define IMX355_FLL_MAX          0xffff
0025 
0026 /* Exposure control */
0027 #define IMX355_REG_EXPOSURE     0x0202
0028 #define IMX355_EXPOSURE_MIN     1
0029 #define IMX355_EXPOSURE_STEP        1
0030 #define IMX355_EXPOSURE_DEFAULT     0x0282
0031 
0032 /* Analog gain control */
0033 #define IMX355_REG_ANALOG_GAIN      0x0204
0034 #define IMX355_ANA_GAIN_MIN     0
0035 #define IMX355_ANA_GAIN_MAX     960
0036 #define IMX355_ANA_GAIN_STEP        1
0037 #define IMX355_ANA_GAIN_DEFAULT     0
0038 
0039 /* Digital gain control */
0040 #define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
0041 #define IMX355_REG_DIG_GAIN_GLOBAL  0x020e
0042 #define IMX355_DGTL_GAIN_MIN        256
0043 #define IMX355_DGTL_GAIN_MAX        4095
0044 #define IMX355_DGTL_GAIN_STEP       1
0045 #define IMX355_DGTL_GAIN_DEFAULT    256
0046 
0047 /* Test Pattern Control */
0048 #define IMX355_REG_TEST_PATTERN     0x0600
0049 #define IMX355_TEST_PATTERN_DISABLED        0
0050 #define IMX355_TEST_PATTERN_SOLID_COLOR     1
0051 #define IMX355_TEST_PATTERN_COLOR_BARS      2
0052 #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
0053 #define IMX355_TEST_PATTERN_PN9         4
0054 
0055 /* Flip Control */
0056 #define IMX355_REG_ORIENTATION      0x0101
0057 
0058 /* default link frequency and external clock */
0059 #define IMX355_LINK_FREQ_DEFAULT    360000000
0060 #define IMX355_EXT_CLK          19200000
0061 #define IMX355_LINK_FREQ_INDEX      0
0062 
0063 struct imx355_reg {
0064     u16 address;
0065     u8 val;
0066 };
0067 
0068 struct imx355_reg_list {
0069     u32 num_of_regs;
0070     const struct imx355_reg *regs;
0071 };
0072 
0073 /* Mode : resolution and related config&values */
0074 struct imx355_mode {
0075     /* Frame width */
0076     u32 width;
0077     /* Frame height */
0078     u32 height;
0079 
0080     /* V-timing */
0081     u32 fll_def;
0082     u32 fll_min;
0083 
0084     /* H-timing */
0085     u32 llp;
0086 
0087     /* index of link frequency */
0088     u32 link_freq_index;
0089 
0090     /* Default register values */
0091     struct imx355_reg_list reg_list;
0092 };
0093 
0094 struct imx355_hwcfg {
0095     u32 ext_clk;            /* sensor external clk */
0096     s64 *link_freqs;        /* CSI-2 link frequencies */
0097     unsigned int nr_of_link_freqs;
0098 };
0099 
0100 struct imx355 {
0101     struct v4l2_subdev sd;
0102     struct media_pad pad;
0103 
0104     struct v4l2_ctrl_handler ctrl_handler;
0105     /* V4L2 Controls */
0106     struct v4l2_ctrl *link_freq;
0107     struct v4l2_ctrl *pixel_rate;
0108     struct v4l2_ctrl *vblank;
0109     struct v4l2_ctrl *hblank;
0110     struct v4l2_ctrl *exposure;
0111     struct v4l2_ctrl *vflip;
0112     struct v4l2_ctrl *hflip;
0113 
0114     /* Current mode */
0115     const struct imx355_mode *cur_mode;
0116 
0117     struct imx355_hwcfg *hwcfg;
0118     s64 link_def_freq;  /* CSI-2 link default frequency */
0119 
0120     /*
0121      * Mutex for serialized access:
0122      * Protect sensor set pad format and start/stop streaming safely.
0123      * Protect access to sensor v4l2 controls.
0124      */
0125     struct mutex mutex;
0126 
0127     /* Streaming on/off */
0128     bool streaming;
0129 };
0130 
0131 static const struct imx355_reg imx355_global_regs[] = {
0132     { 0x0136, 0x13 },
0133     { 0x0137, 0x33 },
0134     { 0x304e, 0x03 },
0135     { 0x4348, 0x16 },
0136     { 0x4350, 0x19 },
0137     { 0x4408, 0x0a },
0138     { 0x440c, 0x0b },
0139     { 0x4411, 0x5f },
0140     { 0x4412, 0x2c },
0141     { 0x4623, 0x00 },
0142     { 0x462c, 0x0f },
0143     { 0x462d, 0x00 },
0144     { 0x462e, 0x00 },
0145     { 0x4684, 0x54 },
0146     { 0x480a, 0x07 },
0147     { 0x4908, 0x07 },
0148     { 0x4909, 0x07 },
0149     { 0x490d, 0x0a },
0150     { 0x491e, 0x0f },
0151     { 0x4921, 0x06 },
0152     { 0x4923, 0x28 },
0153     { 0x4924, 0x28 },
0154     { 0x4925, 0x29 },
0155     { 0x4926, 0x29 },
0156     { 0x4927, 0x1f },
0157     { 0x4928, 0x20 },
0158     { 0x4929, 0x20 },
0159     { 0x492a, 0x20 },
0160     { 0x492c, 0x05 },
0161     { 0x492d, 0x06 },
0162     { 0x492e, 0x06 },
0163     { 0x492f, 0x06 },
0164     { 0x4930, 0x03 },
0165     { 0x4931, 0x04 },
0166     { 0x4932, 0x04 },
0167     { 0x4933, 0x05 },
0168     { 0x595e, 0x01 },
0169     { 0x5963, 0x01 },
0170     { 0x3030, 0x01 },
0171     { 0x3031, 0x01 },
0172     { 0x3045, 0x01 },
0173     { 0x4010, 0x00 },
0174     { 0x4011, 0x00 },
0175     { 0x4012, 0x00 },
0176     { 0x4013, 0x01 },
0177     { 0x68a8, 0xfe },
0178     { 0x68a9, 0xff },
0179     { 0x6888, 0x00 },
0180     { 0x6889, 0x00 },
0181     { 0x68b0, 0x00 },
0182     { 0x3058, 0x00 },
0183     { 0x305a, 0x00 },
0184 };
0185 
0186 static const struct imx355_reg_list imx355_global_setting = {
0187     .num_of_regs = ARRAY_SIZE(imx355_global_regs),
0188     .regs = imx355_global_regs,
0189 };
0190 
0191 static const struct imx355_reg mode_3268x2448_regs[] = {
0192     { 0x0112, 0x0a },
0193     { 0x0113, 0x0a },
0194     { 0x0114, 0x03 },
0195     { 0x0342, 0x0e },
0196     { 0x0343, 0x58 },
0197     { 0x0340, 0x0a },
0198     { 0x0341, 0x37 },
0199     { 0x0344, 0x00 },
0200     { 0x0345, 0x08 },
0201     { 0x0346, 0x00 },
0202     { 0x0347, 0x08 },
0203     { 0x0348, 0x0c },
0204     { 0x0349, 0xcb },
0205     { 0x034a, 0x09 },
0206     { 0x034b, 0x97 },
0207     { 0x0220, 0x00 },
0208     { 0x0222, 0x01 },
0209     { 0x0900, 0x00 },
0210     { 0x0901, 0x11 },
0211     { 0x0902, 0x00 },
0212     { 0x034c, 0x0c },
0213     { 0x034d, 0xc4 },
0214     { 0x034e, 0x09 },
0215     { 0x034f, 0x90 },
0216     { 0x0301, 0x05 },
0217     { 0x0303, 0x01 },
0218     { 0x0305, 0x02 },
0219     { 0x0306, 0x00 },
0220     { 0x0307, 0x78 },
0221     { 0x030b, 0x01 },
0222     { 0x030d, 0x02 },
0223     { 0x030e, 0x00 },
0224     { 0x030f, 0x4b },
0225     { 0x0310, 0x00 },
0226     { 0x0700, 0x00 },
0227     { 0x0701, 0x10 },
0228     { 0x0820, 0x0b },
0229     { 0x0821, 0x40 },
0230     { 0x3088, 0x04 },
0231     { 0x6813, 0x02 },
0232     { 0x6835, 0x07 },
0233     { 0x6836, 0x01 },
0234     { 0x6837, 0x04 },
0235     { 0x684d, 0x07 },
0236     { 0x684e, 0x01 },
0237     { 0x684f, 0x04 },
0238 };
0239 
0240 static const struct imx355_reg mode_3264x2448_regs[] = {
0241     { 0x0112, 0x0a },
0242     { 0x0113, 0x0a },
0243     { 0x0114, 0x03 },
0244     { 0x0342, 0x0e },
0245     { 0x0343, 0x58 },
0246     { 0x0340, 0x0a },
0247     { 0x0341, 0x37 },
0248     { 0x0344, 0x00 },
0249     { 0x0345, 0x08 },
0250     { 0x0346, 0x00 },
0251     { 0x0347, 0x08 },
0252     { 0x0348, 0x0c },
0253     { 0x0349, 0xc7 },
0254     { 0x034a, 0x09 },
0255     { 0x034b, 0x97 },
0256     { 0x0220, 0x00 },
0257     { 0x0222, 0x01 },
0258     { 0x0900, 0x00 },
0259     { 0x0901, 0x11 },
0260     { 0x0902, 0x00 },
0261     { 0x034c, 0x0c },
0262     { 0x034d, 0xc0 },
0263     { 0x034e, 0x09 },
0264     { 0x034f, 0x90 },
0265     { 0x0301, 0x05 },
0266     { 0x0303, 0x01 },
0267     { 0x0305, 0x02 },
0268     { 0x0306, 0x00 },
0269     { 0x0307, 0x78 },
0270     { 0x030b, 0x01 },
0271     { 0x030d, 0x02 },
0272     { 0x030e, 0x00 },
0273     { 0x030f, 0x4b },
0274     { 0x0310, 0x00 },
0275     { 0x0700, 0x00 },
0276     { 0x0701, 0x10 },
0277     { 0x0820, 0x0b },
0278     { 0x0821, 0x40 },
0279     { 0x3088, 0x04 },
0280     { 0x6813, 0x02 },
0281     { 0x6835, 0x07 },
0282     { 0x6836, 0x01 },
0283     { 0x6837, 0x04 },
0284     { 0x684d, 0x07 },
0285     { 0x684e, 0x01 },
0286     { 0x684f, 0x04 },
0287 };
0288 
0289 static const struct imx355_reg mode_3280x2464_regs[] = {
0290     { 0x0112, 0x0a },
0291     { 0x0113, 0x0a },
0292     { 0x0114, 0x03 },
0293     { 0x0342, 0x0e },
0294     { 0x0343, 0x58 },
0295     { 0x0340, 0x0a },
0296     { 0x0341, 0x37 },
0297     { 0x0344, 0x00 },
0298     { 0x0345, 0x00 },
0299     { 0x0346, 0x00 },
0300     { 0x0347, 0x00 },
0301     { 0x0348, 0x0c },
0302     { 0x0349, 0xcf },
0303     { 0x034a, 0x09 },
0304     { 0x034b, 0x9f },
0305     { 0x0220, 0x00 },
0306     { 0x0222, 0x01 },
0307     { 0x0900, 0x00 },
0308     { 0x0901, 0x11 },
0309     { 0x0902, 0x00 },
0310     { 0x034c, 0x0c },
0311     { 0x034d, 0xd0 },
0312     { 0x034e, 0x09 },
0313     { 0x034f, 0xa0 },
0314     { 0x0301, 0x05 },
0315     { 0x0303, 0x01 },
0316     { 0x0305, 0x02 },
0317     { 0x0306, 0x00 },
0318     { 0x0307, 0x78 },
0319     { 0x030b, 0x01 },
0320     { 0x030d, 0x02 },
0321     { 0x030e, 0x00 },
0322     { 0x030f, 0x4b },
0323     { 0x0310, 0x00 },
0324     { 0x0700, 0x00 },
0325     { 0x0701, 0x10 },
0326     { 0x0820, 0x0b },
0327     { 0x0821, 0x40 },
0328     { 0x3088, 0x04 },
0329     { 0x6813, 0x02 },
0330     { 0x6835, 0x07 },
0331     { 0x6836, 0x01 },
0332     { 0x6837, 0x04 },
0333     { 0x684d, 0x07 },
0334     { 0x684e, 0x01 },
0335     { 0x684f, 0x04 },
0336 };
0337 
0338 static const struct imx355_reg mode_1940x1096_regs[] = {
0339     { 0x0112, 0x0a },
0340     { 0x0113, 0x0a },
0341     { 0x0114, 0x03 },
0342     { 0x0342, 0x0e },
0343     { 0x0343, 0x58 },
0344     { 0x0340, 0x05 },
0345     { 0x0341, 0x1a },
0346     { 0x0344, 0x02 },
0347     { 0x0345, 0xa0 },
0348     { 0x0346, 0x02 },
0349     { 0x0347, 0xac },
0350     { 0x0348, 0x0a },
0351     { 0x0349, 0x33 },
0352     { 0x034a, 0x06 },
0353     { 0x034b, 0xf3 },
0354     { 0x0220, 0x00 },
0355     { 0x0222, 0x01 },
0356     { 0x0900, 0x00 },
0357     { 0x0901, 0x11 },
0358     { 0x0902, 0x00 },
0359     { 0x034c, 0x07 },
0360     { 0x034d, 0x94 },
0361     { 0x034e, 0x04 },
0362     { 0x034f, 0x48 },
0363     { 0x0301, 0x05 },
0364     { 0x0303, 0x01 },
0365     { 0x0305, 0x02 },
0366     { 0x0306, 0x00 },
0367     { 0x0307, 0x78 },
0368     { 0x030b, 0x01 },
0369     { 0x030d, 0x02 },
0370     { 0x030e, 0x00 },
0371     { 0x030f, 0x4b },
0372     { 0x0310, 0x00 },
0373     { 0x0700, 0x00 },
0374     { 0x0701, 0x10 },
0375     { 0x0820, 0x0b },
0376     { 0x0821, 0x40 },
0377     { 0x3088, 0x04 },
0378     { 0x6813, 0x02 },
0379     { 0x6835, 0x07 },
0380     { 0x6836, 0x01 },
0381     { 0x6837, 0x04 },
0382     { 0x684d, 0x07 },
0383     { 0x684e, 0x01 },
0384     { 0x684f, 0x04 },
0385 };
0386 
0387 static const struct imx355_reg mode_1936x1096_regs[] = {
0388     { 0x0112, 0x0a },
0389     { 0x0113, 0x0a },
0390     { 0x0114, 0x03 },
0391     { 0x0342, 0x0e },
0392     { 0x0343, 0x58 },
0393     { 0x0340, 0x05 },
0394     { 0x0341, 0x1a },
0395     { 0x0344, 0x02 },
0396     { 0x0345, 0xa0 },
0397     { 0x0346, 0x02 },
0398     { 0x0347, 0xac },
0399     { 0x0348, 0x0a },
0400     { 0x0349, 0x2f },
0401     { 0x034a, 0x06 },
0402     { 0x034b, 0xf3 },
0403     { 0x0220, 0x00 },
0404     { 0x0222, 0x01 },
0405     { 0x0900, 0x00 },
0406     { 0x0901, 0x11 },
0407     { 0x0902, 0x00 },
0408     { 0x034c, 0x07 },
0409     { 0x034d, 0x90 },
0410     { 0x034e, 0x04 },
0411     { 0x034f, 0x48 },
0412     { 0x0301, 0x05 },
0413     { 0x0303, 0x01 },
0414     { 0x0305, 0x02 },
0415     { 0x0306, 0x00 },
0416     { 0x0307, 0x78 },
0417     { 0x030b, 0x01 },
0418     { 0x030d, 0x02 },
0419     { 0x030e, 0x00 },
0420     { 0x030f, 0x4b },
0421     { 0x0310, 0x00 },
0422     { 0x0700, 0x00 },
0423     { 0x0701, 0x10 },
0424     { 0x0820, 0x0b },
0425     { 0x0821, 0x40 },
0426     { 0x3088, 0x04 },
0427     { 0x6813, 0x02 },
0428     { 0x6835, 0x07 },
0429     { 0x6836, 0x01 },
0430     { 0x6837, 0x04 },
0431     { 0x684d, 0x07 },
0432     { 0x684e, 0x01 },
0433     { 0x684f, 0x04 },
0434 };
0435 
0436 static const struct imx355_reg mode_1924x1080_regs[] = {
0437     { 0x0112, 0x0a },
0438     { 0x0113, 0x0a },
0439     { 0x0114, 0x03 },
0440     { 0x0342, 0x0e },
0441     { 0x0343, 0x58 },
0442     { 0x0340, 0x05 },
0443     { 0x0341, 0x1a },
0444     { 0x0344, 0x02 },
0445     { 0x0345, 0xa8 },
0446     { 0x0346, 0x02 },
0447     { 0x0347, 0xb4 },
0448     { 0x0348, 0x0a },
0449     { 0x0349, 0x2b },
0450     { 0x034a, 0x06 },
0451     { 0x034b, 0xeb },
0452     { 0x0220, 0x00 },
0453     { 0x0222, 0x01 },
0454     { 0x0900, 0x00 },
0455     { 0x0901, 0x11 },
0456     { 0x0902, 0x00 },
0457     { 0x034c, 0x07 },
0458     { 0x034d, 0x84 },
0459     { 0x034e, 0x04 },
0460     { 0x034f, 0x38 },
0461     { 0x0301, 0x05 },
0462     { 0x0303, 0x01 },
0463     { 0x0305, 0x02 },
0464     { 0x0306, 0x00 },
0465     { 0x0307, 0x78 },
0466     { 0x030b, 0x01 },
0467     { 0x030d, 0x02 },
0468     { 0x030e, 0x00 },
0469     { 0x030f, 0x4b },
0470     { 0x0310, 0x00 },
0471     { 0x0700, 0x00 },
0472     { 0x0701, 0x10 },
0473     { 0x0820, 0x0b },
0474     { 0x0821, 0x40 },
0475     { 0x3088, 0x04 },
0476     { 0x6813, 0x02 },
0477     { 0x6835, 0x07 },
0478     { 0x6836, 0x01 },
0479     { 0x6837, 0x04 },
0480     { 0x684d, 0x07 },
0481     { 0x684e, 0x01 },
0482     { 0x684f, 0x04 },
0483 };
0484 
0485 static const struct imx355_reg mode_1920x1080_regs[] = {
0486     { 0x0112, 0x0a },
0487     { 0x0113, 0x0a },
0488     { 0x0114, 0x03 },
0489     { 0x0342, 0x0e },
0490     { 0x0343, 0x58 },
0491     { 0x0340, 0x05 },
0492     { 0x0341, 0x1a },
0493     { 0x0344, 0x02 },
0494     { 0x0345, 0xa8 },
0495     { 0x0346, 0x02 },
0496     { 0x0347, 0xb4 },
0497     { 0x0348, 0x0a },
0498     { 0x0349, 0x27 },
0499     { 0x034a, 0x06 },
0500     { 0x034b, 0xeb },
0501     { 0x0220, 0x00 },
0502     { 0x0222, 0x01 },
0503     { 0x0900, 0x00 },
0504     { 0x0901, 0x11 },
0505     { 0x0902, 0x00 },
0506     { 0x034c, 0x07 },
0507     { 0x034d, 0x80 },
0508     { 0x034e, 0x04 },
0509     { 0x034f, 0x38 },
0510     { 0x0301, 0x05 },
0511     { 0x0303, 0x01 },
0512     { 0x0305, 0x02 },
0513     { 0x0306, 0x00 },
0514     { 0x0307, 0x78 },
0515     { 0x030b, 0x01 },
0516     { 0x030d, 0x02 },
0517     { 0x030e, 0x00 },
0518     { 0x030f, 0x4b },
0519     { 0x0310, 0x00 },
0520     { 0x0700, 0x00 },
0521     { 0x0701, 0x10 },
0522     { 0x0820, 0x0b },
0523     { 0x0821, 0x40 },
0524     { 0x3088, 0x04 },
0525     { 0x6813, 0x02 },
0526     { 0x6835, 0x07 },
0527     { 0x6836, 0x01 },
0528     { 0x6837, 0x04 },
0529     { 0x684d, 0x07 },
0530     { 0x684e, 0x01 },
0531     { 0x684f, 0x04 },
0532 };
0533 
0534 static const struct imx355_reg mode_1640x1232_regs[] = {
0535     { 0x0112, 0x0a },
0536     { 0x0113, 0x0a },
0537     { 0x0114, 0x03 },
0538     { 0x0342, 0x07 },
0539     { 0x0343, 0x2c },
0540     { 0x0340, 0x05 },
0541     { 0x0341, 0x1a },
0542     { 0x0344, 0x00 },
0543     { 0x0345, 0x00 },
0544     { 0x0346, 0x00 },
0545     { 0x0347, 0x00 },
0546     { 0x0348, 0x0c },
0547     { 0x0349, 0xcf },
0548     { 0x034a, 0x09 },
0549     { 0x034b, 0x9f },
0550     { 0x0220, 0x00 },
0551     { 0x0222, 0x01 },
0552     { 0x0900, 0x01 },
0553     { 0x0901, 0x22 },
0554     { 0x0902, 0x00 },
0555     { 0x034c, 0x06 },
0556     { 0x034d, 0x68 },
0557     { 0x034e, 0x04 },
0558     { 0x034f, 0xd0 },
0559     { 0x0301, 0x05 },
0560     { 0x0303, 0x01 },
0561     { 0x0305, 0x02 },
0562     { 0x0306, 0x00 },
0563     { 0x0307, 0x78 },
0564     { 0x030b, 0x01 },
0565     { 0x030d, 0x02 },
0566     { 0x030e, 0x00 },
0567     { 0x030f, 0x4b },
0568     { 0x0310, 0x00 },
0569     { 0x0700, 0x00 },
0570     { 0x0701, 0x10 },
0571     { 0x0820, 0x0b },
0572     { 0x0821, 0x40 },
0573     { 0x3088, 0x04 },
0574     { 0x6813, 0x02 },
0575     { 0x6835, 0x07 },
0576     { 0x6836, 0x01 },
0577     { 0x6837, 0x04 },
0578     { 0x684d, 0x07 },
0579     { 0x684e, 0x01 },
0580     { 0x684f, 0x04 },
0581 };
0582 
0583 static const struct imx355_reg mode_1640x922_regs[] = {
0584     { 0x0112, 0x0a },
0585     { 0x0113, 0x0a },
0586     { 0x0114, 0x03 },
0587     { 0x0342, 0x07 },
0588     { 0x0343, 0x2c },
0589     { 0x0340, 0x05 },
0590     { 0x0341, 0x1a },
0591     { 0x0344, 0x00 },
0592     { 0x0345, 0x00 },
0593     { 0x0346, 0x01 },
0594     { 0x0347, 0x30 },
0595     { 0x0348, 0x0c },
0596     { 0x0349, 0xcf },
0597     { 0x034a, 0x08 },
0598     { 0x034b, 0x63 },
0599     { 0x0220, 0x00 },
0600     { 0x0222, 0x01 },
0601     { 0x0900, 0x01 },
0602     { 0x0901, 0x22 },
0603     { 0x0902, 0x00 },
0604     { 0x034c, 0x06 },
0605     { 0x034d, 0x68 },
0606     { 0x034e, 0x03 },
0607     { 0x034f, 0x9a },
0608     { 0x0301, 0x05 },
0609     { 0x0303, 0x01 },
0610     { 0x0305, 0x02 },
0611     { 0x0306, 0x00 },
0612     { 0x0307, 0x78 },
0613     { 0x030b, 0x01 },
0614     { 0x030d, 0x02 },
0615     { 0x030e, 0x00 },
0616     { 0x030f, 0x4b },
0617     { 0x0310, 0x00 },
0618     { 0x0700, 0x00 },
0619     { 0x0701, 0x10 },
0620     { 0x0820, 0x0b },
0621     { 0x0821, 0x40 },
0622     { 0x3088, 0x04 },
0623     { 0x6813, 0x02 },
0624     { 0x6835, 0x07 },
0625     { 0x6836, 0x01 },
0626     { 0x6837, 0x04 },
0627     { 0x684d, 0x07 },
0628     { 0x684e, 0x01 },
0629     { 0x684f, 0x04 },
0630 };
0631 
0632 static const struct imx355_reg mode_1300x736_regs[] = {
0633     { 0x0112, 0x0a },
0634     { 0x0113, 0x0a },
0635     { 0x0114, 0x03 },
0636     { 0x0342, 0x07 },
0637     { 0x0343, 0x2c },
0638     { 0x0340, 0x05 },
0639     { 0x0341, 0x1a },
0640     { 0x0344, 0x01 },
0641     { 0x0345, 0x58 },
0642     { 0x0346, 0x01 },
0643     { 0x0347, 0xf0 },
0644     { 0x0348, 0x0b },
0645     { 0x0349, 0x7f },
0646     { 0x034a, 0x07 },
0647     { 0x034b, 0xaf },
0648     { 0x0220, 0x00 },
0649     { 0x0222, 0x01 },
0650     { 0x0900, 0x01 },
0651     { 0x0901, 0x22 },
0652     { 0x0902, 0x00 },
0653     { 0x034c, 0x05 },
0654     { 0x034d, 0x14 },
0655     { 0x034e, 0x02 },
0656     { 0x034f, 0xe0 },
0657     { 0x0301, 0x05 },
0658     { 0x0303, 0x01 },
0659     { 0x0305, 0x02 },
0660     { 0x0306, 0x00 },
0661     { 0x0307, 0x78 },
0662     { 0x030b, 0x01 },
0663     { 0x030d, 0x02 },
0664     { 0x030e, 0x00 },
0665     { 0x030f, 0x4b },
0666     { 0x0310, 0x00 },
0667     { 0x0700, 0x00 },
0668     { 0x0701, 0x10 },
0669     { 0x0820, 0x0b },
0670     { 0x0821, 0x40 },
0671     { 0x3088, 0x04 },
0672     { 0x6813, 0x02 },
0673     { 0x6835, 0x07 },
0674     { 0x6836, 0x01 },
0675     { 0x6837, 0x04 },
0676     { 0x684d, 0x07 },
0677     { 0x684e, 0x01 },
0678     { 0x684f, 0x04 },
0679 };
0680 
0681 static const struct imx355_reg mode_1296x736_regs[] = {
0682     { 0x0112, 0x0a },
0683     { 0x0113, 0x0a },
0684     { 0x0114, 0x03 },
0685     { 0x0342, 0x07 },
0686     { 0x0343, 0x2c },
0687     { 0x0340, 0x05 },
0688     { 0x0341, 0x1a },
0689     { 0x0344, 0x01 },
0690     { 0x0345, 0x58 },
0691     { 0x0346, 0x01 },
0692     { 0x0347, 0xf0 },
0693     { 0x0348, 0x0b },
0694     { 0x0349, 0x77 },
0695     { 0x034a, 0x07 },
0696     { 0x034b, 0xaf },
0697     { 0x0220, 0x00 },
0698     { 0x0222, 0x01 },
0699     { 0x0900, 0x01 },
0700     { 0x0901, 0x22 },
0701     { 0x0902, 0x00 },
0702     { 0x034c, 0x05 },
0703     { 0x034d, 0x10 },
0704     { 0x034e, 0x02 },
0705     { 0x034f, 0xe0 },
0706     { 0x0301, 0x05 },
0707     { 0x0303, 0x01 },
0708     { 0x0305, 0x02 },
0709     { 0x0306, 0x00 },
0710     { 0x0307, 0x78 },
0711     { 0x030b, 0x01 },
0712     { 0x030d, 0x02 },
0713     { 0x030e, 0x00 },
0714     { 0x030f, 0x4b },
0715     { 0x0310, 0x00 },
0716     { 0x0700, 0x00 },
0717     { 0x0701, 0x10 },
0718     { 0x0820, 0x0b },
0719     { 0x0821, 0x40 },
0720     { 0x3088, 0x04 },
0721     { 0x6813, 0x02 },
0722     { 0x6835, 0x07 },
0723     { 0x6836, 0x01 },
0724     { 0x6837, 0x04 },
0725     { 0x684d, 0x07 },
0726     { 0x684e, 0x01 },
0727     { 0x684f, 0x04 },
0728 };
0729 
0730 static const struct imx355_reg mode_1284x720_regs[] = {
0731     { 0x0112, 0x0a },
0732     { 0x0113, 0x0a },
0733     { 0x0114, 0x03 },
0734     { 0x0342, 0x07 },
0735     { 0x0343, 0x2c },
0736     { 0x0340, 0x05 },
0737     { 0x0341, 0x1a },
0738     { 0x0344, 0x01 },
0739     { 0x0345, 0x68 },
0740     { 0x0346, 0x02 },
0741     { 0x0347, 0x00 },
0742     { 0x0348, 0x0b },
0743     { 0x0349, 0x6f },
0744     { 0x034a, 0x07 },
0745     { 0x034b, 0x9f },
0746     { 0x0220, 0x00 },
0747     { 0x0222, 0x01 },
0748     { 0x0900, 0x01 },
0749     { 0x0901, 0x22 },
0750     { 0x0902, 0x00 },
0751     { 0x034c, 0x05 },
0752     { 0x034d, 0x04 },
0753     { 0x034e, 0x02 },
0754     { 0x034f, 0xd0 },
0755     { 0x0301, 0x05 },
0756     { 0x0303, 0x01 },
0757     { 0x0305, 0x02 },
0758     { 0x0306, 0x00 },
0759     { 0x0307, 0x78 },
0760     { 0x030b, 0x01 },
0761     { 0x030d, 0x02 },
0762     { 0x030e, 0x00 },
0763     { 0x030f, 0x4b },
0764     { 0x0310, 0x00 },
0765     { 0x0700, 0x00 },
0766     { 0x0701, 0x10 },
0767     { 0x0820, 0x0b },
0768     { 0x0821, 0x40 },
0769     { 0x3088, 0x04 },
0770     { 0x6813, 0x02 },
0771     { 0x6835, 0x07 },
0772     { 0x6836, 0x01 },
0773     { 0x6837, 0x04 },
0774     { 0x684d, 0x07 },
0775     { 0x684e, 0x01 },
0776     { 0x684f, 0x04 },
0777 };
0778 
0779 static const struct imx355_reg mode_1280x720_regs[] = {
0780     { 0x0112, 0x0a },
0781     { 0x0113, 0x0a },
0782     { 0x0114, 0x03 },
0783     { 0x0342, 0x07 },
0784     { 0x0343, 0x2c },
0785     { 0x0340, 0x05 },
0786     { 0x0341, 0x1a },
0787     { 0x0344, 0x01 },
0788     { 0x0345, 0x68 },
0789     { 0x0346, 0x02 },
0790     { 0x0347, 0x00 },
0791     { 0x0348, 0x0b },
0792     { 0x0349, 0x67 },
0793     { 0x034a, 0x07 },
0794     { 0x034b, 0x9f },
0795     { 0x0220, 0x00 },
0796     { 0x0222, 0x01 },
0797     { 0x0900, 0x01 },
0798     { 0x0901, 0x22 },
0799     { 0x0902, 0x00 },
0800     { 0x034c, 0x05 },
0801     { 0x034d, 0x00 },
0802     { 0x034e, 0x02 },
0803     { 0x034f, 0xd0 },
0804     { 0x0301, 0x05 },
0805     { 0x0303, 0x01 },
0806     { 0x0305, 0x02 },
0807     { 0x0306, 0x00 },
0808     { 0x0307, 0x78 },
0809     { 0x030b, 0x01 },
0810     { 0x030d, 0x02 },
0811     { 0x030e, 0x00 },
0812     { 0x030f, 0x4b },
0813     { 0x0310, 0x00 },
0814     { 0x0700, 0x00 },
0815     { 0x0701, 0x10 },
0816     { 0x0820, 0x0b },
0817     { 0x0821, 0x40 },
0818     { 0x3088, 0x04 },
0819     { 0x6813, 0x02 },
0820     { 0x6835, 0x07 },
0821     { 0x6836, 0x01 },
0822     { 0x6837, 0x04 },
0823     { 0x684d, 0x07 },
0824     { 0x684e, 0x01 },
0825     { 0x684f, 0x04 },
0826 };
0827 
0828 static const struct imx355_reg mode_820x616_regs[] = {
0829     { 0x0112, 0x0a },
0830     { 0x0113, 0x0a },
0831     { 0x0114, 0x03 },
0832     { 0x0342, 0x0e },
0833     { 0x0343, 0x58 },
0834     { 0x0340, 0x02 },
0835     { 0x0341, 0x8c },
0836     { 0x0344, 0x00 },
0837     { 0x0345, 0x00 },
0838     { 0x0346, 0x00 },
0839     { 0x0347, 0x00 },
0840     { 0x0348, 0x0c },
0841     { 0x0349, 0xcf },
0842     { 0x034a, 0x09 },
0843     { 0x034b, 0x9f },
0844     { 0x0220, 0x00 },
0845     { 0x0222, 0x01 },
0846     { 0x0900, 0x01 },
0847     { 0x0901, 0x44 },
0848     { 0x0902, 0x00 },
0849     { 0x034c, 0x03 },
0850     { 0x034d, 0x34 },
0851     { 0x034e, 0x02 },
0852     { 0x034f, 0x68 },
0853     { 0x0301, 0x05 },
0854     { 0x0303, 0x01 },
0855     { 0x0305, 0x02 },
0856     { 0x0306, 0x00 },
0857     { 0x0307, 0x78 },
0858     { 0x030b, 0x01 },
0859     { 0x030d, 0x02 },
0860     { 0x030e, 0x00 },
0861     { 0x030f, 0x4b },
0862     { 0x0310, 0x00 },
0863     { 0x0700, 0x02 },
0864     { 0x0701, 0x78 },
0865     { 0x0820, 0x0b },
0866     { 0x0821, 0x40 },
0867     { 0x3088, 0x04 },
0868     { 0x6813, 0x02 },
0869     { 0x6835, 0x07 },
0870     { 0x6836, 0x01 },
0871     { 0x6837, 0x04 },
0872     { 0x684d, 0x07 },
0873     { 0x684e, 0x01 },
0874     { 0x684f, 0x04 },
0875 };
0876 
0877 static const char * const imx355_test_pattern_menu[] = {
0878     "Disabled",
0879     "Solid Colour",
0880     "Eight Vertical Colour Bars",
0881     "Colour Bars With Fade to Grey",
0882     "Pseudorandom Sequence (PN9)",
0883 };
0884 
0885 /* supported link frequencies */
0886 static const s64 link_freq_menu_items[] = {
0887     IMX355_LINK_FREQ_DEFAULT,
0888 };
0889 
0890 /* Mode configs */
0891 static const struct imx355_mode supported_modes[] = {
0892     {
0893         .width = 3280,
0894         .height = 2464,
0895         .fll_def = 2615,
0896         .fll_min = 2615,
0897         .llp = 3672,
0898         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0899         .reg_list = {
0900             .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
0901             .regs = mode_3280x2464_regs,
0902         },
0903     },
0904     {
0905         .width = 3268,
0906         .height = 2448,
0907         .fll_def = 2615,
0908         .fll_min = 2615,
0909         .llp = 3672,
0910         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0911         .reg_list = {
0912             .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
0913             .regs = mode_3268x2448_regs,
0914         },
0915     },
0916     {
0917         .width = 3264,
0918         .height = 2448,
0919         .fll_def = 2615,
0920         .fll_min = 2615,
0921         .llp = 3672,
0922         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0923         .reg_list = {
0924             .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
0925             .regs = mode_3264x2448_regs,
0926         },
0927     },
0928     {
0929         .width = 1940,
0930         .height = 1096,
0931         .fll_def = 1306,
0932         .fll_min = 1306,
0933         .llp = 3672,
0934         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0935         .reg_list = {
0936             .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
0937             .regs = mode_1940x1096_regs,
0938         },
0939     },
0940     {
0941         .width = 1936,
0942         .height = 1096,
0943         .fll_def = 1306,
0944         .fll_min = 1306,
0945         .llp = 3672,
0946         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0947         .reg_list = {
0948             .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
0949             .regs = mode_1936x1096_regs,
0950         },
0951     },
0952     {
0953         .width = 1924,
0954         .height = 1080,
0955         .fll_def = 1306,
0956         .fll_min = 1306,
0957         .llp = 3672,
0958         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0959         .reg_list = {
0960             .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
0961             .regs = mode_1924x1080_regs,
0962         },
0963     },
0964     {
0965         .width = 1920,
0966         .height = 1080,
0967         .fll_def = 1306,
0968         .fll_min = 1306,
0969         .llp = 3672,
0970         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0971         .reg_list = {
0972             .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
0973             .regs = mode_1920x1080_regs,
0974         },
0975     },
0976     {
0977         .width = 1640,
0978         .height = 1232,
0979         .fll_def = 1306,
0980         .fll_min = 1306,
0981         .llp = 1836,
0982         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0983         .reg_list = {
0984             .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
0985             .regs = mode_1640x1232_regs,
0986         },
0987     },
0988     {
0989         .width = 1640,
0990         .height = 922,
0991         .fll_def = 1306,
0992         .fll_min = 1306,
0993         .llp = 1836,
0994         .link_freq_index = IMX355_LINK_FREQ_INDEX,
0995         .reg_list = {
0996             .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
0997             .regs = mode_1640x922_regs,
0998         },
0999     },
1000     {
1001         .width = 1300,
1002         .height = 736,
1003         .fll_def = 1306,
1004         .fll_min = 1306,
1005         .llp = 1836,
1006         .link_freq_index = IMX355_LINK_FREQ_INDEX,
1007         .reg_list = {
1008             .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
1009             .regs = mode_1300x736_regs,
1010         },
1011     },
1012     {
1013         .width = 1296,
1014         .height = 736,
1015         .fll_def = 1306,
1016         .fll_min = 1306,
1017         .llp = 1836,
1018         .link_freq_index = IMX355_LINK_FREQ_INDEX,
1019         .reg_list = {
1020             .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
1021             .regs = mode_1296x736_regs,
1022         },
1023     },
1024     {
1025         .width = 1284,
1026         .height = 720,
1027         .fll_def = 1306,
1028         .fll_min = 1306,
1029         .llp = 1836,
1030         .link_freq_index = IMX355_LINK_FREQ_INDEX,
1031         .reg_list = {
1032             .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
1033             .regs = mode_1284x720_regs,
1034         },
1035     },
1036     {
1037         .width = 1280,
1038         .height = 720,
1039         .fll_def = 1306,
1040         .fll_min = 1306,
1041         .llp = 1836,
1042         .link_freq_index = IMX355_LINK_FREQ_INDEX,
1043         .reg_list = {
1044             .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
1045             .regs = mode_1280x720_regs,
1046         },
1047     },
1048     {
1049         .width = 820,
1050         .height = 616,
1051         .fll_def = 652,
1052         .fll_min = 652,
1053         .llp = 3672,
1054         .link_freq_index = IMX355_LINK_FREQ_INDEX,
1055         .reg_list = {
1056             .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
1057             .regs = mode_820x616_regs,
1058         },
1059     },
1060 };
1061 
1062 static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd)
1063 {
1064     return container_of(_sd, struct imx355, sd);
1065 }
1066 
1067 /* Get bayer order based on flip setting. */
1068 static u32 imx355_get_format_code(struct imx355 *imx355)
1069 {
1070     /*
1071      * Only one bayer order is supported.
1072      * It depends on the flip settings.
1073      */
1074     u32 code;
1075     static const u32 codes[2][2] = {
1076         { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
1077         { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
1078     };
1079 
1080     lockdep_assert_held(&imx355->mutex);
1081     code = codes[imx355->vflip->val][imx355->hflip->val];
1082 
1083     return code;
1084 }
1085 
1086 /* Read registers up to 4 at a time */
1087 static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
1088 {
1089     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1090     struct i2c_msg msgs[2];
1091     u8 addr_buf[2];
1092     u8 data_buf[4] = { 0 };
1093     int ret;
1094 
1095     if (len > 4)
1096         return -EINVAL;
1097 
1098     put_unaligned_be16(reg, addr_buf);
1099     /* Write register address */
1100     msgs[0].addr = client->addr;
1101     msgs[0].flags = 0;
1102     msgs[0].len = ARRAY_SIZE(addr_buf);
1103     msgs[0].buf = addr_buf;
1104 
1105     /* Read data from register */
1106     msgs[1].addr = client->addr;
1107     msgs[1].flags = I2C_M_RD;
1108     msgs[1].len = len;
1109     msgs[1].buf = &data_buf[4 - len];
1110 
1111     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1112     if (ret != ARRAY_SIZE(msgs))
1113         return -EIO;
1114 
1115     *val = get_unaligned_be32(data_buf);
1116 
1117     return 0;
1118 }
1119 
1120 /* Write registers up to 4 at a time */
1121 static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
1122 {
1123     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1124     u8 buf[6];
1125 
1126     if (len > 4)
1127         return -EINVAL;
1128 
1129     put_unaligned_be16(reg, buf);
1130     put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1131     if (i2c_master_send(client, buf, len + 2) != len + 2)
1132         return -EIO;
1133 
1134     return 0;
1135 }
1136 
1137 /* Write a list of registers */
1138 static int imx355_write_regs(struct imx355 *imx355,
1139                  const struct imx355_reg *regs, u32 len)
1140 {
1141     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1142     int ret;
1143     u32 i;
1144 
1145     for (i = 0; i < len; i++) {
1146         ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
1147         if (ret) {
1148             dev_err_ratelimited(&client->dev,
1149                         "write reg 0x%4.4x return err %d",
1150                         regs[i].address, ret);
1151 
1152             return ret;
1153         }
1154     }
1155 
1156     return 0;
1157 }
1158 
1159 /* Open sub-device */
1160 static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1161 {
1162     struct imx355 *imx355 = to_imx355(sd);
1163     struct v4l2_mbus_framefmt *try_fmt =
1164         v4l2_subdev_get_try_format(sd, fh->state, 0);
1165 
1166     mutex_lock(&imx355->mutex);
1167 
1168     /* Initialize try_fmt */
1169     try_fmt->width = imx355->cur_mode->width;
1170     try_fmt->height = imx355->cur_mode->height;
1171     try_fmt->code = imx355_get_format_code(imx355);
1172     try_fmt->field = V4L2_FIELD_NONE;
1173 
1174     mutex_unlock(&imx355->mutex);
1175 
1176     return 0;
1177 }
1178 
1179 static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
1180 {
1181     struct imx355 *imx355 = container_of(ctrl->handler,
1182                          struct imx355, ctrl_handler);
1183     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1184     s64 max;
1185     int ret;
1186 
1187     /* Propagate change of current control to all related controls */
1188     switch (ctrl->id) {
1189     case V4L2_CID_VBLANK:
1190         /* Update max exposure while meeting expected vblanking */
1191         max = imx355->cur_mode->height + ctrl->val - 10;
1192         __v4l2_ctrl_modify_range(imx355->exposure,
1193                      imx355->exposure->minimum,
1194                      max, imx355->exposure->step, max);
1195         break;
1196     }
1197 
1198     /*
1199      * Applying V4L2 control value only happens
1200      * when power is up for streaming
1201      */
1202     if (!pm_runtime_get_if_in_use(&client->dev))
1203         return 0;
1204 
1205     switch (ctrl->id) {
1206     case V4L2_CID_ANALOGUE_GAIN:
1207         /* Analog gain = 1024/(1024 - ctrl->val) times */
1208         ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
1209                        ctrl->val);
1210         break;
1211     case V4L2_CID_DIGITAL_GAIN:
1212         ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
1213                        ctrl->val);
1214         break;
1215     case V4L2_CID_EXPOSURE:
1216         ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
1217                        ctrl->val);
1218         break;
1219     case V4L2_CID_VBLANK:
1220         /* Update FLL that meets expected vertical blanking */
1221         ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
1222                        imx355->cur_mode->height + ctrl->val);
1223         break;
1224     case V4L2_CID_TEST_PATTERN:
1225         ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
1226                        2, ctrl->val);
1227         break;
1228     case V4L2_CID_HFLIP:
1229     case V4L2_CID_VFLIP:
1230         ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
1231                        imx355->hflip->val |
1232                        imx355->vflip->val << 1);
1233         break;
1234     default:
1235         ret = -EINVAL;
1236         dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
1237              ctrl->id, ctrl->val);
1238         break;
1239     }
1240 
1241     pm_runtime_put(&client->dev);
1242 
1243     return ret;
1244 }
1245 
1246 static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
1247     .s_ctrl = imx355_set_ctrl,
1248 };
1249 
1250 static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
1251                  struct v4l2_subdev_state *sd_state,
1252                  struct v4l2_subdev_mbus_code_enum *code)
1253 {
1254     struct imx355 *imx355 = to_imx355(sd);
1255 
1256     if (code->index > 0)
1257         return -EINVAL;
1258 
1259     mutex_lock(&imx355->mutex);
1260     code->code = imx355_get_format_code(imx355);
1261     mutex_unlock(&imx355->mutex);
1262 
1263     return 0;
1264 }
1265 
1266 static int imx355_enum_frame_size(struct v4l2_subdev *sd,
1267                   struct v4l2_subdev_state *sd_state,
1268                   struct v4l2_subdev_frame_size_enum *fse)
1269 {
1270     struct imx355 *imx355 = to_imx355(sd);
1271 
1272     if (fse->index >= ARRAY_SIZE(supported_modes))
1273         return -EINVAL;
1274 
1275     mutex_lock(&imx355->mutex);
1276     if (fse->code != imx355_get_format_code(imx355)) {
1277         mutex_unlock(&imx355->mutex);
1278         return -EINVAL;
1279     }
1280     mutex_unlock(&imx355->mutex);
1281 
1282     fse->min_width = supported_modes[fse->index].width;
1283     fse->max_width = fse->min_width;
1284     fse->min_height = supported_modes[fse->index].height;
1285     fse->max_height = fse->min_height;
1286 
1287     return 0;
1288 }
1289 
1290 static void imx355_update_pad_format(struct imx355 *imx355,
1291                      const struct imx355_mode *mode,
1292                      struct v4l2_subdev_format *fmt)
1293 {
1294     fmt->format.width = mode->width;
1295     fmt->format.height = mode->height;
1296     fmt->format.code = imx355_get_format_code(imx355);
1297     fmt->format.field = V4L2_FIELD_NONE;
1298 }
1299 
1300 static int imx355_do_get_pad_format(struct imx355 *imx355,
1301                     struct v4l2_subdev_state *sd_state,
1302                     struct v4l2_subdev_format *fmt)
1303 {
1304     struct v4l2_mbus_framefmt *framefmt;
1305     struct v4l2_subdev *sd = &imx355->sd;
1306 
1307     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1308         framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
1309         fmt->format = *framefmt;
1310     } else {
1311         imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
1312     }
1313 
1314     return 0;
1315 }
1316 
1317 static int imx355_get_pad_format(struct v4l2_subdev *sd,
1318                  struct v4l2_subdev_state *sd_state,
1319                  struct v4l2_subdev_format *fmt)
1320 {
1321     struct imx355 *imx355 = to_imx355(sd);
1322     int ret;
1323 
1324     mutex_lock(&imx355->mutex);
1325     ret = imx355_do_get_pad_format(imx355, sd_state, fmt);
1326     mutex_unlock(&imx355->mutex);
1327 
1328     return ret;
1329 }
1330 
1331 static int
1332 imx355_set_pad_format(struct v4l2_subdev *sd,
1333               struct v4l2_subdev_state *sd_state,
1334               struct v4l2_subdev_format *fmt)
1335 {
1336     struct imx355 *imx355 = to_imx355(sd);
1337     const struct imx355_mode *mode;
1338     struct v4l2_mbus_framefmt *framefmt;
1339     s32 vblank_def;
1340     s32 vblank_min;
1341     s64 h_blank;
1342     u64 pixel_rate;
1343     u32 height;
1344 
1345     mutex_lock(&imx355->mutex);
1346 
1347     /*
1348      * Only one bayer order is supported.
1349      * It depends on the flip settings.
1350      */
1351     fmt->format.code = imx355_get_format_code(imx355);
1352 
1353     mode = v4l2_find_nearest_size(supported_modes,
1354                       ARRAY_SIZE(supported_modes),
1355                       width, height,
1356                       fmt->format.width, fmt->format.height);
1357     imx355_update_pad_format(imx355, mode, fmt);
1358     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1359         framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
1360         *framefmt = fmt->format;
1361     } else {
1362         imx355->cur_mode = mode;
1363         pixel_rate = imx355->link_def_freq * 2 * 4;
1364         do_div(pixel_rate, 10);
1365         __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
1366         /* Update limits and set FPS to default */
1367         height = imx355->cur_mode->height;
1368         vblank_def = imx355->cur_mode->fll_def - height;
1369         vblank_min = imx355->cur_mode->fll_min - height;
1370         height = IMX355_FLL_MAX - height;
1371         __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
1372                      vblank_def);
1373         __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
1374         h_blank = mode->llp - imx355->cur_mode->width;
1375         /*
1376          * Currently hblank is not changeable.
1377          * So FPS control is done only by vblank.
1378          */
1379         __v4l2_ctrl_modify_range(imx355->hblank, h_blank,
1380                      h_blank, 1, h_blank);
1381     }
1382 
1383     mutex_unlock(&imx355->mutex);
1384 
1385     return 0;
1386 }
1387 
1388 /* Start streaming */
1389 static int imx355_start_streaming(struct imx355 *imx355)
1390 {
1391     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1392     const struct imx355_reg_list *reg_list;
1393     int ret;
1394 
1395     /* Global Setting */
1396     reg_list = &imx355_global_setting;
1397     ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1398     if (ret) {
1399         dev_err(&client->dev, "failed to set global settings");
1400         return ret;
1401     }
1402 
1403     /* Apply default values of current mode */
1404     reg_list = &imx355->cur_mode->reg_list;
1405     ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1406     if (ret) {
1407         dev_err(&client->dev, "failed to set mode");
1408         return ret;
1409     }
1410 
1411     /* set digital gain control to all color mode */
1412     ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
1413     if (ret)
1414         return ret;
1415 
1416     /* Apply customized values from user */
1417     ret =  __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
1418     if (ret)
1419         return ret;
1420 
1421     return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1422                 1, IMX355_MODE_STREAMING);
1423 }
1424 
1425 /* Stop streaming */
1426 static int imx355_stop_streaming(struct imx355 *imx355)
1427 {
1428     return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1429                 1, IMX355_MODE_STANDBY);
1430 }
1431 
1432 static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
1433 {
1434     struct imx355 *imx355 = to_imx355(sd);
1435     struct i2c_client *client = v4l2_get_subdevdata(sd);
1436     int ret = 0;
1437 
1438     mutex_lock(&imx355->mutex);
1439     if (imx355->streaming == enable) {
1440         mutex_unlock(&imx355->mutex);
1441         return 0;
1442     }
1443 
1444     if (enable) {
1445         ret = pm_runtime_resume_and_get(&client->dev);
1446         if (ret < 0)
1447             goto err_unlock;
1448 
1449         /*
1450          * Apply default & customized values
1451          * and then start streaming.
1452          */
1453         ret = imx355_start_streaming(imx355);
1454         if (ret)
1455             goto err_rpm_put;
1456     } else {
1457         imx355_stop_streaming(imx355);
1458         pm_runtime_put(&client->dev);
1459     }
1460 
1461     imx355->streaming = enable;
1462 
1463     /* vflip and hflip cannot change during streaming */
1464     __v4l2_ctrl_grab(imx355->vflip, enable);
1465     __v4l2_ctrl_grab(imx355->hflip, enable);
1466 
1467     mutex_unlock(&imx355->mutex);
1468 
1469     return ret;
1470 
1471 err_rpm_put:
1472     pm_runtime_put(&client->dev);
1473 err_unlock:
1474     mutex_unlock(&imx355->mutex);
1475 
1476     return ret;
1477 }
1478 
1479 static int __maybe_unused imx355_suspend(struct device *dev)
1480 {
1481     struct v4l2_subdev *sd = dev_get_drvdata(dev);
1482     struct imx355 *imx355 = to_imx355(sd);
1483 
1484     if (imx355->streaming)
1485         imx355_stop_streaming(imx355);
1486 
1487     return 0;
1488 }
1489 
1490 static int __maybe_unused imx355_resume(struct device *dev)
1491 {
1492     struct v4l2_subdev *sd = dev_get_drvdata(dev);
1493     struct imx355 *imx355 = to_imx355(sd);
1494     int ret;
1495 
1496     if (imx355->streaming) {
1497         ret = imx355_start_streaming(imx355);
1498         if (ret)
1499             goto error;
1500     }
1501 
1502     return 0;
1503 
1504 error:
1505     imx355_stop_streaming(imx355);
1506     imx355->streaming = 0;
1507     return ret;
1508 }
1509 
1510 /* Verify chip ID */
1511 static int imx355_identify_module(struct imx355 *imx355)
1512 {
1513     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1514     int ret;
1515     u32 val;
1516 
1517     ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
1518     if (ret)
1519         return ret;
1520 
1521     if (val != IMX355_CHIP_ID) {
1522         dev_err(&client->dev, "chip id mismatch: %x!=%x",
1523             IMX355_CHIP_ID, val);
1524         return -EIO;
1525     }
1526     return 0;
1527 }
1528 
1529 static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
1530     .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1531     .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1532 };
1533 
1534 static const struct v4l2_subdev_video_ops imx355_video_ops = {
1535     .s_stream = imx355_set_stream,
1536 };
1537 
1538 static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
1539     .enum_mbus_code = imx355_enum_mbus_code,
1540     .get_fmt = imx355_get_pad_format,
1541     .set_fmt = imx355_set_pad_format,
1542     .enum_frame_size = imx355_enum_frame_size,
1543 };
1544 
1545 static const struct v4l2_subdev_ops imx355_subdev_ops = {
1546     .core = &imx355_subdev_core_ops,
1547     .video = &imx355_video_ops,
1548     .pad = &imx355_pad_ops,
1549 };
1550 
1551 static const struct media_entity_operations imx355_subdev_entity_ops = {
1552     .link_validate = v4l2_subdev_link_validate,
1553 };
1554 
1555 static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
1556     .open = imx355_open,
1557 };
1558 
1559 /* Initialize control handlers */
1560 static int imx355_init_controls(struct imx355 *imx355)
1561 {
1562     struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1563     struct v4l2_ctrl_handler *ctrl_hdlr;
1564     s64 exposure_max;
1565     s64 vblank_def;
1566     s64 vblank_min;
1567     s64 hblank;
1568     u64 pixel_rate;
1569     const struct imx355_mode *mode;
1570     u32 max;
1571     int ret;
1572 
1573     ctrl_hdlr = &imx355->ctrl_handler;
1574     ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
1575     if (ret)
1576         return ret;
1577 
1578     ctrl_hdlr->lock = &imx355->mutex;
1579     max = ARRAY_SIZE(link_freq_menu_items) - 1;
1580     imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
1581                            V4L2_CID_LINK_FREQ, max, 0,
1582                            link_freq_menu_items);
1583     if (imx355->link_freq)
1584         imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1585 
1586     /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
1587     pixel_rate = imx355->link_def_freq * 2 * 4;
1588     do_div(pixel_rate, 10);
1589     /* By default, PIXEL_RATE is read only */
1590     imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1591                            V4L2_CID_PIXEL_RATE, pixel_rate,
1592                            pixel_rate, 1, pixel_rate);
1593 
1594     /* Initialize vblank/hblank/exposure parameters based on current mode */
1595     mode = imx355->cur_mode;
1596     vblank_def = mode->fll_def - mode->height;
1597     vblank_min = mode->fll_min - mode->height;
1598     imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1599                        V4L2_CID_VBLANK, vblank_min,
1600                        IMX355_FLL_MAX - mode->height,
1601                        1, vblank_def);
1602 
1603     hblank = mode->llp - mode->width;
1604     imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1605                        V4L2_CID_HBLANK, hblank, hblank,
1606                        1, hblank);
1607     if (imx355->hblank)
1608         imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1609 
1610     /* fll >= exposure time + adjust parameter (default value is 10) */
1611     exposure_max = mode->fll_def - 10;
1612     imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1613                          V4L2_CID_EXPOSURE,
1614                          IMX355_EXPOSURE_MIN, exposure_max,
1615                          IMX355_EXPOSURE_STEP,
1616                          IMX355_EXPOSURE_DEFAULT);
1617 
1618     imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1619                       V4L2_CID_HFLIP, 0, 1, 1, 0);
1620     imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1621                       V4L2_CID_VFLIP, 0, 1, 1, 0);
1622 
1623     v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1624               IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
1625               IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
1626 
1627     /* Digital gain */
1628     v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1629               IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
1630               IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
1631 
1632     v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
1633                      V4L2_CID_TEST_PATTERN,
1634                      ARRAY_SIZE(imx355_test_pattern_menu) - 1,
1635                      0, 0, imx355_test_pattern_menu);
1636     if (ctrl_hdlr->error) {
1637         ret = ctrl_hdlr->error;
1638         dev_err(&client->dev, "control init failed: %d", ret);
1639         goto error;
1640     }
1641 
1642     imx355->sd.ctrl_handler = ctrl_hdlr;
1643 
1644     return 0;
1645 
1646 error:
1647     v4l2_ctrl_handler_free(ctrl_hdlr);
1648 
1649     return ret;
1650 }
1651 
1652 static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
1653 {
1654     struct imx355_hwcfg *cfg;
1655     struct v4l2_fwnode_endpoint bus_cfg = {
1656         .bus_type = V4L2_MBUS_CSI2_DPHY
1657     };
1658     struct fwnode_handle *ep;
1659     struct fwnode_handle *fwnode = dev_fwnode(dev);
1660     unsigned int i;
1661     int ret;
1662 
1663     if (!fwnode)
1664         return NULL;
1665 
1666     ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1667     if (!ep)
1668         return NULL;
1669 
1670     ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1671     if (ret)
1672         goto out_err;
1673 
1674     cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
1675     if (!cfg)
1676         goto out_err;
1677 
1678     ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
1679                        &cfg->ext_clk);
1680     if (ret) {
1681         dev_err(dev, "can't get clock frequency");
1682         goto out_err;
1683     }
1684 
1685     dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
1686     if (cfg->ext_clk != IMX355_EXT_CLK) {
1687         dev_err(dev, "external clock %d is not supported",
1688             cfg->ext_clk);
1689         goto out_err;
1690     }
1691 
1692     dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
1693     if (!bus_cfg.nr_of_link_frequencies) {
1694         dev_warn(dev, "no link frequencies defined");
1695         goto out_err;
1696     }
1697 
1698     cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
1699     cfg->link_freqs = devm_kcalloc(dev,
1700                        bus_cfg.nr_of_link_frequencies + 1,
1701                        sizeof(*cfg->link_freqs), GFP_KERNEL);
1702     if (!cfg->link_freqs)
1703         goto out_err;
1704 
1705     for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
1706         cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
1707         dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
1708     }
1709 
1710     v4l2_fwnode_endpoint_free(&bus_cfg);
1711     fwnode_handle_put(ep);
1712     return cfg;
1713 
1714 out_err:
1715     v4l2_fwnode_endpoint_free(&bus_cfg);
1716     fwnode_handle_put(ep);
1717     return NULL;
1718 }
1719 
1720 static int imx355_probe(struct i2c_client *client)
1721 {
1722     struct imx355 *imx355;
1723     int ret;
1724     u32 i;
1725 
1726     imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
1727     if (!imx355)
1728         return -ENOMEM;
1729 
1730     mutex_init(&imx355->mutex);
1731 
1732     /* Initialize subdev */
1733     v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
1734 
1735     /* Check module identity */
1736     ret = imx355_identify_module(imx355);
1737     if (ret) {
1738         dev_err(&client->dev, "failed to find sensor: %d", ret);
1739         goto error_probe;
1740     }
1741 
1742     imx355->hwcfg = imx355_get_hwcfg(&client->dev);
1743     if (!imx355->hwcfg) {
1744         dev_err(&client->dev, "failed to get hwcfg");
1745         ret = -ENODEV;
1746         goto error_probe;
1747     }
1748 
1749     imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
1750     for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
1751         if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
1752             dev_dbg(&client->dev, "link freq index %d matched", i);
1753             break;
1754         }
1755     }
1756 
1757     if (i == imx355->hwcfg->nr_of_link_freqs) {
1758         dev_err(&client->dev, "no link frequency supported");
1759         ret = -EINVAL;
1760         goto error_probe;
1761     }
1762 
1763     /* Set default mode to max resolution */
1764     imx355->cur_mode = &supported_modes[0];
1765 
1766     ret = imx355_init_controls(imx355);
1767     if (ret) {
1768         dev_err(&client->dev, "failed to init controls: %d", ret);
1769         goto error_probe;
1770     }
1771 
1772     /* Initialize subdev */
1773     imx355->sd.internal_ops = &imx355_internal_ops;
1774     imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1775         V4L2_SUBDEV_FL_HAS_EVENTS;
1776     imx355->sd.entity.ops = &imx355_subdev_entity_ops;
1777     imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1778 
1779     /* Initialize source pad */
1780     imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
1781     ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
1782     if (ret) {
1783         dev_err(&client->dev, "failed to init entity pads: %d", ret);
1784         goto error_handler_free;
1785     }
1786 
1787     ret = v4l2_async_register_subdev_sensor(&imx355->sd);
1788     if (ret < 0)
1789         goto error_media_entity;
1790 
1791     /*
1792      * Device is already turned on by i2c-core with ACPI domain PM.
1793      * Enable runtime PM and turn off the device.
1794      */
1795     pm_runtime_set_active(&client->dev);
1796     pm_runtime_enable(&client->dev);
1797     pm_runtime_idle(&client->dev);
1798 
1799     return 0;
1800 
1801 error_media_entity:
1802     media_entity_cleanup(&imx355->sd.entity);
1803 
1804 error_handler_free:
1805     v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
1806 
1807 error_probe:
1808     mutex_destroy(&imx355->mutex);
1809 
1810     return ret;
1811 }
1812 
1813 static int imx355_remove(struct i2c_client *client)
1814 {
1815     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1816     struct imx355 *imx355 = to_imx355(sd);
1817 
1818     v4l2_async_unregister_subdev(sd);
1819     media_entity_cleanup(&sd->entity);
1820     v4l2_ctrl_handler_free(sd->ctrl_handler);
1821 
1822     pm_runtime_disable(&client->dev);
1823     pm_runtime_set_suspended(&client->dev);
1824 
1825     mutex_destroy(&imx355->mutex);
1826 
1827     return 0;
1828 }
1829 
1830 static const struct dev_pm_ops imx355_pm_ops = {
1831     SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
1832 };
1833 
1834 static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
1835     { "SONY355A" },
1836     { /* sentinel */ }
1837 };
1838 MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
1839 
1840 static struct i2c_driver imx355_i2c_driver = {
1841     .driver = {
1842         .name = "imx355",
1843         .pm = &imx355_pm_ops,
1844         .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
1845     },
1846     .probe_new = imx355_probe,
1847     .remove = imx355_remove,
1848 };
1849 module_i2c_driver(imx355_i2c_driver);
1850 
1851 MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
1852 MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
1853 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1854 MODULE_AUTHOR("Yang, Hyungwoo");
1855 MODULE_DESCRIPTION("Sony imx355 sensor driver");
1856 MODULE_LICENSE("GPL v2");