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