Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2022 Intel Corporation.
0003 
0004 #include <linux/acpi.h>
0005 #include <linux/clk.h>
0006 #include <linux/delay.h>
0007 #include <linux/i2c.h>
0008 #include <linux/module.h>
0009 #include <linux/pm_runtime.h>
0010 #include <linux/regulator/consumer.h>
0011 #include <media/v4l2-ctrls.h>
0012 #include <media/v4l2-device.h>
0013 #include <media/v4l2-fwnode.h>
0014 
0015 #define OV08D10_SCLK            144000000ULL
0016 #define OV08D10_XVCLK_19_2      19200000
0017 #define OV08D10_ROWCLK          36000
0018 #define OV08D10_DATA_LANES      2
0019 #define OV08D10_RGB_DEPTH       10
0020 
0021 #define OV08D10_REG_PAGE        0xfd
0022 #define OV08D10_REG_GLOBAL_EFFECTIVE        0x01
0023 #define OV08D10_REG_CHIP_ID_0       0x00
0024 #define OV08D10_REG_CHIP_ID_1       0x01
0025 #define OV08D10_ID_MASK         GENMASK(15, 0)
0026 #define OV08D10_CHIP_ID         0x5608
0027 
0028 #define OV08D10_REG_MODE_SELECT     0xa0
0029 #define OV08D10_MODE_STANDBY        0x00
0030 #define OV08D10_MODE_STREAMING      0x01
0031 
0032 /* vertical-timings from sensor */
0033 #define OV08D10_REG_VTS_H       0x05
0034 #define OV08D10_REG_VTS_L       0x06
0035 #define OV08D10_VTS_MAX         0x7fff
0036 
0037 /* Exposure controls from sensor */
0038 #define OV08D10_REG_EXPOSURE_H      0x02
0039 #define OV08D10_REG_EXPOSURE_M      0x03
0040 #define OV08D10_REG_EXPOSURE_L      0x04
0041 #define OV08D10_EXPOSURE_MIN        6
0042 #define OV08D10_EXPOSURE_MAX_MARGIN 6
0043 #define OV08D10_EXPOSURE_STEP       1
0044 
0045 /* Analog gain controls from sensor */
0046 #define OV08D10_REG_ANALOG_GAIN     0x24
0047 #define OV08D10_ANAL_GAIN_MIN       128
0048 #define OV08D10_ANAL_GAIN_MAX       2047
0049 #define OV08D10_ANAL_GAIN_STEP      1
0050 
0051 /* Digital gain controls from sensor */
0052 #define OV08D10_REG_MWB_DGAIN_C     0x21
0053 #define OV08D10_REG_MWB_DGAIN_F     0x22
0054 #define OV08D10_DGTL_GAIN_MIN       0
0055 #define OV08D10_DGTL_GAIN_MAX       4095
0056 #define OV08D10_DGTL_GAIN_STEP      1
0057 #define OV08D10_DGTL_GAIN_DEFAULT   1024
0058 
0059 /* Test Pattern Control */
0060 #define OV08D10_REG_TEST_PATTERN        0x12
0061 #define OV08D10_TEST_PATTERN_ENABLE     0x01
0062 #define OV08D10_TEST_PATTERN_DISABLE        0x00
0063 
0064 /* Flip Mirror Controls from sensor */
0065 #define OV08D10_REG_FLIP_OPT            0x32
0066 #define OV08D10_REG_FLIP_MASK           0x3
0067 
0068 #define to_ov08d10(_sd)     container_of(_sd, struct ov08d10, sd)
0069 
0070 struct ov08d10_reg {
0071     u8 address;
0072     u8 val;
0073 };
0074 
0075 struct ov08d10_reg_list {
0076     u32 num_of_regs;
0077     const struct ov08d10_reg *regs;
0078 };
0079 
0080 struct ov08d10_link_freq_config {
0081     const struct ov08d10_reg_list reg_list;
0082 };
0083 
0084 struct ov08d10_mode {
0085     /* Frame width in pixels */
0086     u32 width;
0087 
0088     /* Frame height in pixels */
0089     u32 height;
0090 
0091     /* Horizontal timining size */
0092     u32 hts;
0093 
0094     /* Default vertical timining size */
0095     u32 vts_def;
0096 
0097     /* Min vertical timining size */
0098     u32 vts_min;
0099 
0100     /* Link frequency needed for this resolution */
0101     u32 link_freq_index;
0102 
0103     /* Sensor register settings for this resolution */
0104     const struct ov08d10_reg_list reg_list;
0105 
0106     /* Number of data lanes */
0107     u8 data_lanes;
0108 };
0109 
0110 /* 3280x2460, 3264x2448 need 720Mbps/lane, 2 lanes */
0111 static const struct ov08d10_reg mipi_data_rate_720mbps[] = {
0112     {0xfd, 0x00},
0113     {0x11, 0x2a},
0114     {0x14, 0x43},
0115     {0x1a, 0x04},
0116     {0x1b, 0xe1},
0117     {0x1e, 0x13},
0118     {0xb7, 0x02}
0119 };
0120 
0121 /* 1632x1224 needs 360Mbps/lane, 2 lanes */
0122 static const struct ov08d10_reg mipi_data_rate_360mbps[] = {
0123     {0xfd, 0x00},
0124     {0x1a, 0x04},
0125     {0x1b, 0xe1},
0126     {0x1d, 0x00},
0127     {0x1c, 0x19},
0128     {0x11, 0x2a},
0129     {0x14, 0x54},
0130     {0x1e, 0x13},
0131     {0xb7, 0x02}
0132 };
0133 
0134 static const struct ov08d10_reg lane_2_mode_3280x2460[] = {
0135     /* 3280x2460 resolution */
0136     {0xfd, 0x01},
0137     {0x12, 0x00},
0138     {0x03, 0x12},
0139     {0x04, 0x58},
0140     {0x07, 0x05},
0141     {0x21, 0x02},
0142     {0x24, 0x30},
0143     {0x33, 0x03},
0144     {0x01, 0x03},
0145     {0x19, 0x10},
0146     {0x42, 0x55},
0147     {0x43, 0x00},
0148     {0x47, 0x07},
0149     {0x48, 0x08},
0150     {0xb2, 0x7f},
0151     {0xb3, 0x7b},
0152     {0xbd, 0x08},
0153     {0xd2, 0x57},
0154     {0xd3, 0x10},
0155     {0xd4, 0x08},
0156     {0xd5, 0x08},
0157     {0xd6, 0x06},
0158     {0xb1, 0x00},
0159     {0xb4, 0x00},
0160     {0xb7, 0x0a},
0161     {0xbc, 0x44},
0162     {0xbf, 0x48},
0163     {0xc1, 0x10},
0164     {0xc3, 0x24},
0165     {0xc8, 0x03},
0166     {0xc9, 0xf8},
0167     {0xe1, 0x33},
0168     {0xe2, 0xbb},
0169     {0x51, 0x0c},
0170     {0x52, 0x0a},
0171     {0x57, 0x8c},
0172     {0x59, 0x09},
0173     {0x5a, 0x08},
0174     {0x5e, 0x10},
0175     {0x60, 0x02},
0176     {0x6d, 0x5c},
0177     {0x76, 0x16},
0178     {0x7c, 0x11},
0179     {0x90, 0x28},
0180     {0x91, 0x16},
0181     {0x92, 0x1c},
0182     {0x93, 0x24},
0183     {0x95, 0x48},
0184     {0x9c, 0x06},
0185     {0xca, 0x0c},
0186     {0xce, 0x0d},
0187     {0xfd, 0x01},
0188     {0xc0, 0x00},
0189     {0xdd, 0x18},
0190     {0xde, 0x19},
0191     {0xdf, 0x32},
0192     {0xe0, 0x70},
0193     {0xfd, 0x01},
0194     {0xc2, 0x05},
0195     {0xd7, 0x88},
0196     {0xd8, 0x77},
0197     {0xd9, 0x00},
0198     {0xfd, 0x07},
0199     {0x00, 0xf8},
0200     {0x01, 0x2b},
0201     {0x05, 0x40},
0202     {0x08, 0x06},
0203     {0x09, 0x11},
0204     {0x28, 0x6f},
0205     {0x2a, 0x20},
0206     {0x2b, 0x05},
0207     {0x5e, 0x10},
0208     {0x52, 0x00},
0209     {0x53, 0x7c},
0210     {0x54, 0x00},
0211     {0x55, 0x7c},
0212     {0x56, 0x00},
0213     {0x57, 0x7c},
0214     {0x58, 0x00},
0215     {0x59, 0x7c},
0216     {0xfd, 0x02},
0217     {0x9a, 0x30},
0218     {0xa8, 0x02},
0219     {0xfd, 0x02},
0220     {0xa1, 0x01},
0221     {0xa2, 0x09},
0222     {0xa3, 0x9c},
0223     {0xa5, 0x00},
0224     {0xa6, 0x0c},
0225     {0xa7, 0xd0},
0226     {0xfd, 0x00},
0227     {0x24, 0x01},
0228     {0xc0, 0x16},
0229     {0xc1, 0x08},
0230     {0xc2, 0x30},
0231     {0x8e, 0x0c},
0232     {0x8f, 0xd0},
0233     {0x90, 0x09},
0234     {0x91, 0x9c},
0235     {0xfd, 0x05},
0236     {0x04, 0x40},
0237     {0x07, 0x00},
0238     {0x0d, 0x01},
0239     {0x0f, 0x01},
0240     {0x10, 0x00},
0241     {0x11, 0x00},
0242     {0x12, 0x0c},
0243     {0x13, 0xcf},
0244     {0x14, 0x00},
0245     {0x15, 0x00},
0246     {0xfd, 0x00},
0247     {0x20, 0x0f},
0248     {0xe7, 0x03},
0249     {0xe7, 0x00}
0250 };
0251 
0252 static const struct ov08d10_reg lane_2_mode_3264x2448[] = {
0253     /* 3264x2448 resolution */
0254     {0xfd, 0x01},
0255     {0x12, 0x00},
0256     {0x03, 0x12},
0257     {0x04, 0x58},
0258     {0x07, 0x05},
0259     {0x21, 0x02},
0260     {0x24, 0x30},
0261     {0x33, 0x03},
0262     {0x01, 0x03},
0263     {0x19, 0x10},
0264     {0x42, 0x55},
0265     {0x43, 0x00},
0266     {0x47, 0x07},
0267     {0x48, 0x08},
0268     {0xb2, 0x7f},
0269     {0xb3, 0x7b},
0270     {0xbd, 0x08},
0271     {0xd2, 0x57},
0272     {0xd3, 0x10},
0273     {0xd4, 0x08},
0274     {0xd5, 0x08},
0275     {0xd6, 0x06},
0276     {0xb1, 0x00},
0277     {0xb4, 0x00},
0278     {0xb7, 0x0a},
0279     {0xbc, 0x44},
0280     {0xbf, 0x48},
0281     {0xc1, 0x10},
0282     {0xc3, 0x24},
0283     {0xc8, 0x03},
0284     {0xc9, 0xf8},
0285     {0xe1, 0x33},
0286     {0xe2, 0xbb},
0287     {0x51, 0x0c},
0288     {0x52, 0x0a},
0289     {0x57, 0x8c},
0290     {0x59, 0x09},
0291     {0x5a, 0x08},
0292     {0x5e, 0x10},
0293     {0x60, 0x02},
0294     {0x6d, 0x5c},
0295     {0x76, 0x16},
0296     {0x7c, 0x11},
0297     {0x90, 0x28},
0298     {0x91, 0x16},
0299     {0x92, 0x1c},
0300     {0x93, 0x24},
0301     {0x95, 0x48},
0302     {0x9c, 0x06},
0303     {0xca, 0x0c},
0304     {0xce, 0x0d},
0305     {0xfd, 0x01},
0306     {0xc0, 0x00},
0307     {0xdd, 0x18},
0308     {0xde, 0x19},
0309     {0xdf, 0x32},
0310     {0xe0, 0x70},
0311     {0xfd, 0x01},
0312     {0xc2, 0x05},
0313     {0xd7, 0x88},
0314     {0xd8, 0x77},
0315     {0xd9, 0x00},
0316     {0xfd, 0x07},
0317     {0x00, 0xf8},
0318     {0x01, 0x2b},
0319     {0x05, 0x40},
0320     {0x08, 0x06},
0321     {0x09, 0x11},
0322     {0x28, 0x6f},
0323     {0x2a, 0x20},
0324     {0x2b, 0x05},
0325     {0x5e, 0x10},
0326     {0x52, 0x00},
0327     {0x53, 0x7c},
0328     {0x54, 0x00},
0329     {0x55, 0x7c},
0330     {0x56, 0x00},
0331     {0x57, 0x7c},
0332     {0x58, 0x00},
0333     {0x59, 0x7c},
0334     {0xfd, 0x02},
0335     {0x9a, 0x30},
0336     {0xa8, 0x02},
0337     {0xfd, 0x02},
0338     {0xa1, 0x09},
0339     {0xa2, 0x09},
0340     {0xa3, 0x90},
0341     {0xa5, 0x08},
0342     {0xa6, 0x0c},
0343     {0xa7, 0xc0},
0344     {0xfd, 0x00},
0345     {0x24, 0x01},
0346     {0xc0, 0x16},
0347     {0xc1, 0x08},
0348     {0xc2, 0x30},
0349     {0x8e, 0x0c},
0350     {0x8f, 0xc0},
0351     {0x90, 0x09},
0352     {0x91, 0x90},
0353     {0xfd, 0x05},
0354     {0x04, 0x40},
0355     {0x07, 0x00},
0356     {0x0d, 0x01},
0357     {0x0f, 0x01},
0358     {0x10, 0x00},
0359     {0x11, 0x00},
0360     {0x12, 0x0c},
0361     {0x13, 0xcf},
0362     {0x14, 0x00},
0363     {0x15, 0x00},
0364     {0xfd, 0x00},
0365     {0x20, 0x0f},
0366     {0xe7, 0x03},
0367     {0xe7, 0x00}
0368 };
0369 
0370 static const struct ov08d10_reg lane_2_mode_1632x1224[] = {
0371     /* 1640x1232 resolution */
0372     {0xfd, 0x01},
0373     {0x1a, 0x0a},
0374     {0x1b, 0x08},
0375     {0x2a, 0x01},
0376     {0x2b, 0x9a},
0377     {0xfd, 0x01},
0378     {0x12, 0x00},
0379     {0x03, 0x05},
0380     {0x04, 0xe2},
0381     {0x07, 0x05},
0382     {0x21, 0x02},
0383     {0x24, 0x30},
0384     {0x33, 0x03},
0385     {0x31, 0x06},
0386     {0x33, 0x03},
0387     {0x01, 0x03},
0388     {0x19, 0x10},
0389     {0x42, 0x55},
0390     {0x43, 0x00},
0391     {0x47, 0x07},
0392     {0x48, 0x08},
0393     {0xb2, 0x7f},
0394     {0xb3, 0x7b},
0395     {0xbd, 0x08},
0396     {0xd2, 0x57},
0397     {0xd3, 0x10},
0398     {0xd4, 0x08},
0399     {0xd5, 0x08},
0400     {0xd6, 0x06},
0401     {0xb1, 0x00},
0402     {0xb4, 0x00},
0403     {0xb7, 0x0a},
0404     {0xbc, 0x44},
0405     {0xbf, 0x48},
0406     {0xc1, 0x10},
0407     {0xc3, 0x24},
0408     {0xc8, 0x03},
0409     {0xc9, 0xf8},
0410     {0xe1, 0x33},
0411     {0xe2, 0xbb},
0412     {0x51, 0x0c},
0413     {0x52, 0x0a},
0414     {0x57, 0x8c},
0415     {0x59, 0x09},
0416     {0x5a, 0x08},
0417     {0x5e, 0x10},
0418     {0x60, 0x02},
0419     {0x6d, 0x5c},
0420     {0x76, 0x16},
0421     {0x7c, 0x1a},
0422     {0x90, 0x28},
0423     {0x91, 0x16},
0424     {0x92, 0x1c},
0425     {0x93, 0x24},
0426     {0x95, 0x48},
0427     {0x9c, 0x06},
0428     {0xca, 0x0c},
0429     {0xce, 0x0d},
0430     {0xfd, 0x01},
0431     {0xc0, 0x00},
0432     {0xdd, 0x18},
0433     {0xde, 0x19},
0434     {0xdf, 0x32},
0435     {0xe0, 0x70},
0436     {0xfd, 0x01},
0437     {0xc2, 0x05},
0438     {0xd7, 0x88},
0439     {0xd8, 0x77},
0440     {0xd9, 0x00},
0441     {0xfd, 0x07},
0442     {0x00, 0xf8},
0443     {0x01, 0x2b},
0444     {0x05, 0x40},
0445     {0x08, 0x03},
0446     {0x09, 0x08},
0447     {0x28, 0x6f},
0448     {0x2a, 0x20},
0449     {0x2b, 0x05},
0450     {0x2c, 0x01},
0451     {0x50, 0x02},
0452     {0x51, 0x03},
0453     {0x5e, 0x00},
0454     {0x52, 0x00},
0455     {0x53, 0x7c},
0456     {0x54, 0x00},
0457     {0x55, 0x7c},
0458     {0x56, 0x00},
0459     {0x57, 0x7c},
0460     {0x58, 0x00},
0461     {0x59, 0x7c},
0462     {0xfd, 0x02},
0463     {0x9a, 0x30},
0464     {0xa8, 0x02},
0465     {0xfd, 0x02},
0466     {0xa9, 0x04},
0467     {0xaa, 0xd0},
0468     {0xab, 0x06},
0469     {0xac, 0x68},
0470     {0xa1, 0x09},
0471     {0xa2, 0x04},
0472     {0xa3, 0xc8},
0473     {0xa5, 0x04},
0474     {0xa6, 0x06},
0475     {0xa7, 0x60},
0476     {0xfd, 0x05},
0477     {0x06, 0x80},
0478     {0x18, 0x06},
0479     {0x19, 0x68},
0480     {0xfd, 0x00},
0481     {0x24, 0x01},
0482     {0xc0, 0x16},
0483     {0xc1, 0x08},
0484     {0xc2, 0x30},
0485     {0x8e, 0x06},
0486     {0x8f, 0x60},
0487     {0x90, 0x04},
0488     {0x91, 0xc8},
0489     {0x93, 0x0e},
0490     {0x94, 0x77},
0491     {0x95, 0x77},
0492     {0x96, 0x10},
0493     {0x98, 0x88},
0494     {0x9c, 0x1a},
0495     {0xfd, 0x05},
0496     {0x04, 0x40},
0497     {0x07, 0x99},
0498     {0x0d, 0x03},
0499     {0x0f, 0x03},
0500     {0x10, 0x00},
0501     {0x11, 0x00},
0502     {0x12, 0x0c},
0503     {0x13, 0xcf},
0504     {0x14, 0x00},
0505     {0x15, 0x00},
0506     {0xfd, 0x00},
0507     {0x20, 0x0f},
0508     {0xe7, 0x03},
0509     {0xe7, 0x00},
0510 };
0511 
0512 static const char * const ov08d10_test_pattern_menu[] = {
0513     "Disabled",
0514     "Standard Color Bar",
0515 };
0516 
0517 struct ov08d10 {
0518     struct v4l2_subdev sd;
0519     struct media_pad pad;
0520     struct v4l2_ctrl_handler ctrl_handler;
0521 
0522     struct clk      *xvclk;
0523 
0524     /* V4L2 Controls */
0525     struct v4l2_ctrl *link_freq;
0526     struct v4l2_ctrl *pixel_rate;
0527     struct v4l2_ctrl *vblank;
0528     struct v4l2_ctrl *hblank;
0529     struct v4l2_ctrl *vflip;
0530     struct v4l2_ctrl *hflip;
0531     struct v4l2_ctrl *exposure;
0532 
0533     /* Current mode */
0534     const struct ov08d10_mode *cur_mode;
0535 
0536     /* To serialize asynchronus callbacks */
0537     struct mutex mutex;
0538 
0539     /* Streaming on/off */
0540     bool streaming;
0541 
0542     /* lanes index */
0543     u8 nlanes;
0544 
0545     const struct ov08d10_lane_cfg *priv_lane;
0546     u8 modes_size;
0547 };
0548 
0549 struct ov08d10_lane_cfg {
0550     const s64 link_freq_menu[2];
0551     const struct ov08d10_link_freq_config link_freq_configs[2];
0552     const struct ov08d10_mode sp_modes[3];
0553 };
0554 
0555 static const struct ov08d10_lane_cfg lane_cfg_2 = {
0556     {
0557         720000000,
0558         360000000,
0559     },
0560     {{
0561         .reg_list = {
0562             .num_of_regs =
0563                 ARRAY_SIZE(mipi_data_rate_720mbps),
0564             .regs = mipi_data_rate_720mbps,
0565         }
0566     },
0567     {
0568         .reg_list = {
0569             .num_of_regs =
0570                 ARRAY_SIZE(mipi_data_rate_360mbps),
0571             .regs = mipi_data_rate_360mbps,
0572         }
0573     }},
0574     {{
0575         .width = 3280,
0576         .height = 2460,
0577         .hts = 1840,
0578         .vts_def = 2504,
0579         .vts_min = 2504,
0580         .reg_list = {
0581             .num_of_regs = ARRAY_SIZE(lane_2_mode_3280x2460),
0582             .regs = lane_2_mode_3280x2460,
0583         },
0584         .link_freq_index = 0,
0585         .data_lanes = 2,
0586     },
0587     {
0588         .width = 3264,
0589         .height = 2448,
0590         .hts = 1840,
0591         .vts_def = 2504,
0592         .vts_min = 2504,
0593         .reg_list = {
0594             .num_of_regs = ARRAY_SIZE(lane_2_mode_3264x2448),
0595             .regs = lane_2_mode_3264x2448,
0596         },
0597         .link_freq_index = 0,
0598         .data_lanes = 2,
0599     },
0600     {
0601         .width = 1632,
0602         .height = 1224,
0603         .hts = 1912,
0604         .vts_def = 3736,
0605         .vts_min = 3736,
0606         .reg_list = {
0607             .num_of_regs = ARRAY_SIZE(lane_2_mode_1632x1224),
0608             .regs = lane_2_mode_1632x1224,
0609         },
0610         .link_freq_index = 1,
0611         .data_lanes = 2,
0612     }}
0613 };
0614 
0615 static u32 ov08d10_get_format_code(struct ov08d10 *ov08d10)
0616 {
0617     static const u32 codes[2][2] = {
0618         { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10},
0619         { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10},
0620     };
0621 
0622     return codes[ov08d10->vflip->val][ov08d10->hflip->val];
0623 }
0624 
0625 static unsigned int ov08d10_modes_num(const struct ov08d10 *ov08d10)
0626 {
0627     unsigned int i, count = 0;
0628 
0629     for (i = 0; i < ARRAY_SIZE(ov08d10->priv_lane->sp_modes); i++) {
0630         if (ov08d10->priv_lane->sp_modes[i].width == 0)
0631             break;
0632         count++;
0633     }
0634 
0635     return count;
0636 }
0637 
0638 static u64 to_rate(const s64 *link_freq_menu,
0639            u32 f_index, u8 nlanes)
0640 {
0641     u64 pixel_rate = link_freq_menu[f_index] * 2 * nlanes;
0642 
0643     do_div(pixel_rate, OV08D10_RGB_DEPTH);
0644 
0645     return pixel_rate;
0646 }
0647 
0648 static u64 to_pixels_per_line(const s64 *link_freq_menu, u32 hts,
0649                   u32 f_index, u8 nlanes)
0650 {
0651     u64 ppl = hts * to_rate(link_freq_menu, f_index, nlanes);
0652 
0653     do_div(ppl, OV08D10_SCLK);
0654 
0655     return ppl;
0656 }
0657 
0658 static int ov08d10_write_reg_list(struct ov08d10 *ov08d10,
0659                   const struct ov08d10_reg_list *r_list)
0660 {
0661     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0662     unsigned int i;
0663     int ret;
0664 
0665     for (i = 0; i < r_list->num_of_regs; i++) {
0666         ret = i2c_smbus_write_byte_data(client, r_list->regs[i].address,
0667                         r_list->regs[i].val);
0668         if (ret) {
0669             dev_err_ratelimited(&client->dev,
0670                         "failed to write reg 0x%2.2x. error = %d",
0671                         r_list->regs[i].address, ret);
0672             return ret;
0673         }
0674     }
0675 
0676     return 0;
0677 }
0678 
0679 static int ov08d10_update_analog_gain(struct ov08d10 *ov08d10, u32 a_gain)
0680 {
0681     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0682     u8 val;
0683     int ret;
0684 
0685     val = ((a_gain >> 3) & 0xFF);
0686     /* CIS control registers */
0687     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0688     if (ret < 0)
0689         return ret;
0690 
0691     /* update AGAIN */
0692     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_ANALOG_GAIN, val);
0693     if (ret < 0)
0694         return ret;
0695 
0696     return i2c_smbus_write_byte_data(client,
0697                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0698 }
0699 
0700 static int ov08d10_update_digital_gain(struct ov08d10 *ov08d10, u32 d_gain)
0701 {
0702     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0703     u8 val;
0704     int ret;
0705 
0706     d_gain = (d_gain >> 1);
0707     /* CIS control registers */
0708     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0709     if (ret < 0)
0710         return ret;
0711 
0712     val = ((d_gain >> 8) & 0x3F);
0713     /* update DGAIN */
0714     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_MWB_DGAIN_C, val);
0715     if (ret < 0)
0716         return ret;
0717 
0718     val = d_gain & 0xFF;
0719     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_MWB_DGAIN_F, val);
0720     if (ret < 0)
0721         return ret;
0722 
0723     return i2c_smbus_write_byte_data(client,
0724                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0725 }
0726 
0727 static int ov08d10_set_exposure(struct ov08d10 *ov08d10, u32 exposure)
0728 {
0729     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0730     u8 val;
0731     u8 hts_h, hts_l;
0732     u32 hts, cur_vts, exp_cal;
0733     int ret;
0734 
0735     cur_vts = ov08d10->cur_mode->vts_def;
0736     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0737     if (ret < 0)
0738         return ret;
0739 
0740     hts_h = i2c_smbus_read_byte_data(client, 0x37);
0741     hts_l = i2c_smbus_read_byte_data(client, 0x38);
0742     hts = ((hts_h << 8) | (hts_l));
0743     exp_cal = 66 * OV08D10_ROWCLK / hts;
0744     exposure = exposure * exp_cal / (cur_vts - OV08D10_EXPOSURE_MAX_MARGIN);
0745     /* CIS control registers */
0746     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0747     if (ret < 0)
0748         return ret;
0749 
0750     /* update exposure */
0751     val = ((exposure >> 16) & 0xFF);
0752     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_EXPOSURE_H, val);
0753     if (ret < 0)
0754         return ret;
0755 
0756     val = ((exposure >> 8) & 0xFF);
0757     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_EXPOSURE_M, val);
0758     if (ret < 0)
0759         return ret;
0760 
0761     val = exposure & 0xFF;
0762     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_EXPOSURE_L, val);
0763     if (ret < 0)
0764         return ret;
0765 
0766     return i2c_smbus_write_byte_data(client,
0767                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0768 }
0769 
0770 static int ov08d10_set_vblank(struct ov08d10 *ov08d10, u32 vblank)
0771 {
0772     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0773     u8 val;
0774     int ret;
0775 
0776     /* CIS control registers */
0777     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0778     if (ret < 0)
0779         return ret;
0780 
0781     val = ((vblank >> 8) & 0xFF);
0782     /* update vblank */
0783     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_VTS_H, val);
0784     if (ret < 0)
0785         return ret;
0786 
0787     val = vblank & 0xFF;
0788     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_VTS_L, val);
0789     if (ret < 0)
0790         return ret;
0791 
0792     return i2c_smbus_write_byte_data(client,
0793                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0794 }
0795 
0796 static int ov08d10_test_pattern(struct ov08d10 *ov08d10, u32 pattern)
0797 {
0798     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0799     u8 val;
0800     int ret;
0801 
0802     if (pattern)
0803         val = OV08D10_TEST_PATTERN_ENABLE;
0804     else
0805         val = OV08D10_TEST_PATTERN_DISABLE;
0806 
0807     /* CIS control registers */
0808     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0809     if (ret < 0)
0810         return ret;
0811 
0812     ret = i2c_smbus_write_byte_data(client,
0813                     OV08D10_REG_TEST_PATTERN, val);
0814     if (ret < 0)
0815         return ret;
0816 
0817     return i2c_smbus_write_byte_data(client,
0818                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0819 }
0820 
0821 static int ov08d10_set_ctrl_flip(struct ov08d10 *ov08d10, u32 ctrl_val)
0822 {
0823     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0824     u8 val;
0825     int ret;
0826 
0827     /* System control registers */
0828     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0829     if (ret < 0)
0830         return ret;
0831 
0832     ret = i2c_smbus_read_byte_data(client, OV08D10_REG_FLIP_OPT);
0833     if (ret < 0)
0834         return ret;
0835 
0836     val = ret | (ctrl_val & OV08D10_REG_FLIP_MASK);
0837 
0838     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0839     if (ret < 0)
0840         return ret;
0841 
0842     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_FLIP_OPT, val);
0843 
0844     if (ret < 0)
0845         return ret;
0846 
0847     return i2c_smbus_write_byte_data(client,
0848                      OV08D10_REG_GLOBAL_EFFECTIVE, 0x01);
0849 }
0850 
0851 static int ov08d10_set_ctrl(struct v4l2_ctrl *ctrl)
0852 {
0853     struct ov08d10 *ov08d10 = container_of(ctrl->handler,
0854                          struct ov08d10, ctrl_handler);
0855     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
0856     s64 exposure_max;
0857     int ret;
0858 
0859     /* Propagate change of current control to all related controls */
0860     if (ctrl->id == V4L2_CID_VBLANK) {
0861         /* Update max exposure while meeting expected vblanking */
0862         exposure_max = ov08d10->cur_mode->height + ctrl->val -
0863                    OV08D10_EXPOSURE_MAX_MARGIN;
0864         __v4l2_ctrl_modify_range(ov08d10->exposure,
0865                      ov08d10->exposure->minimum,
0866                      exposure_max, ov08d10->exposure->step,
0867                      exposure_max);
0868     }
0869 
0870     /* V4L2 controls values will be applied only when power is already up */
0871     if (!pm_runtime_get_if_in_use(&client->dev))
0872         return 0;
0873 
0874     switch (ctrl->id) {
0875     case V4L2_CID_ANALOGUE_GAIN:
0876         ret = ov08d10_update_analog_gain(ov08d10, ctrl->val);
0877         break;
0878 
0879     case V4L2_CID_DIGITAL_GAIN:
0880         ret = ov08d10_update_digital_gain(ov08d10, ctrl->val);
0881         break;
0882 
0883     case V4L2_CID_EXPOSURE:
0884         ret = ov08d10_set_exposure(ov08d10, ctrl->val);
0885         break;
0886 
0887     case V4L2_CID_VBLANK:
0888         ret = ov08d10_set_vblank(ov08d10, ctrl->val);
0889         break;
0890 
0891     case V4L2_CID_TEST_PATTERN:
0892         ret = ov08d10_test_pattern(ov08d10, ctrl->val);
0893         break;
0894 
0895     case V4L2_CID_HFLIP:
0896     case V4L2_CID_VFLIP:
0897         ret = ov08d10_set_ctrl_flip(ov08d10,
0898                         ov08d10->hflip->val |
0899                         ov08d10->vflip->val << 1);
0900         break;
0901 
0902     default:
0903         ret = -EINVAL;
0904         break;
0905     }
0906 
0907     pm_runtime_put(&client->dev);
0908 
0909     return ret;
0910 }
0911 
0912 static const struct v4l2_ctrl_ops ov08d10_ctrl_ops = {
0913     .s_ctrl = ov08d10_set_ctrl,
0914 };
0915 
0916 static int ov08d10_init_controls(struct ov08d10 *ov08d10)
0917 {
0918     struct v4l2_ctrl_handler *ctrl_hdlr;
0919     u8 link_freq_size;
0920     s64 exposure_max;
0921     s64 vblank_def;
0922     s64 vblank_min;
0923     s64 h_blank;
0924     s64 pixel_rate_max;
0925     const struct ov08d10_mode *mode;
0926     int ret;
0927 
0928     ctrl_hdlr = &ov08d10->ctrl_handler;
0929     ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
0930     if (ret)
0931         return ret;
0932 
0933     ctrl_hdlr->lock = &ov08d10->mutex;
0934     link_freq_size = ARRAY_SIZE(ov08d10->priv_lane->link_freq_menu);
0935     ov08d10->link_freq =
0936         v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov08d10_ctrl_ops,
0937                        V4L2_CID_LINK_FREQ,
0938                        link_freq_size - 1,
0939                        0,
0940                        ov08d10->priv_lane->link_freq_menu);
0941     if (ov08d10->link_freq)
0942         ov08d10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
0943 
0944     pixel_rate_max = to_rate(ov08d10->priv_lane->link_freq_menu, 0,
0945                  ov08d10->cur_mode->data_lanes);
0946     ov08d10->pixel_rate =
0947         v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0948                   V4L2_CID_PIXEL_RATE, 0, pixel_rate_max, 1,
0949                   pixel_rate_max);
0950 
0951     mode = ov08d10->cur_mode;
0952     vblank_def = mode->vts_def - mode->height;
0953     vblank_min = mode->vts_min - mode->height;
0954     ov08d10->vblank =
0955         v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0956                   V4L2_CID_VBLANK, vblank_min,
0957                   OV08D10_VTS_MAX - mode->height, 1,
0958                   vblank_def);
0959 
0960     h_blank = to_pixels_per_line(ov08d10->priv_lane->link_freq_menu,
0961                      mode->hts, mode->link_freq_index,
0962                      mode->data_lanes) -
0963                      mode->width;
0964     ov08d10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0965                         V4L2_CID_HBLANK, h_blank, h_blank,
0966                         1, h_blank);
0967     if (ov08d10->hblank)
0968         ov08d10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
0969 
0970     v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
0971               OV08D10_ANAL_GAIN_MIN, OV08D10_ANAL_GAIN_MAX,
0972               OV08D10_ANAL_GAIN_STEP, OV08D10_ANAL_GAIN_MIN);
0973 
0974     v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
0975               OV08D10_DGTL_GAIN_MIN, OV08D10_DGTL_GAIN_MAX,
0976               OV08D10_DGTL_GAIN_STEP, OV08D10_DGTL_GAIN_DEFAULT);
0977 
0978     exposure_max = mode->vts_def - OV08D10_EXPOSURE_MAX_MARGIN;
0979     ov08d10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0980                           V4L2_CID_EXPOSURE,
0981                           OV08D10_EXPOSURE_MIN,
0982                           exposure_max,
0983                           OV08D10_EXPOSURE_STEP,
0984                           exposure_max);
0985 
0986     v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov08d10_ctrl_ops,
0987                      V4L2_CID_TEST_PATTERN,
0988                      ARRAY_SIZE(ov08d10_test_pattern_menu) - 1,
0989                      0, 0, ov08d10_test_pattern_menu);
0990 
0991     ov08d10->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0992                        V4L2_CID_HFLIP, 0, 1, 1, 0);
0993     ov08d10->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov08d10_ctrl_ops,
0994                        V4L2_CID_VFLIP, 0, 1, 1, 0);
0995     if (ctrl_hdlr->error)
0996         return ctrl_hdlr->error;
0997 
0998     ov08d10->sd.ctrl_handler = ctrl_hdlr;
0999 
1000     return 0;
1001 }
1002 
1003 static void ov08d10_update_pad_format(struct ov08d10 *ov08d10,
1004                       const struct ov08d10_mode *mode,
1005                       struct v4l2_mbus_framefmt *fmt)
1006 {
1007     fmt->width = mode->width;
1008     fmt->height = mode->height;
1009     fmt->code = ov08d10_get_format_code(ov08d10);
1010     fmt->field = V4L2_FIELD_NONE;
1011 }
1012 
1013 static int ov08d10_start_streaming(struct ov08d10 *ov08d10)
1014 {
1015     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
1016     const struct ov08d10_reg_list *reg_list;
1017     int link_freq_index, ret;
1018 
1019     link_freq_index = ov08d10->cur_mode->link_freq_index;
1020     reg_list =
1021         &ov08d10->priv_lane->link_freq_configs[link_freq_index].reg_list;
1022 
1023     /* soft reset */
1024     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
1025     if (ret < 0) {
1026         dev_err(&client->dev, "failed to reset sensor");
1027         return ret;
1028     }
1029     ret = i2c_smbus_write_byte_data(client, 0x20, 0x0e);
1030     if (ret < 0) {
1031         dev_err(&client->dev, "failed to reset sensor");
1032         return ret;
1033     }
1034     usleep_range(3000, 4000);
1035     ret = i2c_smbus_write_byte_data(client, 0x20, 0x0b);
1036     if (ret < 0) {
1037         dev_err(&client->dev, "failed to reset sensor");
1038         return ret;
1039     }
1040 
1041     /* update sensor setting */
1042     ret = ov08d10_write_reg_list(ov08d10, reg_list);
1043     if (ret) {
1044         dev_err(&client->dev, "failed to set plls");
1045         return ret;
1046     }
1047 
1048     reg_list = &ov08d10->cur_mode->reg_list;
1049     ret = ov08d10_write_reg_list(ov08d10, reg_list);
1050     if (ret) {
1051         dev_err(&client->dev, "failed to set mode");
1052         return ret;
1053     }
1054 
1055     ret = __v4l2_ctrl_handler_setup(ov08d10->sd.ctrl_handler);
1056     if (ret)
1057         return ret;
1058 
1059     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
1060     if (ret < 0)
1061         return ret;
1062 
1063     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_MODE_SELECT,
1064                     OV08D10_MODE_STREAMING);
1065     if (ret < 0)
1066         return ret;
1067 
1068     return i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
1069 }
1070 
1071 static void ov08d10_stop_streaming(struct ov08d10 *ov08d10)
1072 {
1073     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
1074     int ret;
1075 
1076     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
1077     if (ret < 0) {
1078         dev_err(&client->dev, "failed to stop streaming");
1079         return;
1080     }
1081     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_MODE_SELECT,
1082                     OV08D10_MODE_STANDBY);
1083     if (ret < 0) {
1084         dev_err(&client->dev, "failed to stop streaming");
1085         return;
1086     }
1087 
1088     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
1089     if (ret < 0) {
1090         dev_err(&client->dev, "failed to stop streaming");
1091         return;
1092     }
1093 }
1094 
1095 static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable)
1096 {
1097     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1098     struct i2c_client *client = v4l2_get_subdevdata(sd);
1099     int ret = 0;
1100 
1101     if (ov08d10->streaming == enable)
1102         return 0;
1103 
1104     mutex_lock(&ov08d10->mutex);
1105     if (enable) {
1106         ret = pm_runtime_resume_and_get(&client->dev);
1107         if (ret < 0) {
1108             mutex_unlock(&ov08d10->mutex);
1109             return ret;
1110         }
1111 
1112         ret = ov08d10_start_streaming(ov08d10);
1113         if (ret) {
1114             enable = 0;
1115             ov08d10_stop_streaming(ov08d10);
1116             pm_runtime_put(&client->dev);
1117         }
1118     } else {
1119         ov08d10_stop_streaming(ov08d10);
1120         pm_runtime_put(&client->dev);
1121     }
1122 
1123     ov08d10->streaming = enable;
1124 
1125     /* vflip and hflip cannot change during streaming */
1126     __v4l2_ctrl_grab(ov08d10->vflip, enable);
1127     __v4l2_ctrl_grab(ov08d10->hflip, enable);
1128 
1129     mutex_unlock(&ov08d10->mutex);
1130 
1131     return ret;
1132 }
1133 
1134 static int __maybe_unused ov08d10_suspend(struct device *dev)
1135 {
1136     struct i2c_client *client = to_i2c_client(dev);
1137     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1138     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1139 
1140     mutex_lock(&ov08d10->mutex);
1141     if (ov08d10->streaming)
1142         ov08d10_stop_streaming(ov08d10);
1143 
1144     mutex_unlock(&ov08d10->mutex);
1145 
1146     return 0;
1147 }
1148 
1149 static int __maybe_unused ov08d10_resume(struct device *dev)
1150 {
1151     struct i2c_client *client = to_i2c_client(dev);
1152     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1153     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1154     int ret;
1155 
1156     mutex_lock(&ov08d10->mutex);
1157 
1158     if (ov08d10->streaming) {
1159         ret = ov08d10_start_streaming(ov08d10);
1160         if (ret) {
1161             ov08d10->streaming = false;
1162             ov08d10_stop_streaming(ov08d10);
1163             mutex_unlock(&ov08d10->mutex);
1164             return ret;
1165         }
1166     }
1167 
1168     mutex_unlock(&ov08d10->mutex);
1169 
1170     return 0;
1171 }
1172 
1173 static int ov08d10_set_format(struct v4l2_subdev *sd,
1174                   struct v4l2_subdev_state *sd_state,
1175                   struct v4l2_subdev_format *fmt)
1176 {
1177     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1178     const struct ov08d10_mode *mode;
1179     s32 vblank_def, h_blank;
1180     s64 pixel_rate;
1181 
1182     mode = v4l2_find_nearest_size(ov08d10->priv_lane->sp_modes,
1183                       ov08d10->modes_size,
1184                       width, height, fmt->format.width,
1185                       fmt->format.height);
1186 
1187     mutex_lock(&ov08d10->mutex);
1188     ov08d10_update_pad_format(ov08d10, mode, &fmt->format);
1189     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1190         *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) =
1191                                 fmt->format;
1192     } else {
1193         ov08d10->cur_mode = mode;
1194         __v4l2_ctrl_s_ctrl(ov08d10->link_freq, mode->link_freq_index);
1195         pixel_rate = to_rate(ov08d10->priv_lane->link_freq_menu,
1196                      mode->link_freq_index,
1197                      ov08d10->cur_mode->data_lanes);
1198         __v4l2_ctrl_s_ctrl_int64(ov08d10->pixel_rate, pixel_rate);
1199 
1200         /* Update limits and set FPS to default */
1201         vblank_def = mode->vts_def - mode->height;
1202         __v4l2_ctrl_modify_range(ov08d10->vblank,
1203                      mode->vts_min - mode->height,
1204                      OV08D10_VTS_MAX - mode->height, 1,
1205                      vblank_def);
1206         __v4l2_ctrl_s_ctrl(ov08d10->vblank, vblank_def);
1207         h_blank = to_pixels_per_line(ov08d10->priv_lane->link_freq_menu,
1208                          mode->hts,
1209                          mode->link_freq_index,
1210                          ov08d10->cur_mode->data_lanes)
1211                          - mode->width;
1212         __v4l2_ctrl_modify_range(ov08d10->hblank, h_blank, h_blank, 1,
1213                      h_blank);
1214     }
1215 
1216     mutex_unlock(&ov08d10->mutex);
1217 
1218     return 0;
1219 }
1220 
1221 static int ov08d10_get_format(struct v4l2_subdev *sd,
1222                   struct v4l2_subdev_state *sd_state,
1223                   struct v4l2_subdev_format *fmt)
1224 {
1225     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1226 
1227     mutex_lock(&ov08d10->mutex);
1228     if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
1229         fmt->format = *v4l2_subdev_get_try_format(&ov08d10->sd,
1230                               sd_state,
1231                               fmt->pad);
1232     else
1233         ov08d10_update_pad_format(ov08d10, ov08d10->cur_mode,
1234                       &fmt->format);
1235 
1236     mutex_unlock(&ov08d10->mutex);
1237 
1238     return 0;
1239 }
1240 
1241 static int ov08d10_enum_mbus_code(struct v4l2_subdev *sd,
1242                   struct v4l2_subdev_state *sd_state,
1243                   struct v4l2_subdev_mbus_code_enum *code)
1244 {
1245     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1246 
1247     if (code->index > 0)
1248         return -EINVAL;
1249 
1250     mutex_lock(&ov08d10->mutex);
1251     code->code = ov08d10_get_format_code(ov08d10);
1252     mutex_unlock(&ov08d10->mutex);
1253 
1254     return 0;
1255 }
1256 
1257 static int ov08d10_enum_frame_size(struct v4l2_subdev *sd,
1258                    struct v4l2_subdev_state *sd_state,
1259                    struct v4l2_subdev_frame_size_enum *fse)
1260 {
1261     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1262 
1263     if (fse->index >= ov08d10->modes_size)
1264         return -EINVAL;
1265 
1266     mutex_lock(&ov08d10->mutex);
1267     if (fse->code != ov08d10_get_format_code(ov08d10)) {
1268         mutex_unlock(&ov08d10->mutex);
1269         return -EINVAL;
1270     }
1271     mutex_unlock(&ov08d10->mutex);
1272 
1273     fse->min_width = ov08d10->priv_lane->sp_modes[fse->index].width;
1274     fse->max_width = fse->min_width;
1275     fse->min_height = ov08d10->priv_lane->sp_modes[fse->index].height;
1276     fse->max_height = fse->min_height;
1277 
1278     return 0;
1279 }
1280 
1281 static int ov08d10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1282 {
1283     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1284 
1285     mutex_lock(&ov08d10->mutex);
1286     ov08d10_update_pad_format(ov08d10, &ov08d10->priv_lane->sp_modes[0],
1287                   v4l2_subdev_get_try_format(sd, fh->state, 0));
1288     mutex_unlock(&ov08d10->mutex);
1289 
1290     return 0;
1291 }
1292 
1293 static const struct v4l2_subdev_video_ops ov08d10_video_ops = {
1294     .s_stream = ov08d10_set_stream,
1295 };
1296 
1297 static const struct v4l2_subdev_pad_ops ov08d10_pad_ops = {
1298     .set_fmt = ov08d10_set_format,
1299     .get_fmt = ov08d10_get_format,
1300     .enum_mbus_code = ov08d10_enum_mbus_code,
1301     .enum_frame_size = ov08d10_enum_frame_size,
1302 };
1303 
1304 static const struct v4l2_subdev_ops ov08d10_subdev_ops = {
1305     .video = &ov08d10_video_ops,
1306     .pad = &ov08d10_pad_ops,
1307 };
1308 
1309 static const struct v4l2_subdev_internal_ops ov08d10_internal_ops = {
1310     .open = ov08d10_open,
1311 };
1312 
1313 static int ov08d10_identify_module(struct ov08d10 *ov08d10)
1314 {
1315     struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
1316     u32 val;
1317     u16 chip_id;
1318     int ret;
1319 
1320     /* System control registers */
1321     ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
1322     if (ret < 0)
1323         return ret;
1324 
1325     /* Validate the chip ID */
1326     ret = i2c_smbus_read_byte_data(client, OV08D10_REG_CHIP_ID_0);
1327     if (ret < 0)
1328         return ret;
1329 
1330     val = ret << 8;
1331 
1332     ret = i2c_smbus_read_byte_data(client, OV08D10_REG_CHIP_ID_1);
1333     if (ret < 0)
1334         return ret;
1335 
1336     chip_id = val | ret;
1337 
1338     if ((chip_id & OV08D10_ID_MASK) != OV08D10_CHIP_ID) {
1339         dev_err(&client->dev, "unexpected sensor id(0x%04x)\n",
1340             chip_id);
1341         return -EINVAL;
1342     }
1343 
1344     return 0;
1345 }
1346 
1347 static int ov08d10_get_hwcfg(struct ov08d10 *ov08d10, struct device *dev)
1348 {
1349     struct fwnode_handle *ep;
1350     struct fwnode_handle *fwnode = dev_fwnode(dev);
1351     struct v4l2_fwnode_endpoint bus_cfg = {
1352         .bus_type = V4L2_MBUS_CSI2_DPHY
1353     };
1354     u32 xvclk_rate;
1355     unsigned int i, j;
1356     int ret;
1357 
1358     if (!fwnode)
1359         return -ENXIO;
1360 
1361     ret = fwnode_property_read_u32(fwnode, "clock-frequency", &xvclk_rate);
1362     if (ret)
1363         return ret;
1364 
1365     if (xvclk_rate != OV08D10_XVCLK_19_2)
1366         dev_warn(dev, "external clock rate %u is unsupported",
1367              xvclk_rate);
1368 
1369     ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1370     if (!ep)
1371         return -ENXIO;
1372 
1373     ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1374     fwnode_handle_put(ep);
1375     if (ret)
1376         return ret;
1377 
1378     /* Get number of data lanes */
1379     if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
1380         dev_err(dev, "number of CSI2 data lanes %d is not supported",
1381             bus_cfg.bus.mipi_csi2.num_data_lanes);
1382         ret = -EINVAL;
1383         goto check_hwcfg_error;
1384     }
1385 
1386     dev_dbg(dev, "Using %u data lanes\n", ov08d10->cur_mode->data_lanes);
1387 
1388     ov08d10->priv_lane = &lane_cfg_2;
1389     ov08d10->modes_size = ov08d10_modes_num(ov08d10);
1390 
1391     if (!bus_cfg.nr_of_link_frequencies) {
1392         dev_err(dev, "no link frequencies defined");
1393         ret = -EINVAL;
1394         goto check_hwcfg_error;
1395     }
1396 
1397     for (i = 0; i < ARRAY_SIZE(ov08d10->priv_lane->link_freq_menu); i++) {
1398         for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
1399             if (ov08d10->priv_lane->link_freq_menu[i] ==
1400                 bus_cfg.link_frequencies[j])
1401                 break;
1402         }
1403 
1404         if (j == bus_cfg.nr_of_link_frequencies) {
1405             dev_err(dev, "no link frequency %lld supported",
1406                 ov08d10->priv_lane->link_freq_menu[i]);
1407             ret = -EINVAL;
1408             goto check_hwcfg_error;
1409         }
1410     }
1411 
1412 check_hwcfg_error:
1413     v4l2_fwnode_endpoint_free(&bus_cfg);
1414 
1415     return ret;
1416 }
1417 
1418 static int ov08d10_remove(struct i2c_client *client)
1419 {
1420     struct v4l2_subdev *sd = i2c_get_clientdata(client);
1421     struct ov08d10 *ov08d10 = to_ov08d10(sd);
1422 
1423     v4l2_async_unregister_subdev(sd);
1424     media_entity_cleanup(&sd->entity);
1425     v4l2_ctrl_handler_free(sd->ctrl_handler);
1426     pm_runtime_disable(&client->dev);
1427     mutex_destroy(&ov08d10->mutex);
1428 
1429     return 0;
1430 }
1431 
1432 static int ov08d10_probe(struct i2c_client *client)
1433 {
1434     struct ov08d10 *ov08d10;
1435     int ret;
1436 
1437     ov08d10 = devm_kzalloc(&client->dev, sizeof(*ov08d10), GFP_KERNEL);
1438     if (!ov08d10)
1439         return -ENOMEM;
1440 
1441     ret = ov08d10_get_hwcfg(ov08d10, &client->dev);
1442     if (ret) {
1443         dev_err(&client->dev, "failed to get HW configuration: %d",
1444             ret);
1445         return ret;
1446     }
1447 
1448     v4l2_i2c_subdev_init(&ov08d10->sd, client, &ov08d10_subdev_ops);
1449 
1450     ret = ov08d10_identify_module(ov08d10);
1451     if (ret) {
1452         dev_err(&client->dev, "failed to find sensor: %d", ret);
1453         return ret;
1454     }
1455 
1456     mutex_init(&ov08d10->mutex);
1457     ov08d10->cur_mode = &ov08d10->priv_lane->sp_modes[0];
1458     ret = ov08d10_init_controls(ov08d10);
1459     if (ret) {
1460         dev_err(&client->dev, "failed to init controls: %d", ret);
1461         goto probe_error_v4l2_ctrl_handler_free;
1462     }
1463 
1464     ov08d10->sd.internal_ops = &ov08d10_internal_ops;
1465     ov08d10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1466     ov08d10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1467     ov08d10->pad.flags = MEDIA_PAD_FL_SOURCE;
1468     ret = media_entity_pads_init(&ov08d10->sd.entity, 1, &ov08d10->pad);
1469     if (ret) {
1470         dev_err(&client->dev, "failed to init entity pads: %d", ret);
1471         goto probe_error_v4l2_ctrl_handler_free;
1472     }
1473 
1474     ret = v4l2_async_register_subdev_sensor(&ov08d10->sd);
1475     if (ret < 0) {
1476         dev_err(&client->dev, "failed to register V4L2 subdev: %d",
1477             ret);
1478         goto probe_error_media_entity_cleanup;
1479     }
1480 
1481     /*
1482      * Device is already turned on by i2c-core with ACPI domain PM.
1483      * Enable runtime PM and turn off the device.
1484      */
1485     pm_runtime_set_active(&client->dev);
1486     pm_runtime_enable(&client->dev);
1487     pm_runtime_idle(&client->dev);
1488 
1489     return 0;
1490 
1491 probe_error_media_entity_cleanup:
1492     media_entity_cleanup(&ov08d10->sd.entity);
1493 
1494 probe_error_v4l2_ctrl_handler_free:
1495     v4l2_ctrl_handler_free(ov08d10->sd.ctrl_handler);
1496     mutex_destroy(&ov08d10->mutex);
1497 
1498     return ret;
1499 }
1500 
1501 static const struct dev_pm_ops ov08d10_pm_ops = {
1502     SET_SYSTEM_SLEEP_PM_OPS(ov08d10_suspend, ov08d10_resume)
1503 };
1504 
1505 #ifdef CONFIG_ACPI
1506 static const struct acpi_device_id ov08d10_acpi_ids[] = {
1507     { "OVTI08D1" },
1508     { /* sentinel */ }
1509 };
1510 
1511 MODULE_DEVICE_TABLE(acpi, ov08d10_acpi_ids);
1512 #endif
1513 
1514 static struct i2c_driver ov08d10_i2c_driver = {
1515     .driver = {
1516         .name = "ov08d10",
1517         .pm = &ov08d10_pm_ops,
1518         .acpi_match_table = ACPI_PTR(ov08d10_acpi_ids),
1519     },
1520     .probe_new = ov08d10_probe,
1521     .remove = ov08d10_remove,
1522 };
1523 
1524 module_i2c_driver(ov08d10_i2c_driver);
1525 
1526 MODULE_AUTHOR("Su, Jimmy <jimmy.su@intel.com>");
1527 MODULE_DESCRIPTION("OmniVision ov08d10 sensor driver");
1528 MODULE_LICENSE("GPL v2");