Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2021 Purism SPC
0003 
0004 #include <asm/unaligned.h>
0005 #include <linux/clk.h>
0006 #include <linux/delay.h>
0007 #include <linux/gpio/consumer.h>
0008 #include <linux/i2c.h>
0009 #include <linux/module.h>
0010 #include <linux/pm_runtime.h>
0011 #include <linux/pm.h>
0012 #include <linux/property.h>
0013 #include <linux/regulator/consumer.h>
0014 #include <media/v4l2-ctrls.h>
0015 #include <media/v4l2-device.h>
0016 #include <media/v4l2-fwnode.h>
0017 
0018 #define HI846_MEDIA_BUS_FORMAT      MEDIA_BUS_FMT_SGBRG10_1X10
0019 #define HI846_RGB_DEPTH         10
0020 
0021 /* Frame length lines / vertical timings */
0022 #define HI846_REG_FLL           0x0006
0023 #define HI846_FLL_MAX           0xffff
0024 
0025 /* Horizontal timing */
0026 #define HI846_REG_LLP           0x0008
0027 #define HI846_LINE_LENGTH       3800
0028 
0029 #define HI846_REG_BINNING_MODE      0x000c
0030 
0031 #define HI846_REG_IMAGE_ORIENTATION 0x000e
0032 
0033 #define HI846_REG_UNKNOWN_0022      0x0022
0034 
0035 #define HI846_REG_Y_ADDR_START_VACT_H   0x0026
0036 #define HI846_REG_Y_ADDR_START_VACT_L   0x0027
0037 #define HI846_REG_UNKNOWN_0028      0x0028
0038 
0039 #define HI846_REG_Y_ADDR_END_VACT_H 0x002c
0040 #define HI846_REG_Y_ADDR_END_VACT_L 0x002d
0041 
0042 #define HI846_REG_Y_ODD_INC_FOBP    0x002e
0043 #define HI846_REG_Y_EVEN_INC_FOBP   0x002f
0044 
0045 #define HI846_REG_Y_ODD_INC_VACT    0x0032
0046 #define HI846_REG_Y_EVEN_INC_VACT   0x0033
0047 
0048 #define HI846_REG_GROUPED_PARA_HOLD 0x0046
0049 
0050 #define HI846_REG_TG_ENABLE     0x004c
0051 
0052 #define HI846_REG_UNKNOWN_005C      0x005c
0053 
0054 #define HI846_REG_UNKNOWN_006A      0x006a
0055 
0056 /*
0057  * Long exposure time. Actually, exposure is a 20 bit value that
0058  * includes the lower 4 bits of 0x0073 too. Only 16 bits are used
0059  * right now
0060  */
0061 #define HI846_REG_EXPOSURE      0x0074
0062 #define HI846_EXPOSURE_MIN      6
0063 #define HI846_EXPOSURE_MAX_MARGIN   2
0064 #define HI846_EXPOSURE_STEP     1
0065 
0066 /* Analog gain controls from sensor */
0067 #define HI846_REG_ANALOG_GAIN       0x0077
0068 #define HI846_ANAL_GAIN_MIN     0
0069 #define HI846_ANAL_GAIN_MAX     240
0070 #define HI846_ANAL_GAIN_STEP        8
0071 
0072 /* Digital gain controls from sensor */
0073 #define HI846_REG_MWB_GR_GAIN_H     0x0078
0074 #define HI846_REG_MWB_GR_GAIN_L     0x0079
0075 #define HI846_REG_MWB_GB_GAIN_H     0x007a
0076 #define HI846_REG_MWB_GB_GAIN_L     0x007b
0077 #define HI846_REG_MWB_R_GAIN_H      0x007c
0078 #define HI846_REG_MWB_R_GAIN_L      0x007d
0079 #define HI846_REG_MWB_B_GAIN_H      0x007e
0080 #define HI846_REG_MWB_B_GAIN_L      0x007f
0081 #define HI846_DGTL_GAIN_MIN     512
0082 #define HI846_DGTL_GAIN_MAX     8191
0083 #define HI846_DGTL_GAIN_STEP        1
0084 #define HI846_DGTL_GAIN_DEFAULT     512
0085 
0086 #define HI846_REG_X_ADDR_START_HACT_H   0x0120
0087 #define HI846_REG_X_ADDR_END_HACT_H 0x0122
0088 
0089 #define HI846_REG_UNKNOWN_012A      0x012a
0090 
0091 #define HI846_REG_UNKNOWN_0200      0x0200
0092 
0093 #define HI846_REG_UNKNOWN_021C      0x021c
0094 #define HI846_REG_UNKNOWN_021E      0x021e
0095 
0096 #define HI846_REG_UNKNOWN_0402      0x0402
0097 #define HI846_REG_UNKNOWN_0404      0x0404
0098 #define HI846_REG_UNKNOWN_0408      0x0408
0099 #define HI846_REG_UNKNOWN_0410      0x0410
0100 #define HI846_REG_UNKNOWN_0412      0x0412
0101 #define HI846_REG_UNKNOWN_0414      0x0414
0102 
0103 #define HI846_REG_UNKNOWN_0418      0x0418
0104 
0105 #define HI846_REG_UNKNOWN_051E      0x051e
0106 
0107 /* Formatter */
0108 #define HI846_REG_X_START_H     0x0804
0109 #define HI846_REG_X_START_L     0x0805
0110 
0111 /* MIPI */
0112 #define HI846_REG_UNKNOWN_0900      0x0900
0113 #define HI846_REG_MIPI_TX_OP_EN     0x0901
0114 #define HI846_REG_MIPI_TX_OP_MODE   0x0902
0115 #define HI846_RAW8          BIT(5)
0116 
0117 #define HI846_REG_UNKNOWN_090C      0x090c
0118 #define HI846_REG_UNKNOWN_090E      0x090e
0119 
0120 #define HI846_REG_UNKNOWN_0914      0x0914
0121 #define HI846_REG_TLPX          0x0915
0122 #define HI846_REG_TCLK_PREPARE      0x0916
0123 #define HI846_REG_TCLK_ZERO     0x0917
0124 #define HI846_REG_UNKNOWN_0918      0x0918
0125 #define HI846_REG_THS_PREPARE       0x0919
0126 #define HI846_REG_THS_ZERO      0x091a
0127 #define HI846_REG_THS_TRAIL     0x091b
0128 #define HI846_REG_TCLK_POST     0x091c
0129 #define HI846_REG_TCLK_TRAIL_MIN    0x091d
0130 #define HI846_REG_UNKNOWN_091E      0x091e
0131 
0132 #define HI846_REG_UNKNOWN_0954      0x0954
0133 #define HI846_REG_UNKNOWN_0956      0x0956
0134 #define HI846_REG_UNKNOWN_0958      0x0958
0135 #define HI846_REG_UNKNOWN_095A      0x095a
0136 
0137 /* ISP Common */
0138 #define HI846_REG_MODE_SELECT       0x0a00
0139 #define HI846_MODE_STANDBY      0x00
0140 #define HI846_MODE_STREAMING        0x01
0141 #define HI846_REG_FAST_STANDBY_MODE 0x0a02
0142 #define HI846_REG_ISP_EN_H      0x0a04
0143 
0144 /* Test Pattern Control */
0145 #define HI846_REG_ISP           0x0a05
0146 #define HI846_REG_ISP_TPG_EN        0x01
0147 #define HI846_REG_TEST_PATTERN      0x020a /* 1-9 */
0148 
0149 #define HI846_REG_UNKNOWN_0A0C      0x0a0c
0150 
0151 /* Windowing */
0152 #define HI846_REG_X_OUTPUT_SIZE_H   0x0a12
0153 #define HI846_REG_X_OUTPUT_SIZE_L   0x0a13
0154 #define HI846_REG_Y_OUTPUT_SIZE_H   0x0a14
0155 #define HI846_REG_Y_OUTPUT_SIZE_L   0x0a15
0156 
0157 /* ISP Common */
0158 #define HI846_REG_PEDESTAL_EN       0x0a1a
0159 
0160 #define HI846_REG_UNKNOWN_0A1E      0x0a1e
0161 
0162 /* Horizontal Binning Mode */
0163 #define HI846_REG_HBIN_MODE     0x0a22
0164 
0165 #define HI846_REG_UNKNOWN_0A24      0x0a24
0166 #define HI846_REG_UNKNOWN_0B02      0x0b02
0167 #define HI846_REG_UNKNOWN_0B10      0x0b10
0168 #define HI846_REG_UNKNOWN_0B12      0x0b12
0169 #define HI846_REG_UNKNOWN_0B14      0x0b14
0170 
0171 /* BLC (Black Level Calibration) */
0172 #define HI846_REG_BLC_CTL0      0x0c00
0173 
0174 #define HI846_REG_UNKNOWN_0C06      0x0c06
0175 #define HI846_REG_UNKNOWN_0C10      0x0c10
0176 #define HI846_REG_UNKNOWN_0C12      0x0c12
0177 #define HI846_REG_UNKNOWN_0C14      0x0c14
0178 #define HI846_REG_UNKNOWN_0C16      0x0c16
0179 
0180 #define HI846_REG_UNKNOWN_0E04      0x0e04
0181 
0182 #define HI846_REG_CHIP_ID_L     0x0f16
0183 #define HI846_REG_CHIP_ID_H     0x0f17
0184 #define HI846_CHIP_ID_L         0x46
0185 #define HI846_CHIP_ID_H         0x08
0186 
0187 #define HI846_REG_UNKNOWN_0F04      0x0f04
0188 #define HI846_REG_UNKNOWN_0F08      0x0f08
0189 
0190 /* PLL */
0191 #define HI846_REG_PLL_CFG_MIPI2_H   0x0f2a
0192 #define HI846_REG_PLL_CFG_MIPI2_L   0x0f2b
0193 
0194 #define HI846_REG_UNKNOWN_0F30      0x0f30
0195 #define HI846_REG_PLL_CFG_RAMP1_H   0x0f32
0196 #define HI846_REG_UNKNOWN_0F36      0x0f36
0197 #define HI846_REG_PLL_CFG_MIPI1_H   0x0f38
0198 
0199 #define HI846_REG_UNKNOWN_2008      0x2008
0200 #define HI846_REG_UNKNOWN_326E      0x326e
0201 
0202 struct hi846_reg {
0203     u16 address;
0204     u16 val;
0205 };
0206 
0207 struct hi846_reg_list {
0208     u32 num_of_regs;
0209     const struct hi846_reg *regs;
0210 };
0211 
0212 struct hi846_mode {
0213     /* Frame width in pixels */
0214     u32 width;
0215 
0216     /* Frame height in pixels */
0217     u32 height;
0218 
0219     /* Horizontal timing size */
0220     u32 llp;
0221 
0222     /* Link frequency needed for this resolution */
0223     u8 link_freq_index;
0224 
0225     u16 fps;
0226 
0227     /* Vertical timining size */
0228     u16 frame_len;
0229 
0230     const struct hi846_reg_list reg_list_config;
0231     const struct hi846_reg_list reg_list_2lane;
0232     const struct hi846_reg_list reg_list_4lane;
0233 
0234     /* Position inside of the 3264x2448 pixel array */
0235     struct v4l2_rect crop;
0236 };
0237 
0238 static const struct hi846_reg hi846_init_2lane[] = {
0239     {HI846_REG_MODE_SELECT,     0x0000},
0240     /* regs below are unknown */
0241     {0x2000, 0x100a},
0242     {0x2002, 0x00ff},
0243     {0x2004, 0x0007},
0244     {0x2006, 0x3fff},
0245     {0x2008, 0x3fff},
0246     {0x200a, 0xc216},
0247     {0x200c, 0x1292},
0248     {0x200e, 0xc01a},
0249     {0x2010, 0x403d},
0250     {0x2012, 0x000e},
0251     {0x2014, 0x403e},
0252     {0x2016, 0x0b80},
0253     {0x2018, 0x403f},
0254     {0x201a, 0x82ae},
0255     {0x201c, 0x1292},
0256     {0x201e, 0xc00c},
0257     {0x2020, 0x4130},
0258     {0x2022, 0x43e2},
0259     {0x2024, 0x0180},
0260     {0x2026, 0x4130},
0261     {0x2028, 0x7400},
0262     {0x202a, 0x5000},
0263     {0x202c, 0x0253},
0264     {0x202e, 0x0ad1},
0265     {0x2030, 0x2360},
0266     {0x2032, 0x0009},
0267     {0x2034, 0x5020},
0268     {0x2036, 0x000b},
0269     {0x2038, 0x0002},
0270     {0x203a, 0x0044},
0271     {0x203c, 0x0016},
0272     {0x203e, 0x1792},
0273     {0x2040, 0x7002},
0274     {0x2042, 0x154f},
0275     {0x2044, 0x00d5},
0276     {0x2046, 0x000b},
0277     {0x2048, 0x0019},
0278     {0x204a, 0x1698},
0279     {0x204c, 0x000e},
0280     {0x204e, 0x099a},
0281     {0x2050, 0x0058},
0282     {0x2052, 0x7000},
0283     {0x2054, 0x1799},
0284     {0x2056, 0x0310},
0285     {0x2058, 0x03c3},
0286     {0x205a, 0x004c},
0287     {0x205c, 0x064a},
0288     {0x205e, 0x0001},
0289     {0x2060, 0x0007},
0290     {0x2062, 0x0bc7},
0291     {0x2064, 0x0055},
0292     {0x2066, 0x7000},
0293     {0x2068, 0x1550},
0294     {0x206a, 0x158a},
0295     {0x206c, 0x0004},
0296     {0x206e, 0x1488},
0297     {0x2070, 0x7010},
0298     {0x2072, 0x1508},
0299     {0x2074, 0x0004},
0300     {0x2076, 0x0016},
0301     {0x2078, 0x03d5},
0302     {0x207a, 0x0055},
0303     {0x207c, 0x08ca},
0304     {0x207e, 0x2019},
0305     {0x2080, 0x0007},
0306     {0x2082, 0x7057},
0307     {0x2084, 0x0fc7},
0308     {0x2086, 0x5041},
0309     {0x2088, 0x12c8},
0310     {0x208a, 0x5060},
0311     {0x208c, 0x5080},
0312     {0x208e, 0x2084},
0313     {0x2090, 0x12c8},
0314     {0x2092, 0x7800},
0315     {0x2094, 0x0802},
0316     {0x2096, 0x040f},
0317     {0x2098, 0x1007},
0318     {0x209a, 0x0803},
0319     {0x209c, 0x080b},
0320     {0x209e, 0x3803},
0321     {0x20a0, 0x0807},
0322     {0x20a2, 0x0404},
0323     {0x20a4, 0x0400},
0324     {0x20a6, 0xffff},
0325     {0x20a8, 0xf0b2},
0326     {0x20aa, 0xffef},
0327     {0x20ac, 0x0a84},
0328     {0x20ae, 0x1292},
0329     {0x20b0, 0xc02e},
0330     {0x20b2, 0x4130},
0331     {0x23fe, 0xc056},
0332     {0x3232, 0xfc0c},
0333     {0x3236, 0xfc22},
0334     {0x3248, 0xfca8},
0335     {0x326a, 0x8302},
0336     {0x326c, 0x830a},
0337     {0x326e, 0x0000},
0338     {0x32ca, 0xfc28},
0339     {0x32cc, 0xc3bc},
0340     {0x32ce, 0xc34c},
0341     {0x32d0, 0xc35a},
0342     {0x32d2, 0xc368},
0343     {0x32d4, 0xc376},
0344     {0x32d6, 0xc3c2},
0345     {0x32d8, 0xc3e6},
0346     {0x32da, 0x0003},
0347     {0x32dc, 0x0003},
0348     {0x32de, 0x00c7},
0349     {0x32e0, 0x0031},
0350     {0x32e2, 0x0031},
0351     {0x32e4, 0x0031},
0352     {0x32e6, 0xfc28},
0353     {0x32e8, 0xc3bc},
0354     {0x32ea, 0xc384},
0355     {0x32ec, 0xc392},
0356     {0x32ee, 0xc3a0},
0357     {0x32f0, 0xc3ae},
0358     {0x32f2, 0xc3c4},
0359     {0x32f4, 0xc3e6},
0360     {0x32f6, 0x0003},
0361     {0x32f8, 0x0003},
0362     {0x32fa, 0x00c7},
0363     {0x32fc, 0x0031},
0364     {0x32fe, 0x0031},
0365     {0x3300, 0x0031},
0366     {0x3302, 0x82ca},
0367     {0x3304, 0xc164},
0368     {0x3306, 0x82e6},
0369     {0x3308, 0xc19c},
0370     {0x330a, 0x001f},
0371     {0x330c, 0x001a},
0372     {0x330e, 0x0034},
0373     {0x3310, 0x0000},
0374     {0x3312, 0x0000},
0375     {0x3314, 0xfc94},
0376     {0x3316, 0xc3d8},
0377     /* regs above are unknown */
0378     {HI846_REG_MODE_SELECT,         0x0000},
0379     {HI846_REG_UNKNOWN_0E04,        0x0012},
0380     {HI846_REG_Y_ODD_INC_FOBP,      0x1111},
0381     {HI846_REG_Y_ODD_INC_VACT,      0x1111},
0382     {HI846_REG_UNKNOWN_0022,        0x0008},
0383     {HI846_REG_Y_ADDR_START_VACT_H,     0x0040},
0384     {HI846_REG_UNKNOWN_0028,        0x0017},
0385     {HI846_REG_Y_ADDR_END_VACT_H,       0x09cf},
0386     {HI846_REG_UNKNOWN_005C,        0x2101},
0387     {HI846_REG_FLL,             0x09de},
0388     {HI846_REG_LLP,             0x0ed8},
0389     {HI846_REG_IMAGE_ORIENTATION,       0x0100},
0390     {HI846_REG_BINNING_MODE,        0x0022},
0391     {HI846_REG_HBIN_MODE,           0x0000},
0392     {HI846_REG_UNKNOWN_0A24,        0x0000},
0393     {HI846_REG_X_START_H,           0x0000},
0394     {HI846_REG_X_OUTPUT_SIZE_H,     0x0cc0},
0395     {HI846_REG_Y_OUTPUT_SIZE_H,     0x0990},
0396     {HI846_REG_EXPOSURE,            0x09d8},
0397     {HI846_REG_ANALOG_GAIN,         0x0000},
0398     {HI846_REG_GROUPED_PARA_HOLD,       0x0000},
0399     {HI846_REG_UNKNOWN_051E,        0x0000},
0400     {HI846_REG_UNKNOWN_0200,        0x0400},
0401     {HI846_REG_PEDESTAL_EN,         0x0c00},
0402     {HI846_REG_UNKNOWN_0A0C,        0x0010},
0403     {HI846_REG_UNKNOWN_0A1E,        0x0ccf},
0404     {HI846_REG_UNKNOWN_0402,        0x0110},
0405     {HI846_REG_UNKNOWN_0404,        0x00f4},
0406     {HI846_REG_UNKNOWN_0408,        0x0000},
0407     {HI846_REG_UNKNOWN_0410,        0x008d},
0408     {HI846_REG_UNKNOWN_0412,        0x011a},
0409     {HI846_REG_UNKNOWN_0414,        0x864c},
0410     {HI846_REG_UNKNOWN_021C,        0x0003},
0411     {HI846_REG_UNKNOWN_021E,        0x0235},
0412     {HI846_REG_BLC_CTL0,            0x9150},
0413     {HI846_REG_UNKNOWN_0C06,        0x0021},
0414     {HI846_REG_UNKNOWN_0C10,        0x0040},
0415     {HI846_REG_UNKNOWN_0C12,        0x0040},
0416     {HI846_REG_UNKNOWN_0C14,        0x0040},
0417     {HI846_REG_UNKNOWN_0C16,        0x0040},
0418     {HI846_REG_FAST_STANDBY_MODE,       0x0100},
0419     {HI846_REG_ISP_EN_H,            0x014a},
0420     {HI846_REG_UNKNOWN_0418,        0x0000},
0421     {HI846_REG_UNKNOWN_012A,        0x03b4},
0422     {HI846_REG_X_ADDR_START_HACT_H,     0x0046},
0423     {HI846_REG_X_ADDR_END_HACT_H,       0x0376},
0424     {HI846_REG_UNKNOWN_0B02,        0xe04d},
0425     {HI846_REG_UNKNOWN_0B10,        0x6821},
0426     {HI846_REG_UNKNOWN_0B12,        0x0120},
0427     {HI846_REG_UNKNOWN_0B14,        0x0001},
0428     {HI846_REG_UNKNOWN_2008,        0x38fd},
0429     {HI846_REG_UNKNOWN_326E,        0x0000},
0430     {HI846_REG_UNKNOWN_0900,        0x0320},
0431     {HI846_REG_MIPI_TX_OP_MODE,     0xc31a},
0432     {HI846_REG_UNKNOWN_0914,        0xc109},
0433     {HI846_REG_TCLK_PREPARE,        0x061a},
0434     {HI846_REG_UNKNOWN_0918,        0x0306},
0435     {HI846_REG_THS_ZERO,            0x0b09},
0436     {HI846_REG_TCLK_POST,           0x0c07},
0437     {HI846_REG_UNKNOWN_091E,        0x0a00},
0438     {HI846_REG_UNKNOWN_090C,        0x042a},
0439     {HI846_REG_UNKNOWN_090E,        0x006b},
0440     {HI846_REG_UNKNOWN_0954,        0x0089},
0441     {HI846_REG_UNKNOWN_0956,        0x0000},
0442     {HI846_REG_UNKNOWN_0958,        0xca00},
0443     {HI846_REG_UNKNOWN_095A,        0x9240},
0444     {HI846_REG_UNKNOWN_0F08,        0x2f04},
0445     {HI846_REG_UNKNOWN_0F30,        0x001f},
0446     {HI846_REG_UNKNOWN_0F36,        0x001f},
0447     {HI846_REG_UNKNOWN_0F04,        0x3a00},
0448     {HI846_REG_PLL_CFG_RAMP1_H,     0x025a},
0449     {HI846_REG_PLL_CFG_MIPI1_H,     0x025a},
0450     {HI846_REG_PLL_CFG_MIPI2_H,     0x0024},
0451     {HI846_REG_UNKNOWN_006A,        0x0100},
0452     {HI846_REG_TG_ENABLE,           0x0100},
0453 };
0454 
0455 static const struct hi846_reg hi846_init_4lane[] = {
0456     {0x2000, 0x987a},
0457     {0x2002, 0x00ff},
0458     {0x2004, 0x0047},
0459     {0x2006, 0x3fff},
0460     {0x2008, 0x3fff},
0461     {0x200a, 0xc216},
0462     {0x200c, 0x1292},
0463     {0x200e, 0xc01a},
0464     {0x2010, 0x403d},
0465     {0x2012, 0x000e},
0466     {0x2014, 0x403e},
0467     {0x2016, 0x0b80},
0468     {0x2018, 0x403f},
0469     {0x201a, 0x82ae},
0470     {0x201c, 0x1292},
0471     {0x201e, 0xc00c},
0472     {0x2020, 0x4130},
0473     {0x2022, 0x43e2},
0474     {0x2024, 0x0180},
0475     {0x2026, 0x4130},
0476     {0x2028, 0x7400},
0477     {0x202a, 0x5000},
0478     {0x202c, 0x0253},
0479     {0x202e, 0x0ad1},
0480     {0x2030, 0x2360},
0481     {0x2032, 0x0009},
0482     {0x2034, 0x5020},
0483     {0x2036, 0x000b},
0484     {0x2038, 0x0002},
0485     {0x203a, 0x0044},
0486     {0x203c, 0x0016},
0487     {0x203e, 0x1792},
0488     {0x2040, 0x7002},
0489     {0x2042, 0x154f},
0490     {0x2044, 0x00d5},
0491     {0x2046, 0x000b},
0492     {0x2048, 0x0019},
0493     {0x204a, 0x1698},
0494     {0x204c, 0x000e},
0495     {0x204e, 0x099a},
0496     {0x2050, 0x0058},
0497     {0x2052, 0x7000},
0498     {0x2054, 0x1799},
0499     {0x2056, 0x0310},
0500     {0x2058, 0x03c3},
0501     {0x205a, 0x004c},
0502     {0x205c, 0x064a},
0503     {0x205e, 0x0001},
0504     {0x2060, 0x0007},
0505     {0x2062, 0x0bc7},
0506     {0x2064, 0x0055},
0507     {0x2066, 0x7000},
0508     {0x2068, 0x1550},
0509     {0x206a, 0x158a},
0510     {0x206c, 0x0004},
0511     {0x206e, 0x1488},
0512     {0x2070, 0x7010},
0513     {0x2072, 0x1508},
0514     {0x2074, 0x0004},
0515     {0x2076, 0x0016},
0516     {0x2078, 0x03d5},
0517     {0x207a, 0x0055},
0518     {0x207c, 0x08ca},
0519     {0x207e, 0x2019},
0520     {0x2080, 0x0007},
0521     {0x2082, 0x7057},
0522     {0x2084, 0x0fc7},
0523     {0x2086, 0x5041},
0524     {0x2088, 0x12c8},
0525     {0x208a, 0x5060},
0526     {0x208c, 0x5080},
0527     {0x208e, 0x2084},
0528     {0x2090, 0x12c8},
0529     {0x2092, 0x7800},
0530     {0x2094, 0x0802},
0531     {0x2096, 0x040f},
0532     {0x2098, 0x1007},
0533     {0x209a, 0x0803},
0534     {0x209c, 0x080b},
0535     {0x209e, 0x3803},
0536     {0x20a0, 0x0807},
0537     {0x20a2, 0x0404},
0538     {0x20a4, 0x0400},
0539     {0x20a6, 0xffff},
0540     {0x20a8, 0xf0b2},
0541     {0x20aa, 0xffef},
0542     {0x20ac, 0x0a84},
0543     {0x20ae, 0x1292},
0544     {0x20b0, 0xc02e},
0545     {0x20b2, 0x4130},
0546     {0x20b4, 0xf0b2},
0547     {0x20b6, 0xffbf},
0548     {0x20b8, 0x2004},
0549     {0x20ba, 0x403f},
0550     {0x20bc, 0x00c3},
0551     {0x20be, 0x4fe2},
0552     {0x20c0, 0x8318},
0553     {0x20c2, 0x43cf},
0554     {0x20c4, 0x0000},
0555     {0x20c6, 0x9382},
0556     {0x20c8, 0xc314},
0557     {0x20ca, 0x2003},
0558     {0x20cc, 0x12b0},
0559     {0x20ce, 0xcab0},
0560     {0x20d0, 0x4130},
0561     {0x20d2, 0x12b0},
0562     {0x20d4, 0xc90a},
0563     {0x20d6, 0x4130},
0564     {0x20d8, 0x42d2},
0565     {0x20da, 0x8318},
0566     {0x20dc, 0x00c3},
0567     {0x20de, 0x9382},
0568     {0x20e0, 0xc314},
0569     {0x20e2, 0x2009},
0570     {0x20e4, 0x120b},
0571     {0x20e6, 0x120a},
0572     {0x20e8, 0x1209},
0573     {0x20ea, 0x1208},
0574     {0x20ec, 0x1207},
0575     {0x20ee, 0x1206},
0576     {0x20f0, 0x4030},
0577     {0x20f2, 0xc15e},
0578     {0x20f4, 0x4130},
0579     {0x20f6, 0x1292},
0580     {0x20f8, 0xc008},
0581     {0x20fa, 0x4130},
0582     {0x20fc, 0x42d2},
0583     {0x20fe, 0x82a1},
0584     {0x2100, 0x00c2},
0585     {0x2102, 0x1292},
0586     {0x2104, 0xc040},
0587     {0x2106, 0x4130},
0588     {0x2108, 0x1292},
0589     {0x210a, 0xc006},
0590     {0x210c, 0x42a2},
0591     {0x210e, 0x7324},
0592     {0x2110, 0x9382},
0593     {0x2112, 0xc314},
0594     {0x2114, 0x2011},
0595     {0x2116, 0x425f},
0596     {0x2118, 0x82a1},
0597     {0x211a, 0xf25f},
0598     {0x211c, 0x00c1},
0599     {0x211e, 0xf35f},
0600     {0x2120, 0x2406},
0601     {0x2122, 0x425f},
0602     {0x2124, 0x00c0},
0603     {0x2126, 0xf37f},
0604     {0x2128, 0x522f},
0605     {0x212a, 0x4f82},
0606     {0x212c, 0x7324},
0607     {0x212e, 0x425f},
0608     {0x2130, 0x82d4},
0609     {0x2132, 0xf35f},
0610     {0x2134, 0x4fc2},
0611     {0x2136, 0x01b3},
0612     {0x2138, 0x93c2},
0613     {0x213a, 0x829f},
0614     {0x213c, 0x2421},
0615     {0x213e, 0x403e},
0616     {0x2140, 0xfffe},
0617     {0x2142, 0x40b2},
0618     {0x2144, 0xec78},
0619     {0x2146, 0x831c},
0620     {0x2148, 0x40b2},
0621     {0x214a, 0xec78},
0622     {0x214c, 0x831e},
0623     {0x214e, 0x40b2},
0624     {0x2150, 0xec78},
0625     {0x2152, 0x8320},
0626     {0x2154, 0xb3d2},
0627     {0x2156, 0x008c},
0628     {0x2158, 0x2405},
0629     {0x215a, 0x4e0f},
0630     {0x215c, 0x503f},
0631     {0x215e, 0xffd8},
0632     {0x2160, 0x4f82},
0633     {0x2162, 0x831c},
0634     {0x2164, 0x90f2},
0635     {0x2166, 0x0003},
0636     {0x2168, 0x008c},
0637     {0x216a, 0x2401},
0638     {0x216c, 0x4130},
0639     {0x216e, 0x421f},
0640     {0x2170, 0x831c},
0641     {0x2172, 0x5e0f},
0642     {0x2174, 0x4f82},
0643     {0x2176, 0x831e},
0644     {0x2178, 0x5e0f},
0645     {0x217a, 0x4f82},
0646     {0x217c, 0x8320},
0647     {0x217e, 0x3ff6},
0648     {0x2180, 0x432e},
0649     {0x2182, 0x3fdf},
0650     {0x2184, 0x421f},
0651     {0x2186, 0x7100},
0652     {0x2188, 0x4f0e},
0653     {0x218a, 0x503e},
0654     {0x218c, 0xffd8},
0655     {0x218e, 0x4e82},
0656     {0x2190, 0x7a04},
0657     {0x2192, 0x421e},
0658     {0x2194, 0x831c},
0659     {0x2196, 0x5f0e},
0660     {0x2198, 0x4e82},
0661     {0x219a, 0x7a06},
0662     {0x219c, 0x0b00},
0663     {0x219e, 0x7304},
0664     {0x21a0, 0x0050},
0665     {0x21a2, 0x40b2},
0666     {0x21a4, 0xd081},
0667     {0x21a6, 0x0b88},
0668     {0x21a8, 0x421e},
0669     {0x21aa, 0x831e},
0670     {0x21ac, 0x5f0e},
0671     {0x21ae, 0x4e82},
0672     {0x21b0, 0x7a0e},
0673     {0x21b2, 0x521f},
0674     {0x21b4, 0x8320},
0675     {0x21b6, 0x4f82},
0676     {0x21b8, 0x7a10},
0677     {0x21ba, 0x0b00},
0678     {0x21bc, 0x7304},
0679     {0x21be, 0x007a},
0680     {0x21c0, 0x40b2},
0681     {0x21c2, 0x0081},
0682     {0x21c4, 0x0b88},
0683     {0x21c6, 0x4392},
0684     {0x21c8, 0x7a0a},
0685     {0x21ca, 0x0800},
0686     {0x21cc, 0x7a0c},
0687     {0x21ce, 0x0b00},
0688     {0x21d0, 0x7304},
0689     {0x21d2, 0x022b},
0690     {0x21d4, 0x40b2},
0691     {0x21d6, 0xd081},
0692     {0x21d8, 0x0b88},
0693     {0x21da, 0x0b00},
0694     {0x21dc, 0x7304},
0695     {0x21de, 0x0255},
0696     {0x21e0, 0x40b2},
0697     {0x21e2, 0x0081},
0698     {0x21e4, 0x0b88},
0699     {0x21e6, 0x4130},
0700     {0x23fe, 0xc056},
0701     {0x3232, 0xfc0c},
0702     {0x3236, 0xfc22},
0703     {0x3238, 0xfcfc},
0704     {0x323a, 0xfd84},
0705     {0x323c, 0xfd08},
0706     {0x3246, 0xfcd8},
0707     {0x3248, 0xfca8},
0708     {0x324e, 0xfcb4},
0709     {0x326a, 0x8302},
0710     {0x326c, 0x830a},
0711     {0x326e, 0x0000},
0712     {0x32ca, 0xfc28},
0713     {0x32cc, 0xc3bc},
0714     {0x32ce, 0xc34c},
0715     {0x32d0, 0xc35a},
0716     {0x32d2, 0xc368},
0717     {0x32d4, 0xc376},
0718     {0x32d6, 0xc3c2},
0719     {0x32d8, 0xc3e6},
0720     {0x32da, 0x0003},
0721     {0x32dc, 0x0003},
0722     {0x32de, 0x00c7},
0723     {0x32e0, 0x0031},
0724     {0x32e2, 0x0031},
0725     {0x32e4, 0x0031},
0726     {0x32e6, 0xfc28},
0727     {0x32e8, 0xc3bc},
0728     {0x32ea, 0xc384},
0729     {0x32ec, 0xc392},
0730     {0x32ee, 0xc3a0},
0731     {0x32f0, 0xc3ae},
0732     {0x32f2, 0xc3c4},
0733     {0x32f4, 0xc3e6},
0734     {0x32f6, 0x0003},
0735     {0x32f8, 0x0003},
0736     {0x32fa, 0x00c7},
0737     {0x32fc, 0x0031},
0738     {0x32fe, 0x0031},
0739     {0x3300, 0x0031},
0740     {0x3302, 0x82ca},
0741     {0x3304, 0xc164},
0742     {0x3306, 0x82e6},
0743     {0x3308, 0xc19c},
0744     {0x330a, 0x001f},
0745     {0x330c, 0x001a},
0746     {0x330e, 0x0034},
0747     {0x3310, 0x0000},
0748     {0x3312, 0x0000},
0749     {0x3314, 0xfc94},
0750     {0x3316, 0xc3d8},
0751 
0752     {0x0a00, 0x0000},
0753     {0x0e04, 0x0012},
0754     {0x002e, 0x1111},
0755     {0x0032, 0x1111},
0756     {0x0022, 0x0008},
0757     {0x0026, 0x0040},
0758     {0x0028, 0x0017},
0759     {0x002c, 0x09cf},
0760     {0x005c, 0x2101},
0761     {0x0006, 0x09de},
0762     {0x0008, 0x0ed8},
0763     {0x000e, 0x0100},
0764     {0x000c, 0x0022},
0765     {0x0a22, 0x0000},
0766     {0x0a24, 0x0000},
0767     {0x0804, 0x0000},
0768     {0x0a12, 0x0cc0},
0769     {0x0a14, 0x0990},
0770     {0x0074, 0x09d8},
0771     {0x0076, 0x0000},
0772     {0x051e, 0x0000},
0773     {0x0200, 0x0400},
0774     {0x0a1a, 0x0c00},
0775     {0x0a0c, 0x0010},
0776     {0x0a1e, 0x0ccf},
0777     {0x0402, 0x0110},
0778     {0x0404, 0x00f4},
0779     {0x0408, 0x0000},
0780     {0x0410, 0x008d},
0781     {0x0412, 0x011a},
0782     {0x0414, 0x864c},
0783     /* for OTP */
0784     {0x021c, 0x0003},
0785     {0x021e, 0x0235},
0786     /* for OTP */
0787     {0x0c00, 0x9950},
0788     {0x0c06, 0x0021},
0789     {0x0c10, 0x0040},
0790     {0x0c12, 0x0040},
0791     {0x0c14, 0x0040},
0792     {0x0c16, 0x0040},
0793     {0x0a02, 0x0100},
0794     {0x0a04, 0x015a},
0795     {0x0418, 0x0000},
0796     {0x0128, 0x0028},
0797     {0x012a, 0xffff},
0798     {0x0120, 0x0046},
0799     {0x0122, 0x0376},
0800     {0x012c, 0x0020},
0801     {0x012e, 0xffff},
0802     {0x0124, 0x0040},
0803     {0x0126, 0x0378},
0804     {0x0746, 0x0050},
0805     {0x0748, 0x01d5},
0806     {0x074a, 0x022b},
0807     {0x074c, 0x03b0},
0808     {0x0756, 0x043f},
0809     {0x0758, 0x3f1d},
0810     {0x0b02, 0xe04d},
0811     {0x0b10, 0x6821},
0812     {0x0b12, 0x0120},
0813     {0x0b14, 0x0001},
0814     {0x2008, 0x38fd},
0815     {0x326e, 0x0000},
0816     {0x0900, 0x0300},
0817     {0x0902, 0xc319},
0818     {0x0914, 0xc109},
0819     {0x0916, 0x061a},
0820     {0x0918, 0x0407},
0821     {0x091a, 0x0a0b},
0822     {0x091c, 0x0e08},
0823     {0x091e, 0x0a00},
0824     {0x090c, 0x0427},
0825     {0x090e, 0x0059},
0826     {0x0954, 0x0089},
0827     {0x0956, 0x0000},
0828     {0x0958, 0xca80},
0829     {0x095a, 0x9240},
0830     {0x0f08, 0x2f04},
0831     {0x0f30, 0x001f},
0832     {0x0f36, 0x001f},
0833     {0x0f04, 0x3a00},
0834     {0x0f32, 0x025a},
0835     {0x0f38, 0x025a},
0836     {0x0f2a, 0x4124},
0837     {0x006a, 0x0100},
0838     {0x004c, 0x0100},
0839     {0x0044, 0x0001},
0840 };
0841 
0842 static const struct hi846_reg mode_640x480_config[] = {
0843     {HI846_REG_MODE_SELECT,         0x0000},
0844     {HI846_REG_Y_ODD_INC_FOBP,      0x7711},
0845     {HI846_REG_Y_ODD_INC_VACT,      0x7711},
0846     {HI846_REG_Y_ADDR_START_VACT_H,     0x0148},
0847     {HI846_REG_Y_ADDR_END_VACT_H,       0x08c7},
0848     {HI846_REG_UNKNOWN_005C,        0x4404},
0849     {HI846_REG_FLL,             0x0277},
0850     {HI846_REG_LLP,             0x0ed8},
0851     {HI846_REG_BINNING_MODE,        0x0322},
0852     {HI846_REG_HBIN_MODE,           0x0200},
0853     {HI846_REG_UNKNOWN_0A24,        0x0000},
0854     {HI846_REG_X_START_H,           0x0058},
0855     {HI846_REG_X_OUTPUT_SIZE_H,     0x0280},
0856     {HI846_REG_Y_OUTPUT_SIZE_H,     0x01e0},
0857 
0858     /* For OTP */
0859     {HI846_REG_UNKNOWN_021C,        0x0003},
0860     {HI846_REG_UNKNOWN_021E,        0x0235},
0861 
0862     {HI846_REG_ISP_EN_H,            0x016a},
0863     {HI846_REG_UNKNOWN_0418,        0x0210},
0864     {HI846_REG_UNKNOWN_0B02,        0xe04d},
0865     {HI846_REG_UNKNOWN_0B10,        0x7021},
0866     {HI846_REG_UNKNOWN_0B12,        0x0120},
0867     {HI846_REG_UNKNOWN_0B14,        0x0001},
0868     {HI846_REG_UNKNOWN_2008,        0x38fd},
0869     {HI846_REG_UNKNOWN_326E,        0x0000},
0870 };
0871 
0872 static const struct hi846_reg mode_640x480_mipi_2lane[] = {
0873     {HI846_REG_UNKNOWN_0900,        0x0300},
0874     {HI846_REG_MIPI_TX_OP_MODE,     0x4319},
0875     {HI846_REG_UNKNOWN_0914,        0xc105},
0876     {HI846_REG_TCLK_PREPARE,        0x030c},
0877     {HI846_REG_UNKNOWN_0918,        0x0304},
0878     {HI846_REG_THS_ZERO,            0x0708},
0879     {HI846_REG_TCLK_POST,           0x0b04},
0880     {HI846_REG_UNKNOWN_091E,        0x0500},
0881     {HI846_REG_UNKNOWN_090C,        0x0208},
0882     {HI846_REG_UNKNOWN_090E,        0x009a},
0883     {HI846_REG_UNKNOWN_0954,        0x0089},
0884     {HI846_REG_UNKNOWN_0956,        0x0000},
0885     {HI846_REG_UNKNOWN_0958,        0xca80},
0886     {HI846_REG_UNKNOWN_095A,        0x9240},
0887     {HI846_REG_PLL_CFG_MIPI2_H,     0x4924},
0888     {HI846_REG_TG_ENABLE,           0x0100},
0889 };
0890 
0891 static const struct hi846_reg mode_1280x720_config[] = {
0892     {HI846_REG_MODE_SELECT,         0x0000},
0893     {HI846_REG_Y_ODD_INC_FOBP,      0x3311},
0894     {HI846_REG_Y_ODD_INC_VACT,      0x3311},
0895     {HI846_REG_Y_ADDR_START_VACT_H,     0x0238},
0896     {HI846_REG_Y_ADDR_END_VACT_H,       0x07d7},
0897     {HI846_REG_UNKNOWN_005C,        0x4202},
0898     {HI846_REG_FLL,             0x034a},
0899     {HI846_REG_LLP,             0x0ed8},
0900     {HI846_REG_BINNING_MODE,        0x0122},
0901     {HI846_REG_HBIN_MODE,           0x0100},
0902     {HI846_REG_UNKNOWN_0A24,        0x0000},
0903     {HI846_REG_X_START_H,           0x00b0},
0904     {HI846_REG_X_OUTPUT_SIZE_H,     0x0500},
0905     {HI846_REG_Y_OUTPUT_SIZE_H,     0x02d0},
0906     {HI846_REG_EXPOSURE,            0x0344},
0907 
0908     /* For OTP */
0909     {HI846_REG_UNKNOWN_021C,        0x0003},
0910     {HI846_REG_UNKNOWN_021E,        0x0235},
0911 
0912     {HI846_REG_ISP_EN_H,            0x016a},
0913     {HI846_REG_UNKNOWN_0418,        0x0410},
0914     {HI846_REG_UNKNOWN_0B02,        0xe04d},
0915     {HI846_REG_UNKNOWN_0B10,        0x6c21},
0916     {HI846_REG_UNKNOWN_0B12,        0x0120},
0917     {HI846_REG_UNKNOWN_0B14,        0x0005},
0918     {HI846_REG_UNKNOWN_2008,        0x38fd},
0919     {HI846_REG_UNKNOWN_326E,        0x0000},
0920 };
0921 
0922 static const struct hi846_reg mode_1280x720_mipi_2lane[] = {
0923     {HI846_REG_UNKNOWN_0900,        0x0300},
0924     {HI846_REG_MIPI_TX_OP_MODE,     0x4319},
0925     {HI846_REG_UNKNOWN_0914,        0xc109},
0926     {HI846_REG_TCLK_PREPARE,        0x061a},
0927     {HI846_REG_UNKNOWN_0918,        0x0407},
0928     {HI846_REG_THS_ZERO,            0x0a0b},
0929     {HI846_REG_TCLK_POST,           0x0e08},
0930     {HI846_REG_UNKNOWN_091E,        0x0a00},
0931     {HI846_REG_UNKNOWN_090C,        0x0427},
0932     {HI846_REG_UNKNOWN_090E,        0x0145},
0933     {HI846_REG_UNKNOWN_0954,        0x0089},
0934     {HI846_REG_UNKNOWN_0956,        0x0000},
0935     {HI846_REG_UNKNOWN_0958,        0xca80},
0936     {HI846_REG_UNKNOWN_095A,        0x9240},
0937     {HI846_REG_PLL_CFG_MIPI2_H,     0x4124},
0938     {HI846_REG_TG_ENABLE,           0x0100},
0939 };
0940 
0941 static const struct hi846_reg mode_1280x720_mipi_4lane[] = {
0942     /* 360Mbps */
0943     {HI846_REG_UNKNOWN_0900,        0x0300},
0944     {HI846_REG_MIPI_TX_OP_MODE,     0xc319},
0945     {HI846_REG_UNKNOWN_0914,        0xc105},
0946     {HI846_REG_TCLK_PREPARE,        0x030c},
0947     {HI846_REG_UNKNOWN_0918,        0x0304},
0948     {HI846_REG_THS_ZERO,            0x0708},
0949     {HI846_REG_TCLK_POST,           0x0b04},
0950     {HI846_REG_UNKNOWN_091E,        0x0500},
0951     {HI846_REG_UNKNOWN_090C,        0x0208},
0952     {HI846_REG_UNKNOWN_090E,        0x008a},
0953     {HI846_REG_UNKNOWN_0954,        0x0089},
0954     {HI846_REG_UNKNOWN_0956,        0x0000},
0955     {HI846_REG_UNKNOWN_0958,        0xca80},
0956     {HI846_REG_UNKNOWN_095A,        0x9240},
0957     {HI846_REG_PLL_CFG_MIPI2_H,     0x4924},
0958     {HI846_REG_TG_ENABLE,           0x0100},
0959 };
0960 
0961 static const struct hi846_reg mode_1632x1224_config[] = {
0962     {HI846_REG_MODE_SELECT,         0x0000},
0963     {HI846_REG_Y_ODD_INC_FOBP,      0x3311},
0964     {HI846_REG_Y_ODD_INC_VACT,      0x3311},
0965     {HI846_REG_Y_ADDR_START_VACT_H,     0x0040},
0966     {HI846_REG_Y_ADDR_END_VACT_H,       0x09cf},
0967     {HI846_REG_UNKNOWN_005C,        0x4202},
0968     {HI846_REG_FLL,             0x09de},
0969     {HI846_REG_LLP,             0x0ed8},
0970     {HI846_REG_BINNING_MODE,        0x0122},
0971     {HI846_REG_HBIN_MODE,           0x0100},
0972     {HI846_REG_UNKNOWN_0A24,        0x0000},
0973     {HI846_REG_X_START_H,           0x0000},
0974     {HI846_REG_X_OUTPUT_SIZE_H,     0x0660},
0975     {HI846_REG_Y_OUTPUT_SIZE_H,     0x04c8},
0976     {HI846_REG_EXPOSURE,            0x09d8},
0977 
0978     /* For OTP */
0979     {HI846_REG_UNKNOWN_021C,        0x0003},
0980     {HI846_REG_UNKNOWN_021E,        0x0235},
0981 
0982     {HI846_REG_ISP_EN_H,            0x016a},
0983     {HI846_REG_UNKNOWN_0418,        0x0000},
0984     {HI846_REG_UNKNOWN_0B02,        0xe04d},
0985     {HI846_REG_UNKNOWN_0B10,        0x6c21},
0986     {HI846_REG_UNKNOWN_0B12,        0x0120},
0987     {HI846_REG_UNKNOWN_0B14,        0x0005},
0988     {HI846_REG_UNKNOWN_2008,        0x38fd},
0989     {HI846_REG_UNKNOWN_326E,        0x0000},
0990 };
0991 
0992 static const struct hi846_reg mode_1632x1224_mipi_2lane[] = {
0993     {HI846_REG_UNKNOWN_0900,        0x0300},
0994     {HI846_REG_MIPI_TX_OP_MODE,     0x4319},
0995     {HI846_REG_UNKNOWN_0914,        0xc109},
0996     {HI846_REG_TCLK_PREPARE,        0x061a},
0997     {HI846_REG_UNKNOWN_0918,        0x0407},
0998     {HI846_REG_THS_ZERO,            0x0a0b},
0999     {HI846_REG_TCLK_POST,           0x0e08},
1000     {HI846_REG_UNKNOWN_091E,        0x0a00},
1001     {HI846_REG_UNKNOWN_090C,        0x0427},
1002     {HI846_REG_UNKNOWN_090E,        0x0069},
1003     {HI846_REG_UNKNOWN_0954,        0x0089},
1004     {HI846_REG_UNKNOWN_0956,        0x0000},
1005     {HI846_REG_UNKNOWN_0958,        0xca80},
1006     {HI846_REG_UNKNOWN_095A,        0x9240},
1007     {HI846_REG_PLL_CFG_MIPI2_H,     0x4124},
1008     {HI846_REG_TG_ENABLE,           0x0100},
1009 };
1010 
1011 static const struct hi846_reg mode_1632x1224_mipi_4lane[] = {
1012     {HI846_REG_UNKNOWN_0900,        0x0300},
1013     {HI846_REG_MIPI_TX_OP_MODE,     0xc319},
1014     {HI846_REG_UNKNOWN_0914,        0xc105},
1015     {HI846_REG_TCLK_PREPARE,        0x030c},
1016     {HI846_REG_UNKNOWN_0918,        0x0304},
1017     {HI846_REG_THS_ZERO,            0x0708},
1018     {HI846_REG_TCLK_POST,           0x0b04},
1019     {HI846_REG_UNKNOWN_091E,        0x0500},
1020     {HI846_REG_UNKNOWN_090C,        0x0208},
1021     {HI846_REG_UNKNOWN_090E,        0x001c},
1022     {HI846_REG_UNKNOWN_0954,        0x0089},
1023     {HI846_REG_UNKNOWN_0956,        0x0000},
1024     {HI846_REG_UNKNOWN_0958,        0xca80},
1025     {HI846_REG_UNKNOWN_095A,        0x9240},
1026     {HI846_REG_PLL_CFG_MIPI2_H,     0x4924},
1027     {HI846_REG_TG_ENABLE,           0x0100},
1028 };
1029 
1030 static const char * const hi846_test_pattern_menu[] = {
1031     "Disabled",
1032     "Solid Colour",
1033     "100% Colour Bars",
1034     "Fade To Grey Colour Bars",
1035     "PN9",
1036     "Gradient Horizontal",
1037     "Gradient Vertical",
1038     "Check Board",
1039     "Slant Pattern",
1040     "Resolution Pattern",
1041 };
1042 
1043 #define FREQ_INDEX_640  0
1044 #define FREQ_INDEX_1280 1
1045 static const s64 hi846_link_freqs[] = {
1046     [FREQ_INDEX_640] = 80000000,
1047     [FREQ_INDEX_1280] = 200000000,
1048 };
1049 
1050 static const struct hi846_reg_list hi846_init_regs_list_2lane = {
1051     .num_of_regs = ARRAY_SIZE(hi846_init_2lane),
1052     .regs = hi846_init_2lane,
1053 };
1054 
1055 static const struct hi846_reg_list hi846_init_regs_list_4lane = {
1056     .num_of_regs = ARRAY_SIZE(hi846_init_4lane),
1057     .regs = hi846_init_4lane,
1058 };
1059 
1060 static const struct hi846_mode supported_modes[] = {
1061     {
1062         .width = 640,
1063         .height = 480,
1064         .link_freq_index = FREQ_INDEX_640,
1065         .fps = 120,
1066         .frame_len = 631,
1067         .llp = HI846_LINE_LENGTH,
1068         .reg_list_config = {
1069             .num_of_regs = ARRAY_SIZE(mode_640x480_config),
1070             .regs = mode_640x480_config,
1071         },
1072         .reg_list_2lane = {
1073             .num_of_regs = ARRAY_SIZE(mode_640x480_mipi_2lane),
1074             .regs = mode_640x480_mipi_2lane,
1075         },
1076         .reg_list_4lane = {
1077             .num_of_regs = 0,
1078         },
1079         .crop = {
1080             .left = 0x58,
1081             .top = 0x148,
1082             .width = 640 * 4,
1083             .height = 480 * 4,
1084         },
1085     },
1086     {
1087         .width = 1280,
1088         .height = 720,
1089         .link_freq_index = FREQ_INDEX_1280,
1090         .fps = 90,
1091         .frame_len = 842,
1092         .llp = HI846_LINE_LENGTH,
1093         .reg_list_config = {
1094             .num_of_regs = ARRAY_SIZE(mode_1280x720_config),
1095             .regs = mode_1280x720_config,
1096         },
1097         .reg_list_2lane = {
1098             .num_of_regs = ARRAY_SIZE(mode_1280x720_mipi_2lane),
1099             .regs = mode_1280x720_mipi_2lane,
1100         },
1101         .reg_list_4lane = {
1102             .num_of_regs = ARRAY_SIZE(mode_1280x720_mipi_4lane),
1103             .regs = mode_1280x720_mipi_4lane,
1104         },
1105         .crop = {
1106             .left = 0xb0,
1107             .top = 0x238,
1108             .width = 1280 * 2,
1109             .height = 720 * 2,
1110         },
1111     },
1112     {
1113         .width = 1632,
1114         .height = 1224,
1115         .link_freq_index = FREQ_INDEX_1280,
1116         .fps = 30,
1117         .frame_len = 2526,
1118         .llp = HI846_LINE_LENGTH,
1119         .reg_list_config = {
1120             .num_of_regs = ARRAY_SIZE(mode_1632x1224_config),
1121             .regs = mode_1632x1224_config,
1122         },
1123         .reg_list_2lane = {
1124             .num_of_regs = ARRAY_SIZE(mode_1632x1224_mipi_2lane),
1125             .regs = mode_1632x1224_mipi_2lane,
1126         },
1127         .reg_list_4lane = {
1128             .num_of_regs = ARRAY_SIZE(mode_1632x1224_mipi_4lane),
1129             .regs = mode_1632x1224_mipi_4lane,
1130         },
1131         .crop = {
1132             .left = 0x0,
1133             .top = 0x0,
1134             .width = 1632 * 2,
1135             .height = 1224 * 2,
1136         },
1137     }
1138 };
1139 
1140 struct hi846_datafmt {
1141     u32 code;
1142     enum v4l2_colorspace colorspace;
1143 };
1144 
1145 static const char * const hi846_supply_names[] = {
1146     "vddio", /* Digital I/O (1.8V or 2.8V) */
1147     "vdda", /* Analog (2.8V) */
1148     "vddd", /* Digital Core (1.2V) */
1149 };
1150 
1151 #define HI846_NUM_SUPPLIES ARRAY_SIZE(hi846_supply_names)
1152 
1153 struct hi846 {
1154     struct gpio_desc *rst_gpio;
1155     struct gpio_desc *shutdown_gpio;
1156     struct regulator_bulk_data supplies[HI846_NUM_SUPPLIES];
1157     struct clk *clock;
1158     const struct hi846_datafmt *fmt;
1159     struct v4l2_subdev sd;
1160     struct media_pad pad;
1161     struct v4l2_ctrl_handler ctrl_handler;
1162     u8 nr_lanes;
1163 
1164     struct v4l2_ctrl *link_freq;
1165     struct v4l2_ctrl *pixel_rate;
1166     struct v4l2_ctrl *vblank;
1167     struct v4l2_ctrl *hblank;
1168     struct v4l2_ctrl *exposure;
1169 
1170     struct mutex mutex; /* protect cur_mode, streaming and chip access */
1171     const struct hi846_mode *cur_mode;
1172     bool streaming;
1173 };
1174 
1175 static inline struct hi846 *to_hi846(struct v4l2_subdev *sd)
1176 {
1177     return container_of(sd, struct hi846, sd);
1178 }
1179 
1180 static const struct hi846_datafmt hi846_colour_fmts[] = {
1181     { HI846_MEDIA_BUS_FORMAT, V4L2_COLORSPACE_RAW },
1182 };
1183 
1184 static const struct hi846_datafmt *hi846_find_datafmt(u32 code)
1185 {
1186     unsigned int i;
1187 
1188     for (i = 0; i < ARRAY_SIZE(hi846_colour_fmts); i++)
1189         if (hi846_colour_fmts[i].code == code)
1190             return &hi846_colour_fmts[i];
1191 
1192     return NULL;
1193 }
1194 
1195 static inline u8 hi846_get_link_freq_index(struct hi846 *hi846)
1196 {
1197     return hi846->cur_mode->link_freq_index;
1198 }
1199 
1200 static u64 hi846_get_link_freq(struct hi846 *hi846)
1201 {
1202     u8 index = hi846_get_link_freq_index(hi846);
1203 
1204     return hi846_link_freqs[index];
1205 }
1206 
1207 static u64 hi846_calc_pixel_rate(struct hi846 *hi846)
1208 {
1209     u64 link_freq = hi846_get_link_freq(hi846);
1210     u64 pixel_rate = link_freq * 2 * hi846->nr_lanes;
1211 
1212     do_div(pixel_rate, HI846_RGB_DEPTH);
1213 
1214     return pixel_rate;
1215 }
1216 
1217 static int hi846_read_reg(struct hi846 *hi846, u16 reg, u8 *val)
1218 {
1219     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1220     struct i2c_msg msgs[2];
1221     u8 addr_buf[2];
1222     u8 data_buf[1] = {0};
1223     int ret;
1224 
1225     put_unaligned_be16(reg, addr_buf);
1226     msgs[0].addr = client->addr;
1227     msgs[0].flags = 0;
1228     msgs[0].len = sizeof(addr_buf);
1229     msgs[0].buf = addr_buf;
1230     msgs[1].addr = client->addr;
1231     msgs[1].flags = I2C_M_RD;
1232     msgs[1].len = 1;
1233     msgs[1].buf = data_buf;
1234 
1235     ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1236     if (ret != ARRAY_SIZE(msgs)) {
1237         dev_err(&client->dev, "i2c read error: %d\n", ret);
1238         return -EIO;
1239     }
1240 
1241     *val = data_buf[0];
1242 
1243     return 0;
1244 }
1245 
1246 static int hi846_write_reg(struct hi846 *hi846, u16 reg, u8 val)
1247 {
1248     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1249     u8 buf[3] = { reg >> 8, reg & 0xff, val };
1250     struct i2c_msg msg[] = {
1251         { .addr = client->addr, .flags = 0,
1252           .len = ARRAY_SIZE(buf), .buf = buf },
1253     };
1254     int ret;
1255 
1256     ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
1257     if (ret != ARRAY_SIZE(msg)) {
1258         dev_err(&client->dev, "i2c write error\n");
1259         return -EIO;
1260     }
1261 
1262     return 0;
1263 }
1264 
1265 static void hi846_write_reg_16(struct hi846 *hi846, u16 reg, u16 val, int *err)
1266 {
1267     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1268     u8 buf[4];
1269     int ret;
1270 
1271     if (*err < 0)
1272         return;
1273 
1274     put_unaligned_be16(reg, buf);
1275     put_unaligned_be16(val, buf + 2);
1276     ret = i2c_master_send(client, buf, sizeof(buf));
1277     if (ret != sizeof(buf)) {
1278         dev_err(&client->dev, "i2c_master_send != %zu: %d\n",
1279             sizeof(buf), ret);
1280         *err = -EIO;
1281     }
1282 }
1283 
1284 static int hi846_write_reg_list(struct hi846 *hi846,
1285                 const struct hi846_reg_list *r_list)
1286 {
1287     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1288     unsigned int i;
1289     int ret = 0;
1290 
1291     for (i = 0; i < r_list->num_of_regs; i++) {
1292         hi846_write_reg_16(hi846, r_list->regs[i].address,
1293                    r_list->regs[i].val, &ret);
1294         if (ret) {
1295             dev_err_ratelimited(&client->dev,
1296                         "failed to write reg 0x%4.4x: %d",
1297                         r_list->regs[i].address, ret);
1298             return ret;
1299         }
1300     }
1301 
1302     return 0;
1303 }
1304 
1305 static int hi846_update_digital_gain(struct hi846 *hi846, u16 d_gain)
1306 {
1307     int ret = 0;
1308 
1309     hi846_write_reg_16(hi846, HI846_REG_MWB_GR_GAIN_H, d_gain, &ret);
1310     hi846_write_reg_16(hi846, HI846_REG_MWB_GB_GAIN_H, d_gain, &ret);
1311     hi846_write_reg_16(hi846, HI846_REG_MWB_R_GAIN_H, d_gain, &ret);
1312     hi846_write_reg_16(hi846, HI846_REG_MWB_B_GAIN_H, d_gain, &ret);
1313 
1314     return ret;
1315 }
1316 
1317 static int hi846_test_pattern(struct hi846 *hi846, u32 pattern)
1318 {
1319     int ret;
1320     u8 val;
1321 
1322     if (pattern) {
1323         ret = hi846_read_reg(hi846, HI846_REG_ISP, &val);
1324         if (ret)
1325             return ret;
1326 
1327         ret = hi846_write_reg(hi846, HI846_REG_ISP,
1328                       val | HI846_REG_ISP_TPG_EN);
1329         if (ret)
1330             return ret;
1331     }
1332 
1333     return hi846_write_reg(hi846, HI846_REG_TEST_PATTERN, pattern);
1334 }
1335 
1336 static int hi846_set_ctrl(struct v4l2_ctrl *ctrl)
1337 {
1338     struct hi846 *hi846 = container_of(ctrl->handler,
1339                          struct hi846, ctrl_handler);
1340     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1341     s64 exposure_max;
1342     int ret = 0;
1343     u32 shutter, frame_len;
1344 
1345     /* Propagate change of current control to all related controls */
1346     if (ctrl->id == V4L2_CID_VBLANK) {
1347         /* Update max exposure while meeting expected vblanking */
1348         exposure_max = hi846->cur_mode->height + ctrl->val -
1349                    HI846_EXPOSURE_MAX_MARGIN;
1350         __v4l2_ctrl_modify_range(hi846->exposure,
1351                      hi846->exposure->minimum,
1352                      exposure_max, hi846->exposure->step,
1353                      exposure_max);
1354     }
1355 
1356     if (!pm_runtime_get_if_in_use(&client->dev))
1357         return 0;
1358 
1359     switch (ctrl->id) {
1360     case V4L2_CID_ANALOGUE_GAIN:
1361         ret = hi846_write_reg(hi846, HI846_REG_ANALOG_GAIN, ctrl->val);
1362         break;
1363 
1364     case V4L2_CID_DIGITAL_GAIN:
1365         ret = hi846_update_digital_gain(hi846, ctrl->val);
1366         break;
1367 
1368     case V4L2_CID_EXPOSURE:
1369         shutter = ctrl->val;
1370         frame_len = hi846->cur_mode->frame_len;
1371 
1372         if (shutter > frame_len - 6) { /* margin */
1373             frame_len = shutter + 6;
1374             if (frame_len > 0xffff) { /* max frame len */
1375                 frame_len = 0xffff;
1376             }
1377         }
1378 
1379         if (shutter < 6)
1380             shutter = 6;
1381         if (shutter > (0xffff - 6))
1382             shutter = 0xffff - 6;
1383 
1384         hi846_write_reg_16(hi846, HI846_REG_FLL, frame_len, &ret);
1385         hi846_write_reg_16(hi846, HI846_REG_EXPOSURE, shutter, &ret);
1386         break;
1387 
1388     case V4L2_CID_VBLANK:
1389         /* Update FLL that meets expected vertical blanking */
1390         hi846_write_reg_16(hi846, HI846_REG_FLL,
1391                    hi846->cur_mode->height + ctrl->val, &ret);
1392         break;
1393     case V4L2_CID_TEST_PATTERN:
1394         ret = hi846_test_pattern(hi846, ctrl->val);
1395         break;
1396 
1397     default:
1398         ret = -EINVAL;
1399         break;
1400     }
1401 
1402     pm_runtime_put(&client->dev);
1403 
1404     return ret;
1405 }
1406 
1407 static const struct v4l2_ctrl_ops hi846_ctrl_ops = {
1408     .s_ctrl = hi846_set_ctrl,
1409 };
1410 
1411 static int hi846_init_controls(struct hi846 *hi846)
1412 {
1413     struct v4l2_ctrl_handler *ctrl_hdlr;
1414     s64 exposure_max, h_blank;
1415     int ret;
1416     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1417     struct v4l2_fwnode_device_properties props;
1418 
1419     ctrl_hdlr = &hi846->ctrl_handler;
1420     ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
1421     if (ret)
1422         return ret;
1423 
1424     ctrl_hdlr->lock = &hi846->mutex;
1425 
1426     hi846->link_freq =
1427         v4l2_ctrl_new_int_menu(ctrl_hdlr, &hi846_ctrl_ops,
1428                        V4L2_CID_LINK_FREQ,
1429                        ARRAY_SIZE(hi846_link_freqs) - 1,
1430                        0, hi846_link_freqs);
1431     if (hi846->link_freq)
1432         hi846->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1433 
1434     hi846->pixel_rate =
1435         v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops,
1436                   V4L2_CID_PIXEL_RATE, 0,
1437                   hi846_calc_pixel_rate(hi846), 1,
1438                   hi846_calc_pixel_rate(hi846));
1439     hi846->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops,
1440                       V4L2_CID_VBLANK,
1441                       hi846->cur_mode->frame_len -
1442                       hi846->cur_mode->height,
1443                       HI846_FLL_MAX -
1444                       hi846->cur_mode->height, 1,
1445                       hi846->cur_mode->frame_len -
1446                       hi846->cur_mode->height);
1447 
1448     h_blank = hi846->cur_mode->llp - hi846->cur_mode->width;
1449 
1450     hi846->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops,
1451                       V4L2_CID_HBLANK, h_blank, h_blank, 1,
1452                       h_blank);
1453     if (hi846->hblank)
1454         hi846->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1455 
1456     v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1457               HI846_ANAL_GAIN_MIN, HI846_ANAL_GAIN_MAX,
1458               HI846_ANAL_GAIN_STEP, HI846_ANAL_GAIN_MIN);
1459     v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1460               HI846_DGTL_GAIN_MIN, HI846_DGTL_GAIN_MAX,
1461               HI846_DGTL_GAIN_STEP, HI846_DGTL_GAIN_DEFAULT);
1462     exposure_max = hi846->cur_mode->frame_len - HI846_EXPOSURE_MAX_MARGIN;
1463     hi846->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops,
1464                         V4L2_CID_EXPOSURE,
1465                         HI846_EXPOSURE_MIN, exposure_max,
1466                         HI846_EXPOSURE_STEP,
1467                         exposure_max);
1468     v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &hi846_ctrl_ops,
1469                      V4L2_CID_TEST_PATTERN,
1470                      ARRAY_SIZE(hi846_test_pattern_menu) - 1,
1471                      0, 0, hi846_test_pattern_menu);
1472     if (ctrl_hdlr->error) {
1473         dev_err(&client->dev, "v4l ctrl handler error: %d\n",
1474             ctrl_hdlr->error);
1475         return ctrl_hdlr->error;
1476     }
1477 
1478     ret = v4l2_fwnode_device_parse(&client->dev, &props);
1479     if (ret)
1480         return ret;
1481 
1482     ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &hi846_ctrl_ops,
1483                           &props);
1484     if (ret)
1485         return ret;
1486 
1487     hi846->sd.ctrl_handler = ctrl_hdlr;
1488 
1489     return 0;
1490 }
1491 
1492 static int hi846_set_video_mode(struct hi846 *hi846, int fps)
1493 {
1494     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1495     u64 frame_length;
1496     int ret = 0;
1497     int dummy_lines;
1498     u64 link_freq = hi846_get_link_freq(hi846);
1499 
1500     dev_dbg(&client->dev, "%s: link freq: %llu\n", __func__,
1501         hi846_get_link_freq(hi846));
1502 
1503     do_div(link_freq, fps);
1504     frame_length = link_freq;
1505     do_div(frame_length, HI846_LINE_LENGTH);
1506 
1507     dummy_lines = (frame_length > hi846->cur_mode->frame_len) ?
1508             (frame_length - hi846->cur_mode->frame_len) : 0;
1509 
1510     frame_length = hi846->cur_mode->frame_len + dummy_lines;
1511 
1512     dev_dbg(&client->dev, "%s: frame length calculated: %llu\n", __func__,
1513         frame_length);
1514 
1515     hi846_write_reg_16(hi846, HI846_REG_FLL, frame_length & 0xFFFF, &ret);
1516     hi846_write_reg_16(hi846, HI846_REG_LLP,
1517                HI846_LINE_LENGTH & 0xFFFF, &ret);
1518 
1519     return ret;
1520 }
1521 
1522 static int hi846_start_streaming(struct hi846 *hi846)
1523 {
1524     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1525     int ret = 0;
1526     u8 val;
1527 
1528     if (hi846->nr_lanes == 2)
1529         ret = hi846_write_reg_list(hi846, &hi846_init_regs_list_2lane);
1530     else
1531         ret = hi846_write_reg_list(hi846, &hi846_init_regs_list_4lane);
1532     if (ret) {
1533         dev_err(&client->dev, "failed to set plls: %d\n", ret);
1534         return ret;
1535     }
1536 
1537     ret = hi846_write_reg_list(hi846, &hi846->cur_mode->reg_list_config);
1538     if (ret) {
1539         dev_err(&client->dev, "failed to set mode: %d\n", ret);
1540         return ret;
1541     }
1542 
1543     if (hi846->nr_lanes == 2)
1544         ret = hi846_write_reg_list(hi846,
1545                        &hi846->cur_mode->reg_list_2lane);
1546     else
1547         ret = hi846_write_reg_list(hi846,
1548                        &hi846->cur_mode->reg_list_4lane);
1549     if (ret) {
1550         dev_err(&client->dev, "failed to set mipi mode: %d\n", ret);
1551         return ret;
1552     }
1553 
1554     hi846_set_video_mode(hi846, hi846->cur_mode->fps);
1555 
1556     ret = __v4l2_ctrl_handler_setup(hi846->sd.ctrl_handler);
1557     if (ret)
1558         return ret;
1559 
1560     /*
1561      * Reading 0x0034 is purely done for debugging reasons: It is not
1562      * documented in the DS but only mentioned once:
1563      * "If 0x0034[2] bit is disabled , Visible pixel width and height is 0."
1564      * So even though that sounds like we won't see anything, we don't
1565      * know more about this, so in that case only inform the user but do
1566      * nothing more.
1567      */
1568     ret = hi846_read_reg(hi846, 0x0034, &val);
1569     if (ret)
1570         return ret;
1571     if (!(val & BIT(2)))
1572         dev_info(&client->dev, "visible pixel width and height is 0\n");
1573 
1574     ret = hi846_write_reg(hi846, HI846_REG_MODE_SELECT,
1575                   HI846_MODE_STREAMING);
1576     if (ret) {
1577         dev_err(&client->dev, "failed to start stream");
1578         return ret;
1579     }
1580 
1581     hi846->streaming = 1;
1582 
1583     dev_dbg(&client->dev, "%s: started streaming successfully\n", __func__);
1584 
1585     return ret;
1586 }
1587 
1588 static void hi846_stop_streaming(struct hi846 *hi846)
1589 {
1590     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1591 
1592     if (hi846_write_reg(hi846, HI846_REG_MODE_SELECT, HI846_MODE_STANDBY))
1593         dev_err(&client->dev, "failed to stop stream");
1594 
1595     hi846->streaming = 0;
1596 }
1597 
1598 static int hi846_set_stream(struct v4l2_subdev *sd, int enable)
1599 {
1600     struct hi846 *hi846 = to_hi846(sd);
1601     struct i2c_client *client = v4l2_get_subdevdata(sd);
1602     int ret = 0;
1603 
1604     if (hi846->streaming == enable)
1605         return 0;
1606 
1607     mutex_lock(&hi846->mutex);
1608 
1609     if (enable) {
1610         ret = pm_runtime_get_sync(&client->dev);
1611         if (ret < 0) {
1612             pm_runtime_put_noidle(&client->dev);
1613             goto out;
1614         }
1615 
1616         ret = hi846_start_streaming(hi846);
1617     }
1618 
1619     if (!enable || ret) {
1620         hi846_stop_streaming(hi846);
1621         pm_runtime_put(&client->dev);
1622     }
1623 
1624 out:
1625     mutex_unlock(&hi846->mutex);
1626 
1627     return ret;
1628 }
1629 
1630 static int hi846_power_on(struct hi846 *hi846)
1631 {
1632     int ret;
1633 
1634     ret = regulator_bulk_enable(HI846_NUM_SUPPLIES, hi846->supplies);
1635     if (ret < 0)
1636         return ret;
1637 
1638     ret = clk_prepare_enable(hi846->clock);
1639     if (ret < 0)
1640         goto err_reg;
1641 
1642     if (hi846->shutdown_gpio)
1643         gpiod_set_value_cansleep(hi846->shutdown_gpio, 0);
1644 
1645     /* 30us = 2400 cycles at 80Mhz */
1646     usleep_range(30, 60);
1647     if (hi846->rst_gpio)
1648         gpiod_set_value_cansleep(hi846->rst_gpio, 0);
1649     usleep_range(30, 60);
1650 
1651     return 0;
1652 
1653 err_reg:
1654     regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies);
1655 
1656     return ret;
1657 }
1658 
1659 static int hi846_power_off(struct hi846 *hi846)
1660 {
1661     if (hi846->rst_gpio)
1662         gpiod_set_value_cansleep(hi846->rst_gpio, 1);
1663 
1664     if (hi846->shutdown_gpio)
1665         gpiod_set_value_cansleep(hi846->shutdown_gpio, 1);
1666 
1667     clk_disable_unprepare(hi846->clock);
1668     return regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies);
1669 }
1670 
1671 static int __maybe_unused hi846_suspend(struct device *dev)
1672 {
1673     struct i2c_client *client = to_i2c_client(dev);
1674     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1675     struct hi846 *hi846 = to_hi846(sd);
1676 
1677     if (hi846->streaming)
1678         hi846_stop_streaming(hi846);
1679 
1680     return hi846_power_off(hi846);
1681 }
1682 
1683 static int __maybe_unused hi846_resume(struct device *dev)
1684 {
1685     struct i2c_client *client = to_i2c_client(dev);
1686     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1687     struct hi846 *hi846 = to_hi846(sd);
1688     int ret;
1689 
1690     ret = hi846_power_on(hi846);
1691     if (ret)
1692         return ret;
1693 
1694     if (hi846->streaming) {
1695         ret = hi846_start_streaming(hi846);
1696         if (ret) {
1697             dev_err(dev, "%s: start streaming failed: %d\n",
1698                 __func__, ret);
1699             goto error;
1700         }
1701     }
1702 
1703     return 0;
1704 
1705 error:
1706     hi846_power_off(hi846);
1707     return ret;
1708 }
1709 
1710 static int hi846_set_format(struct v4l2_subdev *sd,
1711                 struct v4l2_subdev_state *sd_state,
1712                 struct v4l2_subdev_format *format)
1713 {
1714     struct hi846 *hi846 = to_hi846(sd);
1715     struct v4l2_mbus_framefmt *mf = &format->format;
1716     struct i2c_client *client = v4l2_get_subdevdata(sd);
1717     const struct hi846_datafmt *fmt = hi846_find_datafmt(mf->code);
1718     u32 tgt_fps;
1719     s32 vblank_def, h_blank;
1720 
1721     if (!fmt) {
1722         mf->code = hi846_colour_fmts[0].code;
1723         mf->colorspace = hi846_colour_fmts[0].colorspace;
1724         fmt = &hi846_colour_fmts[0];
1725     }
1726 
1727     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
1728         *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = *mf;
1729         return 0;
1730     }
1731 
1732     if (hi846->nr_lanes == 2) {
1733         if (!hi846->cur_mode->reg_list_2lane.num_of_regs) {
1734             dev_err(&client->dev,
1735                 "this mode is not supported for 2 lanes\n");
1736             return -EINVAL;
1737         }
1738     } else {
1739         if (!hi846->cur_mode->reg_list_4lane.num_of_regs) {
1740             dev_err(&client->dev,
1741                 "this mode is not supported for 4 lanes\n");
1742             return -EINVAL;
1743         }
1744     }
1745 
1746     mutex_lock(&hi846->mutex);
1747 
1748     if (hi846->streaming) {
1749         mutex_unlock(&hi846->mutex);
1750         return -EBUSY;
1751     }
1752 
1753     hi846->fmt = fmt;
1754 
1755     hi846->cur_mode =
1756         v4l2_find_nearest_size(supported_modes,
1757                        ARRAY_SIZE(supported_modes),
1758                        width, height, mf->width, mf->height);
1759     dev_dbg(&client->dev, "%s: found mode: %dx%d\n", __func__,
1760         hi846->cur_mode->width, hi846->cur_mode->height);
1761 
1762     tgt_fps = hi846->cur_mode->fps;
1763     dev_dbg(&client->dev, "%s: target fps: %d\n", __func__, tgt_fps);
1764 
1765     mf->width = hi846->cur_mode->width;
1766     mf->height = hi846->cur_mode->height;
1767     mf->code = HI846_MEDIA_BUS_FORMAT;
1768     mf->field = V4L2_FIELD_NONE;
1769 
1770     __v4l2_ctrl_s_ctrl(hi846->link_freq, hi846_get_link_freq_index(hi846));
1771     __v4l2_ctrl_s_ctrl_int64(hi846->pixel_rate,
1772                  hi846_calc_pixel_rate(hi846));
1773 
1774     /* Update limits and set FPS to default */
1775     vblank_def = hi846->cur_mode->frame_len - hi846->cur_mode->height;
1776     __v4l2_ctrl_modify_range(hi846->vblank,
1777                  hi846->cur_mode->frame_len -
1778                     hi846->cur_mode->height,
1779                  HI846_FLL_MAX - hi846->cur_mode->height, 1,
1780                  vblank_def);
1781     __v4l2_ctrl_s_ctrl(hi846->vblank, vblank_def);
1782 
1783     h_blank = hi846->cur_mode->llp - hi846->cur_mode->width;
1784 
1785     __v4l2_ctrl_modify_range(hi846->hblank, h_blank, h_blank, 1,
1786                  h_blank);
1787 
1788     dev_dbg(&client->dev, "Set fmt w=%d h=%d code=0x%x colorspace=0x%x\n",
1789         mf->width, mf->height,
1790         fmt->code, fmt->colorspace);
1791 
1792     mutex_unlock(&hi846->mutex);
1793 
1794     return 0;
1795 }
1796 
1797 static int hi846_get_format(struct v4l2_subdev *sd,
1798                 struct v4l2_subdev_state *sd_state,
1799                 struct v4l2_subdev_format *format)
1800 {
1801     struct hi846 *hi846 = to_hi846(sd);
1802     struct v4l2_mbus_framefmt *mf = &format->format;
1803     struct i2c_client *client = v4l2_get_subdevdata(sd);
1804 
1805     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
1806         format->format = *v4l2_subdev_get_try_format(&hi846->sd,
1807                             sd_state,
1808                             format->pad);
1809         return 0;
1810     }
1811 
1812     mutex_lock(&hi846->mutex);
1813     mf->code        = HI846_MEDIA_BUS_FORMAT;
1814     mf->colorspace  = V4L2_COLORSPACE_RAW;
1815     mf->field       = V4L2_FIELD_NONE;
1816     mf->width       = hi846->cur_mode->width;
1817     mf->height      = hi846->cur_mode->height;
1818     mutex_unlock(&hi846->mutex);
1819     dev_dbg(&client->dev,
1820         "Get format w=%d h=%d code=0x%x colorspace=0x%x\n",
1821         mf->width, mf->height, mf->code, mf->colorspace);
1822 
1823     return 0;
1824 }
1825 
1826 static int hi846_enum_mbus_code(struct v4l2_subdev *sd,
1827                 struct v4l2_subdev_state *sd_state,
1828                 struct v4l2_subdev_mbus_code_enum *code)
1829 {
1830     if (code->pad || code->index > 0)
1831         return -EINVAL;
1832 
1833     code->code = HI846_MEDIA_BUS_FORMAT;
1834 
1835     return 0;
1836 }
1837 
1838 static int hi846_enum_frame_size(struct v4l2_subdev *sd,
1839                  struct v4l2_subdev_state *sd_state,
1840                  struct v4l2_subdev_frame_size_enum *fse)
1841 {
1842     struct i2c_client *client = v4l2_get_subdevdata(sd);
1843 
1844     if (fse->pad || fse->index >= ARRAY_SIZE(supported_modes))
1845         return -EINVAL;
1846 
1847     if (fse->code != HI846_MEDIA_BUS_FORMAT) {
1848         dev_err(&client->dev, "frame size enum not matching\n");
1849         return -EINVAL;
1850     }
1851 
1852     fse->min_width = supported_modes[fse->index].width;
1853     fse->max_width = supported_modes[fse->index].width;
1854     fse->min_height = supported_modes[fse->index].height;
1855     fse->max_height = supported_modes[fse->index].height;
1856 
1857     dev_dbg(&client->dev, "%s: max width: %d max height: %d\n", __func__,
1858         fse->max_width, fse->max_height);
1859 
1860     return 0;
1861 }
1862 
1863 static int hi846_get_selection(struct v4l2_subdev *sd,
1864                    struct v4l2_subdev_state *sd_state,
1865                    struct v4l2_subdev_selection *sel)
1866 {
1867     struct hi846 *hi846 = to_hi846(sd);
1868 
1869     switch (sel->target) {
1870     case V4L2_SEL_TGT_CROP:
1871     case V4L2_SEL_TGT_CROP_DEFAULT:
1872         mutex_lock(&hi846->mutex);
1873         switch (sel->which) {
1874         case V4L2_SUBDEV_FORMAT_TRY:
1875             v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
1876             break;
1877         case V4L2_SUBDEV_FORMAT_ACTIVE:
1878             sel->r = hi846->cur_mode->crop;
1879             break;
1880         }
1881         mutex_unlock(&hi846->mutex);
1882         return 0;
1883     case V4L2_SEL_TGT_CROP_BOUNDS:
1884     case V4L2_SEL_TGT_NATIVE_SIZE:
1885         sel->r.top = 0;
1886         sel->r.left = 0;
1887         sel->r.width = 3264;
1888         sel->r.height = 2448;
1889         return 0;
1890     default:
1891         return -EINVAL;
1892     }
1893 }
1894 
1895 static int hi846_init_cfg(struct v4l2_subdev *sd,
1896               struct v4l2_subdev_state *sd_state)
1897 {
1898     struct hi846 *hi846 = to_hi846(sd);
1899     struct v4l2_mbus_framefmt *mf;
1900 
1901     mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
1902 
1903     mutex_lock(&hi846->mutex);
1904     mf->code        = HI846_MEDIA_BUS_FORMAT;
1905     mf->colorspace  = V4L2_COLORSPACE_RAW;
1906     mf->field       = V4L2_FIELD_NONE;
1907     mf->width       = hi846->cur_mode->width;
1908     mf->height      = hi846->cur_mode->height;
1909     mutex_unlock(&hi846->mutex);
1910 
1911     return 0;
1912 }
1913 
1914 static const struct v4l2_subdev_video_ops hi846_video_ops = {
1915     .s_stream = hi846_set_stream,
1916 };
1917 
1918 static const struct v4l2_subdev_pad_ops hi846_pad_ops = {
1919     .init_cfg = hi846_init_cfg,
1920     .enum_frame_size = hi846_enum_frame_size,
1921     .enum_mbus_code = hi846_enum_mbus_code,
1922     .set_fmt = hi846_set_format,
1923     .get_fmt = hi846_get_format,
1924     .get_selection = hi846_get_selection,
1925 };
1926 
1927 static const struct v4l2_subdev_ops hi846_subdev_ops = {
1928     .video = &hi846_video_ops,
1929     .pad = &hi846_pad_ops,
1930 };
1931 
1932 static const struct media_entity_operations hi846_subdev_entity_ops = {
1933     .link_validate = v4l2_subdev_link_validate,
1934 };
1935 
1936 static int hi846_identify_module(struct hi846 *hi846)
1937 {
1938     struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd);
1939     int ret;
1940     u8 hi, lo;
1941 
1942     ret = hi846_read_reg(hi846, HI846_REG_CHIP_ID_L, &lo);
1943     if (ret)
1944         return ret;
1945 
1946     if (lo != HI846_CHIP_ID_L) {
1947         dev_err(&client->dev, "wrong chip id low byte: %x", lo);
1948         return -ENXIO;
1949     }
1950 
1951     ret = hi846_read_reg(hi846, HI846_REG_CHIP_ID_H, &hi);
1952     if (ret)
1953         return ret;
1954 
1955     if (hi != HI846_CHIP_ID_H) {
1956         dev_err(&client->dev, "wrong chip id high byte: %x", hi);
1957         return -ENXIO;
1958     }
1959 
1960     dev_info(&client->dev, "chip id %02X %02X using %d mipi lanes\n",
1961          hi, lo, hi846->nr_lanes);
1962 
1963     return 0;
1964 }
1965 
1966 static s64 hi846_check_link_freqs(struct hi846 *hi846,
1967                   struct v4l2_fwnode_endpoint *ep)
1968 {
1969     const s64 *freqs = hi846_link_freqs;
1970     int freqs_count = ARRAY_SIZE(hi846_link_freqs);
1971     int i, j;
1972 
1973     for (i = 0; i < freqs_count; i++) {
1974         for (j = 0; j < ep->nr_of_link_frequencies; j++)
1975             if (freqs[i] == ep->link_frequencies[j])
1976                 break;
1977         if (j == ep->nr_of_link_frequencies)
1978             return freqs[i];
1979     }
1980 
1981     return 0;
1982 }
1983 
1984 static int hi846_parse_dt(struct hi846 *hi846, struct device *dev)
1985 {
1986     struct fwnode_handle *ep;
1987     struct fwnode_handle *fwnode = dev_fwnode(dev);
1988     struct v4l2_fwnode_endpoint bus_cfg = {
1989         .bus_type = V4L2_MBUS_CSI2_DPHY
1990     };
1991     int ret;
1992     s64 fq;
1993 
1994     ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1995     if (!ep) {
1996         dev_err(dev, "unable to find endpoint node\n");
1997         return -ENXIO;
1998     }
1999 
2000     ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
2001     fwnode_handle_put(ep);
2002     if (ret) {
2003         dev_err(dev, "failed to parse endpoint node: %d\n", ret);
2004         return ret;
2005     }
2006 
2007     if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 &&
2008         bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
2009         dev_err(dev, "number of CSI2 data lanes %d is not supported",
2010             bus_cfg.bus.mipi_csi2.num_data_lanes);
2011         v4l2_fwnode_endpoint_free(&bus_cfg);
2012         return -EINVAL;
2013     }
2014 
2015     hi846->nr_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
2016 
2017     if (!bus_cfg.nr_of_link_frequencies) {
2018         dev_err(dev, "link-frequency property not found in DT\n");
2019         return -EINVAL;
2020     }
2021 
2022     /* Check that link frequences for all the modes are in device tree */
2023     fq = hi846_check_link_freqs(hi846, &bus_cfg);
2024     if (fq) {
2025         dev_err(dev, "Link frequency of %lld is not supported\n", fq);
2026         return -EINVAL;
2027     }
2028 
2029     v4l2_fwnode_endpoint_free(&bus_cfg);
2030 
2031     hi846->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
2032     if (IS_ERR(hi846->rst_gpio)) {
2033         dev_err(dev, "failed to get reset gpio: %pe\n",
2034             hi846->rst_gpio);
2035         return PTR_ERR(hi846->rst_gpio);
2036     }
2037 
2038     hi846->shutdown_gpio = devm_gpiod_get_optional(dev, "shutdown",
2039                                GPIOD_OUT_LOW);
2040     if (IS_ERR(hi846->shutdown_gpio)) {
2041         dev_err(dev, "failed to get shutdown gpio: %pe\n",
2042             hi846->shutdown_gpio);
2043         return PTR_ERR(hi846->shutdown_gpio);
2044     }
2045 
2046     return 0;
2047 }
2048 
2049 static int hi846_probe(struct i2c_client *client)
2050 {
2051     struct hi846 *hi846;
2052     int ret;
2053     int i;
2054     u32 mclk_freq;
2055 
2056     hi846 = devm_kzalloc(&client->dev, sizeof(*hi846), GFP_KERNEL);
2057     if (!hi846)
2058         return -ENOMEM;
2059 
2060     ret = hi846_parse_dt(hi846, &client->dev);
2061     if (ret) {
2062         dev_err(&client->dev, "failed to check HW configuration: %d",
2063             ret);
2064         return ret;
2065     }
2066 
2067     hi846->clock = devm_clk_get(&client->dev, NULL);
2068     if (IS_ERR(hi846->clock)) {
2069         dev_err(&client->dev, "failed to get clock: %pe\n",
2070             hi846->clock);
2071         return PTR_ERR(hi846->clock);
2072     }
2073 
2074     mclk_freq = clk_get_rate(hi846->clock);
2075     if (mclk_freq != 25000000)
2076         dev_warn(&client->dev,
2077              "External clock freq should be 25000000, not %u.\n",
2078              mclk_freq);
2079 
2080     for (i = 0; i < HI846_NUM_SUPPLIES; i++)
2081         hi846->supplies[i].supply = hi846_supply_names[i];
2082 
2083     ret = devm_regulator_bulk_get(&client->dev, HI846_NUM_SUPPLIES,
2084                       hi846->supplies);
2085     if (ret < 0)
2086         return ret;
2087 
2088     v4l2_i2c_subdev_init(&hi846->sd, client, &hi846_subdev_ops);
2089 
2090     mutex_init(&hi846->mutex);
2091 
2092     ret = hi846_power_on(hi846);
2093     if (ret)
2094         goto err_mutex;
2095 
2096     ret = hi846_identify_module(hi846);
2097     if (ret)
2098         goto err_power_off;
2099 
2100     hi846->cur_mode = &supported_modes[0];
2101 
2102     ret = hi846_init_controls(hi846);
2103     if (ret) {
2104         dev_err(&client->dev, "failed to init controls: %d", ret);
2105         goto err_power_off;
2106     }
2107 
2108     hi846->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2109     hi846->sd.entity.ops = &hi846_subdev_entity_ops;
2110     hi846->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
2111     hi846->pad.flags = MEDIA_PAD_FL_SOURCE;
2112     ret = media_entity_pads_init(&hi846->sd.entity, 1, &hi846->pad);
2113     if (ret) {
2114         dev_err(&client->dev, "failed to init entity pads: %d", ret);
2115         goto err_v4l2_ctrl_handler_free;
2116     }
2117 
2118     ret = v4l2_async_register_subdev_sensor(&hi846->sd);
2119     if (ret < 0) {
2120         dev_err(&client->dev, "failed to register V4L2 subdev: %d",
2121             ret);
2122         goto err_media_entity_cleanup;
2123     }
2124 
2125     pm_runtime_set_active(&client->dev);
2126     pm_runtime_enable(&client->dev);
2127     pm_runtime_idle(&client->dev);
2128 
2129     return 0;
2130 
2131 err_media_entity_cleanup:
2132     media_entity_cleanup(&hi846->sd.entity);
2133 
2134 err_v4l2_ctrl_handler_free:
2135     v4l2_ctrl_handler_free(hi846->sd.ctrl_handler);
2136 
2137 err_power_off:
2138     hi846_power_off(hi846);
2139 
2140 err_mutex:
2141     mutex_destroy(&hi846->mutex);
2142 
2143     return ret;
2144 }
2145 
2146 static int hi846_remove(struct i2c_client *client)
2147 {
2148     struct v4l2_subdev *sd = i2c_get_clientdata(client);
2149     struct hi846 *hi846 = to_hi846(sd);
2150 
2151     v4l2_async_unregister_subdev(sd);
2152     media_entity_cleanup(&sd->entity);
2153     v4l2_ctrl_handler_free(sd->ctrl_handler);
2154 
2155     pm_runtime_disable(&client->dev);
2156     if (!pm_runtime_status_suspended(&client->dev))
2157         hi846_suspend(&client->dev);
2158     pm_runtime_set_suspended(&client->dev);
2159 
2160     mutex_destroy(&hi846->mutex);
2161 
2162     return 0;
2163 }
2164 
2165 static const struct dev_pm_ops hi846_pm_ops = {
2166     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
2167                 pm_runtime_force_resume)
2168     SET_RUNTIME_PM_OPS(hi846_suspend, hi846_resume, NULL)
2169 };
2170 
2171 static const struct of_device_id hi846_of_match[] = {
2172     { .compatible = "hynix,hi846", },
2173     {},
2174 };
2175 MODULE_DEVICE_TABLE(of, hi846_of_match);
2176 
2177 static struct i2c_driver hi846_i2c_driver = {
2178     .driver = {
2179         .name = "hi846",
2180         .pm = &hi846_pm_ops,
2181         .of_match_table = hi846_of_match,
2182     },
2183     .probe_new = hi846_probe,
2184     .remove = hi846_remove,
2185 };
2186 
2187 module_i2c_driver(hi846_i2c_driver);
2188 
2189 MODULE_AUTHOR("Angus Ainslie <angus@akkea.ca>");
2190 MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
2191 MODULE_DESCRIPTION("Hynix HI846 sensor driver");
2192 MODULE_LICENSE("GPL v2");