0001
0002
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
0033 #define OV08D10_REG_VTS_H 0x05
0034 #define OV08D10_REG_VTS_L 0x06
0035 #define OV08D10_VTS_MAX 0x7fff
0036
0037
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
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
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
0060 #define OV08D10_REG_TEST_PATTERN 0x12
0061 #define OV08D10_TEST_PATTERN_ENABLE 0x01
0062 #define OV08D10_TEST_PATTERN_DISABLE 0x00
0063
0064
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
0086 u32 width;
0087
0088
0089 u32 height;
0090
0091
0092 u32 hts;
0093
0094
0095 u32 vts_def;
0096
0097
0098 u32 vts_min;
0099
0100
0101 u32 link_freq_index;
0102
0103
0104 const struct ov08d10_reg_list reg_list;
0105
0106
0107 u8 data_lanes;
0108 };
0109
0110
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
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
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
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
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
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
0534 const struct ov08d10_mode *cur_mode;
0535
0536
0537 struct mutex mutex;
0538
0539
0540 bool streaming;
0541
0542
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
0687 ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0688 if (ret < 0)
0689 return ret;
0690
0691
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
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
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
0746 ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
0747 if (ret < 0)
0748 return ret;
0749
0750
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
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
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
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
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
0860 if (ctrl->id == V4L2_CID_VBLANK) {
0861
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
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
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
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
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
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
1321 ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
1322 if (ret < 0)
1323 return ret;
1324
1325
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
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
1483
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 { }
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");