1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2018 Intel Corporation 3 4 #include <asm/unaligned.h> 5 #include <linux/acpi.h> 6 #include <linux/i2c.h> 7 #include <linux/module.h> 8 #include <linux/pm_runtime.h> 9 #include <media/v4l2-ctrls.h> 10 #include <media/v4l2-device.h> 11 #include <media/v4l2-event.h> 12 #include <media/v4l2-fwnode.h> 13 14 #define IMX355_REG_MODE_SELECT 0x0100 15 #define IMX355_MODE_STANDBY 0x00 16 #define IMX355_MODE_STREAMING 0x01 17 18 /* Chip ID */ 19 #define IMX355_REG_CHIP_ID 0x0016 20 #define IMX355_CHIP_ID 0x0355 21 22 /* V_TIMING internal */ 23 #define IMX355_REG_FLL 0x0340 24 #define IMX355_FLL_MAX 0xffff 25 26 /* Exposure control */ 27 #define IMX355_REG_EXPOSURE 0x0202 28 #define IMX355_EXPOSURE_MIN 1 29 #define IMX355_EXPOSURE_STEP 1 30 #define IMX355_EXPOSURE_DEFAULT 0x0282 31 32 /* Analog gain control */ 33 #define IMX355_REG_ANALOG_GAIN 0x0204 34 #define IMX355_ANA_GAIN_MIN 0 35 #define IMX355_ANA_GAIN_MAX 960 36 #define IMX355_ANA_GAIN_STEP 1 37 #define IMX355_ANA_GAIN_DEFAULT 0 38 39 /* Digital gain control */ 40 #define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070 41 #define IMX355_REG_DIG_GAIN_GLOBAL 0x020e 42 #define IMX355_DGTL_GAIN_MIN 256 43 #define IMX355_DGTL_GAIN_MAX 4095 44 #define IMX355_DGTL_GAIN_STEP 1 45 #define IMX355_DGTL_GAIN_DEFAULT 256 46 47 /* Test Pattern Control */ 48 #define IMX355_REG_TEST_PATTERN 0x0600 49 #define IMX355_TEST_PATTERN_DISABLED 0 50 #define IMX355_TEST_PATTERN_SOLID_COLOR 1 51 #define IMX355_TEST_PATTERN_COLOR_BARS 2 52 #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3 53 #define IMX355_TEST_PATTERN_PN9 4 54 55 /* Flip Control */ 56 #define IMX355_REG_ORIENTATION 0x0101 57 58 /* default link frequency and external clock */ 59 #define IMX355_LINK_FREQ_DEFAULT 360000000 60 #define IMX355_EXT_CLK 19200000 61 #define IMX355_LINK_FREQ_INDEX 0 62 63 struct imx355_reg { 64 u16 address; 65 u8 val; 66 }; 67 68 struct imx355_reg_list { 69 u32 num_of_regs; 70 const struct imx355_reg *regs; 71 }; 72 73 /* Mode : resolution and related config&values */ 74 struct imx355_mode { 75 /* Frame width */ 76 u32 width; 77 /* Frame height */ 78 u32 height; 79 80 /* V-timing */ 81 u32 fll_def; 82 u32 fll_min; 83 84 /* H-timing */ 85 u32 llp; 86 87 /* index of link frequency */ 88 u32 link_freq_index; 89 90 /* Default register values */ 91 struct imx355_reg_list reg_list; 92 }; 93 94 struct imx355_hwcfg { 95 u32 ext_clk; /* sensor external clk */ 96 s64 *link_freqs; /* CSI-2 link frequencies */ 97 unsigned int nr_of_link_freqs; 98 }; 99 100 struct imx355 { 101 struct v4l2_subdev sd; 102 struct media_pad pad; 103 104 struct v4l2_ctrl_handler ctrl_handler; 105 /* V4L2 Controls */ 106 struct v4l2_ctrl *link_freq; 107 struct v4l2_ctrl *pixel_rate; 108 struct v4l2_ctrl *vblank; 109 struct v4l2_ctrl *hblank; 110 struct v4l2_ctrl *exposure; 111 struct v4l2_ctrl *vflip; 112 struct v4l2_ctrl *hflip; 113 114 /* Current mode */ 115 const struct imx355_mode *cur_mode; 116 117 struct imx355_hwcfg *hwcfg; 118 s64 link_def_freq; /* CSI-2 link default frequency */ 119 120 /* 121 * Mutex for serialized access: 122 * Protect sensor set pad format and start/stop streaming safely. 123 * Protect access to sensor v4l2 controls. 124 */ 125 struct mutex mutex; 126 127 /* Streaming on/off */ 128 bool streaming; 129 }; 130 131 static const struct imx355_reg imx355_global_regs[] = { 132 { 0x0136, 0x13 }, 133 { 0x0137, 0x33 }, 134 { 0x304e, 0x03 }, 135 { 0x4348, 0x16 }, 136 { 0x4350, 0x19 }, 137 { 0x4408, 0x0a }, 138 { 0x440c, 0x0b }, 139 { 0x4411, 0x5f }, 140 { 0x4412, 0x2c }, 141 { 0x4623, 0x00 }, 142 { 0x462c, 0x0f }, 143 { 0x462d, 0x00 }, 144 { 0x462e, 0x00 }, 145 { 0x4684, 0x54 }, 146 { 0x480a, 0x07 }, 147 { 0x4908, 0x07 }, 148 { 0x4909, 0x07 }, 149 { 0x490d, 0x0a }, 150 { 0x491e, 0x0f }, 151 { 0x4921, 0x06 }, 152 { 0x4923, 0x28 }, 153 { 0x4924, 0x28 }, 154 { 0x4925, 0x29 }, 155 { 0x4926, 0x29 }, 156 { 0x4927, 0x1f }, 157 { 0x4928, 0x20 }, 158 { 0x4929, 0x20 }, 159 { 0x492a, 0x20 }, 160 { 0x492c, 0x05 }, 161 { 0x492d, 0x06 }, 162 { 0x492e, 0x06 }, 163 { 0x492f, 0x06 }, 164 { 0x4930, 0x03 }, 165 { 0x4931, 0x04 }, 166 { 0x4932, 0x04 }, 167 { 0x4933, 0x05 }, 168 { 0x595e, 0x01 }, 169 { 0x5963, 0x01 }, 170 { 0x3030, 0x01 }, 171 { 0x3031, 0x01 }, 172 { 0x3045, 0x01 }, 173 { 0x4010, 0x00 }, 174 { 0x4011, 0x00 }, 175 { 0x4012, 0x00 }, 176 { 0x4013, 0x01 }, 177 { 0x68a8, 0xfe }, 178 { 0x68a9, 0xff }, 179 { 0x6888, 0x00 }, 180 { 0x6889, 0x00 }, 181 { 0x68b0, 0x00 }, 182 { 0x3058, 0x00 }, 183 { 0x305a, 0x00 }, 184 }; 185 186 static const struct imx355_reg_list imx355_global_setting = { 187 .num_of_regs = ARRAY_SIZE(imx355_global_regs), 188 .regs = imx355_global_regs, 189 }; 190 191 static const struct imx355_reg mode_3268x2448_regs[] = { 192 { 0x0112, 0x0a }, 193 { 0x0113, 0x0a }, 194 { 0x0114, 0x03 }, 195 { 0x0342, 0x0e }, 196 { 0x0343, 0x58 }, 197 { 0x0340, 0x0a }, 198 { 0x0341, 0x37 }, 199 { 0x0344, 0x00 }, 200 { 0x0345, 0x08 }, 201 { 0x0346, 0x00 }, 202 { 0x0347, 0x08 }, 203 { 0x0348, 0x0c }, 204 { 0x0349, 0xcb }, 205 { 0x034a, 0x09 }, 206 { 0x034b, 0x97 }, 207 { 0x0220, 0x00 }, 208 { 0x0222, 0x01 }, 209 { 0x0900, 0x00 }, 210 { 0x0901, 0x11 }, 211 { 0x0902, 0x00 }, 212 { 0x034c, 0x0c }, 213 { 0x034d, 0xc4 }, 214 { 0x034e, 0x09 }, 215 { 0x034f, 0x90 }, 216 { 0x0301, 0x05 }, 217 { 0x0303, 0x01 }, 218 { 0x0305, 0x02 }, 219 { 0x0306, 0x00 }, 220 { 0x0307, 0x78 }, 221 { 0x030b, 0x01 }, 222 { 0x030d, 0x02 }, 223 { 0x030e, 0x00 }, 224 { 0x030f, 0x4b }, 225 { 0x0310, 0x00 }, 226 { 0x0700, 0x00 }, 227 { 0x0701, 0x10 }, 228 { 0x0820, 0x0b }, 229 { 0x0821, 0x40 }, 230 { 0x3088, 0x04 }, 231 { 0x6813, 0x02 }, 232 { 0x6835, 0x07 }, 233 { 0x6836, 0x01 }, 234 { 0x6837, 0x04 }, 235 { 0x684d, 0x07 }, 236 { 0x684e, 0x01 }, 237 { 0x684f, 0x04 }, 238 }; 239 240 static const struct imx355_reg mode_3264x2448_regs[] = { 241 { 0x0112, 0x0a }, 242 { 0x0113, 0x0a }, 243 { 0x0114, 0x03 }, 244 { 0x0342, 0x0e }, 245 { 0x0343, 0x58 }, 246 { 0x0340, 0x0a }, 247 { 0x0341, 0x37 }, 248 { 0x0344, 0x00 }, 249 { 0x0345, 0x08 }, 250 { 0x0346, 0x00 }, 251 { 0x0347, 0x08 }, 252 { 0x0348, 0x0c }, 253 { 0x0349, 0xc7 }, 254 { 0x034a, 0x09 }, 255 { 0x034b, 0x97 }, 256 { 0x0220, 0x00 }, 257 { 0x0222, 0x01 }, 258 { 0x0900, 0x00 }, 259 { 0x0901, 0x11 }, 260 { 0x0902, 0x00 }, 261 { 0x034c, 0x0c }, 262 { 0x034d, 0xc0 }, 263 { 0x034e, 0x09 }, 264 { 0x034f, 0x90 }, 265 { 0x0301, 0x05 }, 266 { 0x0303, 0x01 }, 267 { 0x0305, 0x02 }, 268 { 0x0306, 0x00 }, 269 { 0x0307, 0x78 }, 270 { 0x030b, 0x01 }, 271 { 0x030d, 0x02 }, 272 { 0x030e, 0x00 }, 273 { 0x030f, 0x4b }, 274 { 0x0310, 0x00 }, 275 { 0x0700, 0x00 }, 276 { 0x0701, 0x10 }, 277 { 0x0820, 0x0b }, 278 { 0x0821, 0x40 }, 279 { 0x3088, 0x04 }, 280 { 0x6813, 0x02 }, 281 { 0x6835, 0x07 }, 282 { 0x6836, 0x01 }, 283 { 0x6837, 0x04 }, 284 { 0x684d, 0x07 }, 285 { 0x684e, 0x01 }, 286 { 0x684f, 0x04 }, 287 }; 288 289 static const struct imx355_reg mode_3280x2464_regs[] = { 290 { 0x0112, 0x0a }, 291 { 0x0113, 0x0a }, 292 { 0x0114, 0x03 }, 293 { 0x0342, 0x0e }, 294 { 0x0343, 0x58 }, 295 { 0x0340, 0x0a }, 296 { 0x0341, 0x37 }, 297 { 0x0344, 0x00 }, 298 { 0x0345, 0x00 }, 299 { 0x0346, 0x00 }, 300 { 0x0347, 0x00 }, 301 { 0x0348, 0x0c }, 302 { 0x0349, 0xcf }, 303 { 0x034a, 0x09 }, 304 { 0x034b, 0x9f }, 305 { 0x0220, 0x00 }, 306 { 0x0222, 0x01 }, 307 { 0x0900, 0x00 }, 308 { 0x0901, 0x11 }, 309 { 0x0902, 0x00 }, 310 { 0x034c, 0x0c }, 311 { 0x034d, 0xd0 }, 312 { 0x034e, 0x09 }, 313 { 0x034f, 0xa0 }, 314 { 0x0301, 0x05 }, 315 { 0x0303, 0x01 }, 316 { 0x0305, 0x02 }, 317 { 0x0306, 0x00 }, 318 { 0x0307, 0x78 }, 319 { 0x030b, 0x01 }, 320 { 0x030d, 0x02 }, 321 { 0x030e, 0x00 }, 322 { 0x030f, 0x4b }, 323 { 0x0310, 0x00 }, 324 { 0x0700, 0x00 }, 325 { 0x0701, 0x10 }, 326 { 0x0820, 0x0b }, 327 { 0x0821, 0x40 }, 328 { 0x3088, 0x04 }, 329 { 0x6813, 0x02 }, 330 { 0x6835, 0x07 }, 331 { 0x6836, 0x01 }, 332 { 0x6837, 0x04 }, 333 { 0x684d, 0x07 }, 334 { 0x684e, 0x01 }, 335 { 0x684f, 0x04 }, 336 }; 337 338 static const struct imx355_reg mode_1940x1096_regs[] = { 339 { 0x0112, 0x0a }, 340 { 0x0113, 0x0a }, 341 { 0x0114, 0x03 }, 342 { 0x0342, 0x0e }, 343 { 0x0343, 0x58 }, 344 { 0x0340, 0x05 }, 345 { 0x0341, 0x1a }, 346 { 0x0344, 0x02 }, 347 { 0x0345, 0xa0 }, 348 { 0x0346, 0x02 }, 349 { 0x0347, 0xac }, 350 { 0x0348, 0x0a }, 351 { 0x0349, 0x33 }, 352 { 0x034a, 0x06 }, 353 { 0x034b, 0xf3 }, 354 { 0x0220, 0x00 }, 355 { 0x0222, 0x01 }, 356 { 0x0900, 0x00 }, 357 { 0x0901, 0x11 }, 358 { 0x0902, 0x00 }, 359 { 0x034c, 0x07 }, 360 { 0x034d, 0x94 }, 361 { 0x034e, 0x04 }, 362 { 0x034f, 0x48 }, 363 { 0x0301, 0x05 }, 364 { 0x0303, 0x01 }, 365 { 0x0305, 0x02 }, 366 { 0x0306, 0x00 }, 367 { 0x0307, 0x78 }, 368 { 0x030b, 0x01 }, 369 { 0x030d, 0x02 }, 370 { 0x030e, 0x00 }, 371 { 0x030f, 0x4b }, 372 { 0x0310, 0x00 }, 373 { 0x0700, 0x00 }, 374 { 0x0701, 0x10 }, 375 { 0x0820, 0x0b }, 376 { 0x0821, 0x40 }, 377 { 0x3088, 0x04 }, 378 { 0x6813, 0x02 }, 379 { 0x6835, 0x07 }, 380 { 0x6836, 0x01 }, 381 { 0x6837, 0x04 }, 382 { 0x684d, 0x07 }, 383 { 0x684e, 0x01 }, 384 { 0x684f, 0x04 }, 385 }; 386 387 static const struct imx355_reg mode_1936x1096_regs[] = { 388 { 0x0112, 0x0a }, 389 { 0x0113, 0x0a }, 390 { 0x0114, 0x03 }, 391 { 0x0342, 0x0e }, 392 { 0x0343, 0x58 }, 393 { 0x0340, 0x05 }, 394 { 0x0341, 0x1a }, 395 { 0x0344, 0x02 }, 396 { 0x0345, 0xa0 }, 397 { 0x0346, 0x02 }, 398 { 0x0347, 0xac }, 399 { 0x0348, 0x0a }, 400 { 0x0349, 0x2f }, 401 { 0x034a, 0x06 }, 402 { 0x034b, 0xf3 }, 403 { 0x0220, 0x00 }, 404 { 0x0222, 0x01 }, 405 { 0x0900, 0x00 }, 406 { 0x0901, 0x11 }, 407 { 0x0902, 0x00 }, 408 { 0x034c, 0x07 }, 409 { 0x034d, 0x90 }, 410 { 0x034e, 0x04 }, 411 { 0x034f, 0x48 }, 412 { 0x0301, 0x05 }, 413 { 0x0303, 0x01 }, 414 { 0x0305, 0x02 }, 415 { 0x0306, 0x00 }, 416 { 0x0307, 0x78 }, 417 { 0x030b, 0x01 }, 418 { 0x030d, 0x02 }, 419 { 0x030e, 0x00 }, 420 { 0x030f, 0x4b }, 421 { 0x0310, 0x00 }, 422 { 0x0700, 0x00 }, 423 { 0x0701, 0x10 }, 424 { 0x0820, 0x0b }, 425 { 0x0821, 0x40 }, 426 { 0x3088, 0x04 }, 427 { 0x6813, 0x02 }, 428 { 0x6835, 0x07 }, 429 { 0x6836, 0x01 }, 430 { 0x6837, 0x04 }, 431 { 0x684d, 0x07 }, 432 { 0x684e, 0x01 }, 433 { 0x684f, 0x04 }, 434 }; 435 436 static const struct imx355_reg mode_1924x1080_regs[] = { 437 { 0x0112, 0x0a }, 438 { 0x0113, 0x0a }, 439 { 0x0114, 0x03 }, 440 { 0x0342, 0x0e }, 441 { 0x0343, 0x58 }, 442 { 0x0340, 0x05 }, 443 { 0x0341, 0x1a }, 444 { 0x0344, 0x02 }, 445 { 0x0345, 0xa8 }, 446 { 0x0346, 0x02 }, 447 { 0x0347, 0xb4 }, 448 { 0x0348, 0x0a }, 449 { 0x0349, 0x2b }, 450 { 0x034a, 0x06 }, 451 { 0x034b, 0xeb }, 452 { 0x0220, 0x00 }, 453 { 0x0222, 0x01 }, 454 { 0x0900, 0x00 }, 455 { 0x0901, 0x11 }, 456 { 0x0902, 0x00 }, 457 { 0x034c, 0x07 }, 458 { 0x034d, 0x84 }, 459 { 0x034e, 0x04 }, 460 { 0x034f, 0x38 }, 461 { 0x0301, 0x05 }, 462 { 0x0303, 0x01 }, 463 { 0x0305, 0x02 }, 464 { 0x0306, 0x00 }, 465 { 0x0307, 0x78 }, 466 { 0x030b, 0x01 }, 467 { 0x030d, 0x02 }, 468 { 0x030e, 0x00 }, 469 { 0x030f, 0x4b }, 470 { 0x0310, 0x00 }, 471 { 0x0700, 0x00 }, 472 { 0x0701, 0x10 }, 473 { 0x0820, 0x0b }, 474 { 0x0821, 0x40 }, 475 { 0x3088, 0x04 }, 476 { 0x6813, 0x02 }, 477 { 0x6835, 0x07 }, 478 { 0x6836, 0x01 }, 479 { 0x6837, 0x04 }, 480 { 0x684d, 0x07 }, 481 { 0x684e, 0x01 }, 482 { 0x684f, 0x04 }, 483 }; 484 485 static const struct imx355_reg mode_1920x1080_regs[] = { 486 { 0x0112, 0x0a }, 487 { 0x0113, 0x0a }, 488 { 0x0114, 0x03 }, 489 { 0x0342, 0x0e }, 490 { 0x0343, 0x58 }, 491 { 0x0340, 0x05 }, 492 { 0x0341, 0x1a }, 493 { 0x0344, 0x02 }, 494 { 0x0345, 0xa8 }, 495 { 0x0346, 0x02 }, 496 { 0x0347, 0xb4 }, 497 { 0x0348, 0x0a }, 498 { 0x0349, 0x27 }, 499 { 0x034a, 0x06 }, 500 { 0x034b, 0xeb }, 501 { 0x0220, 0x00 }, 502 { 0x0222, 0x01 }, 503 { 0x0900, 0x00 }, 504 { 0x0901, 0x11 }, 505 { 0x0902, 0x00 }, 506 { 0x034c, 0x07 }, 507 { 0x034d, 0x80 }, 508 { 0x034e, 0x04 }, 509 { 0x034f, 0x38 }, 510 { 0x0301, 0x05 }, 511 { 0x0303, 0x01 }, 512 { 0x0305, 0x02 }, 513 { 0x0306, 0x00 }, 514 { 0x0307, 0x78 }, 515 { 0x030b, 0x01 }, 516 { 0x030d, 0x02 }, 517 { 0x030e, 0x00 }, 518 { 0x030f, 0x4b }, 519 { 0x0310, 0x00 }, 520 { 0x0700, 0x00 }, 521 { 0x0701, 0x10 }, 522 { 0x0820, 0x0b }, 523 { 0x0821, 0x40 }, 524 { 0x3088, 0x04 }, 525 { 0x6813, 0x02 }, 526 { 0x6835, 0x07 }, 527 { 0x6836, 0x01 }, 528 { 0x6837, 0x04 }, 529 { 0x684d, 0x07 }, 530 { 0x684e, 0x01 }, 531 { 0x684f, 0x04 }, 532 }; 533 534 static const struct imx355_reg mode_1640x1232_regs[] = { 535 { 0x0112, 0x0a }, 536 { 0x0113, 0x0a }, 537 { 0x0114, 0x03 }, 538 { 0x0342, 0x07 }, 539 { 0x0343, 0x2c }, 540 { 0x0340, 0x05 }, 541 { 0x0341, 0x1a }, 542 { 0x0344, 0x00 }, 543 { 0x0345, 0x00 }, 544 { 0x0346, 0x00 }, 545 { 0x0347, 0x00 }, 546 { 0x0348, 0x0c }, 547 { 0x0349, 0xcf }, 548 { 0x034a, 0x09 }, 549 { 0x034b, 0x9f }, 550 { 0x0220, 0x00 }, 551 { 0x0222, 0x01 }, 552 { 0x0900, 0x01 }, 553 { 0x0901, 0x22 }, 554 { 0x0902, 0x00 }, 555 { 0x034c, 0x06 }, 556 { 0x034d, 0x68 }, 557 { 0x034e, 0x04 }, 558 { 0x034f, 0xd0 }, 559 { 0x0301, 0x05 }, 560 { 0x0303, 0x01 }, 561 { 0x0305, 0x02 }, 562 { 0x0306, 0x00 }, 563 { 0x0307, 0x78 }, 564 { 0x030b, 0x01 }, 565 { 0x030d, 0x02 }, 566 { 0x030e, 0x00 }, 567 { 0x030f, 0x4b }, 568 { 0x0310, 0x00 }, 569 { 0x0700, 0x00 }, 570 { 0x0701, 0x10 }, 571 { 0x0820, 0x0b }, 572 { 0x0821, 0x40 }, 573 { 0x3088, 0x04 }, 574 { 0x6813, 0x02 }, 575 { 0x6835, 0x07 }, 576 { 0x6836, 0x01 }, 577 { 0x6837, 0x04 }, 578 { 0x684d, 0x07 }, 579 { 0x684e, 0x01 }, 580 { 0x684f, 0x04 }, 581 }; 582 583 static const struct imx355_reg mode_1640x922_regs[] = { 584 { 0x0112, 0x0a }, 585 { 0x0113, 0x0a }, 586 { 0x0114, 0x03 }, 587 { 0x0342, 0x07 }, 588 { 0x0343, 0x2c }, 589 { 0x0340, 0x05 }, 590 { 0x0341, 0x1a }, 591 { 0x0344, 0x00 }, 592 { 0x0345, 0x00 }, 593 { 0x0346, 0x01 }, 594 { 0x0347, 0x30 }, 595 { 0x0348, 0x0c }, 596 { 0x0349, 0xcf }, 597 { 0x034a, 0x08 }, 598 { 0x034b, 0x63 }, 599 { 0x0220, 0x00 }, 600 { 0x0222, 0x01 }, 601 { 0x0900, 0x01 }, 602 { 0x0901, 0x22 }, 603 { 0x0902, 0x00 }, 604 { 0x034c, 0x06 }, 605 { 0x034d, 0x68 }, 606 { 0x034e, 0x03 }, 607 { 0x034f, 0x9a }, 608 { 0x0301, 0x05 }, 609 { 0x0303, 0x01 }, 610 { 0x0305, 0x02 }, 611 { 0x0306, 0x00 }, 612 { 0x0307, 0x78 }, 613 { 0x030b, 0x01 }, 614 { 0x030d, 0x02 }, 615 { 0x030e, 0x00 }, 616 { 0x030f, 0x4b }, 617 { 0x0310, 0x00 }, 618 { 0x0700, 0x00 }, 619 { 0x0701, 0x10 }, 620 { 0x0820, 0x0b }, 621 { 0x0821, 0x40 }, 622 { 0x3088, 0x04 }, 623 { 0x6813, 0x02 }, 624 { 0x6835, 0x07 }, 625 { 0x6836, 0x01 }, 626 { 0x6837, 0x04 }, 627 { 0x684d, 0x07 }, 628 { 0x684e, 0x01 }, 629 { 0x684f, 0x04 }, 630 }; 631 632 static const struct imx355_reg mode_1300x736_regs[] = { 633 { 0x0112, 0x0a }, 634 { 0x0113, 0x0a }, 635 { 0x0114, 0x03 }, 636 { 0x0342, 0x07 }, 637 { 0x0343, 0x2c }, 638 { 0x0340, 0x05 }, 639 { 0x0341, 0x1a }, 640 { 0x0344, 0x01 }, 641 { 0x0345, 0x58 }, 642 { 0x0346, 0x01 }, 643 { 0x0347, 0xf0 }, 644 { 0x0348, 0x0b }, 645 { 0x0349, 0x7f }, 646 { 0x034a, 0x07 }, 647 { 0x034b, 0xaf }, 648 { 0x0220, 0x00 }, 649 { 0x0222, 0x01 }, 650 { 0x0900, 0x01 }, 651 { 0x0901, 0x22 }, 652 { 0x0902, 0x00 }, 653 { 0x034c, 0x05 }, 654 { 0x034d, 0x14 }, 655 { 0x034e, 0x02 }, 656 { 0x034f, 0xe0 }, 657 { 0x0301, 0x05 }, 658 { 0x0303, 0x01 }, 659 { 0x0305, 0x02 }, 660 { 0x0306, 0x00 }, 661 { 0x0307, 0x78 }, 662 { 0x030b, 0x01 }, 663 { 0x030d, 0x02 }, 664 { 0x030e, 0x00 }, 665 { 0x030f, 0x4b }, 666 { 0x0310, 0x00 }, 667 { 0x0700, 0x00 }, 668 { 0x0701, 0x10 }, 669 { 0x0820, 0x0b }, 670 { 0x0821, 0x40 }, 671 { 0x3088, 0x04 }, 672 { 0x6813, 0x02 }, 673 { 0x6835, 0x07 }, 674 { 0x6836, 0x01 }, 675 { 0x6837, 0x04 }, 676 { 0x684d, 0x07 }, 677 { 0x684e, 0x01 }, 678 { 0x684f, 0x04 }, 679 }; 680 681 static const struct imx355_reg mode_1296x736_regs[] = { 682 { 0x0112, 0x0a }, 683 { 0x0113, 0x0a }, 684 { 0x0114, 0x03 }, 685 { 0x0342, 0x07 }, 686 { 0x0343, 0x2c }, 687 { 0x0340, 0x05 }, 688 { 0x0341, 0x1a }, 689 { 0x0344, 0x01 }, 690 { 0x0345, 0x58 }, 691 { 0x0346, 0x01 }, 692 { 0x0347, 0xf0 }, 693 { 0x0348, 0x0b }, 694 { 0x0349, 0x77 }, 695 { 0x034a, 0x07 }, 696 { 0x034b, 0xaf }, 697 { 0x0220, 0x00 }, 698 { 0x0222, 0x01 }, 699 { 0x0900, 0x01 }, 700 { 0x0901, 0x22 }, 701 { 0x0902, 0x00 }, 702 { 0x034c, 0x05 }, 703 { 0x034d, 0x10 }, 704 { 0x034e, 0x02 }, 705 { 0x034f, 0xe0 }, 706 { 0x0301, 0x05 }, 707 { 0x0303, 0x01 }, 708 { 0x0305, 0x02 }, 709 { 0x0306, 0x00 }, 710 { 0x0307, 0x78 }, 711 { 0x030b, 0x01 }, 712 { 0x030d, 0x02 }, 713 { 0x030e, 0x00 }, 714 { 0x030f, 0x4b }, 715 { 0x0310, 0x00 }, 716 { 0x0700, 0x00 }, 717 { 0x0701, 0x10 }, 718 { 0x0820, 0x0b }, 719 { 0x0821, 0x40 }, 720 { 0x3088, 0x04 }, 721 { 0x6813, 0x02 }, 722 { 0x6835, 0x07 }, 723 { 0x6836, 0x01 }, 724 { 0x6837, 0x04 }, 725 { 0x684d, 0x07 }, 726 { 0x684e, 0x01 }, 727 { 0x684f, 0x04 }, 728 }; 729 730 static const struct imx355_reg mode_1284x720_regs[] = { 731 { 0x0112, 0x0a }, 732 { 0x0113, 0x0a }, 733 { 0x0114, 0x03 }, 734 { 0x0342, 0x07 }, 735 { 0x0343, 0x2c }, 736 { 0x0340, 0x05 }, 737 { 0x0341, 0x1a }, 738 { 0x0344, 0x01 }, 739 { 0x0345, 0x68 }, 740 { 0x0346, 0x02 }, 741 { 0x0347, 0x00 }, 742 { 0x0348, 0x0b }, 743 { 0x0349, 0x6f }, 744 { 0x034a, 0x07 }, 745 { 0x034b, 0x9f }, 746 { 0x0220, 0x00 }, 747 { 0x0222, 0x01 }, 748 { 0x0900, 0x01 }, 749 { 0x0901, 0x22 }, 750 { 0x0902, 0x00 }, 751 { 0x034c, 0x05 }, 752 { 0x034d, 0x04 }, 753 { 0x034e, 0x02 }, 754 { 0x034f, 0xd0 }, 755 { 0x0301, 0x05 }, 756 { 0x0303, 0x01 }, 757 { 0x0305, 0x02 }, 758 { 0x0306, 0x00 }, 759 { 0x0307, 0x78 }, 760 { 0x030b, 0x01 }, 761 { 0x030d, 0x02 }, 762 { 0x030e, 0x00 }, 763 { 0x030f, 0x4b }, 764 { 0x0310, 0x00 }, 765 { 0x0700, 0x00 }, 766 { 0x0701, 0x10 }, 767 { 0x0820, 0x0b }, 768 { 0x0821, 0x40 }, 769 { 0x3088, 0x04 }, 770 { 0x6813, 0x02 }, 771 { 0x6835, 0x07 }, 772 { 0x6836, 0x01 }, 773 { 0x6837, 0x04 }, 774 { 0x684d, 0x07 }, 775 { 0x684e, 0x01 }, 776 { 0x684f, 0x04 }, 777 }; 778 779 static const struct imx355_reg mode_1280x720_regs[] = { 780 { 0x0112, 0x0a }, 781 { 0x0113, 0x0a }, 782 { 0x0114, 0x03 }, 783 { 0x0342, 0x07 }, 784 { 0x0343, 0x2c }, 785 { 0x0340, 0x05 }, 786 { 0x0341, 0x1a }, 787 { 0x0344, 0x01 }, 788 { 0x0345, 0x68 }, 789 { 0x0346, 0x02 }, 790 { 0x0347, 0x00 }, 791 { 0x0348, 0x0b }, 792 { 0x0349, 0x67 }, 793 { 0x034a, 0x07 }, 794 { 0x034b, 0x9f }, 795 { 0x0220, 0x00 }, 796 { 0x0222, 0x01 }, 797 { 0x0900, 0x01 }, 798 { 0x0901, 0x22 }, 799 { 0x0902, 0x00 }, 800 { 0x034c, 0x05 }, 801 { 0x034d, 0x00 }, 802 { 0x034e, 0x02 }, 803 { 0x034f, 0xd0 }, 804 { 0x0301, 0x05 }, 805 { 0x0303, 0x01 }, 806 { 0x0305, 0x02 }, 807 { 0x0306, 0x00 }, 808 { 0x0307, 0x78 }, 809 { 0x030b, 0x01 }, 810 { 0x030d, 0x02 }, 811 { 0x030e, 0x00 }, 812 { 0x030f, 0x4b }, 813 { 0x0310, 0x00 }, 814 { 0x0700, 0x00 }, 815 { 0x0701, 0x10 }, 816 { 0x0820, 0x0b }, 817 { 0x0821, 0x40 }, 818 { 0x3088, 0x04 }, 819 { 0x6813, 0x02 }, 820 { 0x6835, 0x07 }, 821 { 0x6836, 0x01 }, 822 { 0x6837, 0x04 }, 823 { 0x684d, 0x07 }, 824 { 0x684e, 0x01 }, 825 { 0x684f, 0x04 }, 826 }; 827 828 static const struct imx355_reg mode_820x616_regs[] = { 829 { 0x0112, 0x0a }, 830 { 0x0113, 0x0a }, 831 { 0x0114, 0x03 }, 832 { 0x0342, 0x0e }, 833 { 0x0343, 0x58 }, 834 { 0x0340, 0x02 }, 835 { 0x0341, 0x8c }, 836 { 0x0344, 0x00 }, 837 { 0x0345, 0x00 }, 838 { 0x0346, 0x00 }, 839 { 0x0347, 0x00 }, 840 { 0x0348, 0x0c }, 841 { 0x0349, 0xcf }, 842 { 0x034a, 0x09 }, 843 { 0x034b, 0x9f }, 844 { 0x0220, 0x00 }, 845 { 0x0222, 0x01 }, 846 { 0x0900, 0x01 }, 847 { 0x0901, 0x44 }, 848 { 0x0902, 0x00 }, 849 { 0x034c, 0x03 }, 850 { 0x034d, 0x34 }, 851 { 0x034e, 0x02 }, 852 { 0x034f, 0x68 }, 853 { 0x0301, 0x05 }, 854 { 0x0303, 0x01 }, 855 { 0x0305, 0x02 }, 856 { 0x0306, 0x00 }, 857 { 0x0307, 0x78 }, 858 { 0x030b, 0x01 }, 859 { 0x030d, 0x02 }, 860 { 0x030e, 0x00 }, 861 { 0x030f, 0x4b }, 862 { 0x0310, 0x00 }, 863 { 0x0700, 0x02 }, 864 { 0x0701, 0x78 }, 865 { 0x0820, 0x0b }, 866 { 0x0821, 0x40 }, 867 { 0x3088, 0x04 }, 868 { 0x6813, 0x02 }, 869 { 0x6835, 0x07 }, 870 { 0x6836, 0x01 }, 871 { 0x6837, 0x04 }, 872 { 0x684d, 0x07 }, 873 { 0x684e, 0x01 }, 874 { 0x684f, 0x04 }, 875 }; 876 877 static const char * const imx355_test_pattern_menu[] = { 878 "Disabled", 879 "Solid Colour", 880 "Eight Vertical Colour Bars", 881 "Colour Bars With Fade to Grey", 882 "Pseudorandom Sequence (PN9)", 883 }; 884 885 /* supported link frequencies */ 886 static const s64 link_freq_menu_items[] = { 887 IMX355_LINK_FREQ_DEFAULT, 888 }; 889 890 /* Mode configs */ 891 static const struct imx355_mode supported_modes[] = { 892 { 893 .width = 3280, 894 .height = 2464, 895 .fll_def = 2615, 896 .fll_min = 2615, 897 .llp = 3672, 898 .link_freq_index = IMX355_LINK_FREQ_INDEX, 899 .reg_list = { 900 .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs), 901 .regs = mode_3280x2464_regs, 902 }, 903 }, 904 { 905 .width = 3268, 906 .height = 2448, 907 .fll_def = 2615, 908 .fll_min = 2615, 909 .llp = 3672, 910 .link_freq_index = IMX355_LINK_FREQ_INDEX, 911 .reg_list = { 912 .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs), 913 .regs = mode_3268x2448_regs, 914 }, 915 }, 916 { 917 .width = 3264, 918 .height = 2448, 919 .fll_def = 2615, 920 .fll_min = 2615, 921 .llp = 3672, 922 .link_freq_index = IMX355_LINK_FREQ_INDEX, 923 .reg_list = { 924 .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs), 925 .regs = mode_3264x2448_regs, 926 }, 927 }, 928 { 929 .width = 1940, 930 .height = 1096, 931 .fll_def = 1306, 932 .fll_min = 1306, 933 .llp = 3672, 934 .link_freq_index = IMX355_LINK_FREQ_INDEX, 935 .reg_list = { 936 .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs), 937 .regs = mode_1940x1096_regs, 938 }, 939 }, 940 { 941 .width = 1936, 942 .height = 1096, 943 .fll_def = 1306, 944 .fll_min = 1306, 945 .llp = 3672, 946 .link_freq_index = IMX355_LINK_FREQ_INDEX, 947 .reg_list = { 948 .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs), 949 .regs = mode_1936x1096_regs, 950 }, 951 }, 952 { 953 .width = 1924, 954 .height = 1080, 955 .fll_def = 1306, 956 .fll_min = 1306, 957 .llp = 3672, 958 .link_freq_index = IMX355_LINK_FREQ_INDEX, 959 .reg_list = { 960 .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs), 961 .regs = mode_1924x1080_regs, 962 }, 963 }, 964 { 965 .width = 1920, 966 .height = 1080, 967 .fll_def = 1306, 968 .fll_min = 1306, 969 .llp = 3672, 970 .link_freq_index = IMX355_LINK_FREQ_INDEX, 971 .reg_list = { 972 .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs), 973 .regs = mode_1920x1080_regs, 974 }, 975 }, 976 { 977 .width = 1640, 978 .height = 1232, 979 .fll_def = 1306, 980 .fll_min = 1306, 981 .llp = 1836, 982 .link_freq_index = IMX355_LINK_FREQ_INDEX, 983 .reg_list = { 984 .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs), 985 .regs = mode_1640x1232_regs, 986 }, 987 }, 988 { 989 .width = 1640, 990 .height = 922, 991 .fll_def = 1306, 992 .fll_min = 1306, 993 .llp = 1836, 994 .link_freq_index = IMX355_LINK_FREQ_INDEX, 995 .reg_list = { 996 .num_of_regs = ARRAY_SIZE(mode_1640x922_regs), 997 .regs = mode_1640x922_regs, 998 }, 999 }, 1000 { 1001 .width = 1300, 1002 .height = 736, 1003 .fll_def = 1306, 1004 .fll_min = 1306, 1005 .llp = 1836, 1006 .link_freq_index = IMX355_LINK_FREQ_INDEX, 1007 .reg_list = { 1008 .num_of_regs = ARRAY_SIZE(mode_1300x736_regs), 1009 .regs = mode_1300x736_regs, 1010 }, 1011 }, 1012 { 1013 .width = 1296, 1014 .height = 736, 1015 .fll_def = 1306, 1016 .fll_min = 1306, 1017 .llp = 1836, 1018 .link_freq_index = IMX355_LINK_FREQ_INDEX, 1019 .reg_list = { 1020 .num_of_regs = ARRAY_SIZE(mode_1296x736_regs), 1021 .regs = mode_1296x736_regs, 1022 }, 1023 }, 1024 { 1025 .width = 1284, 1026 .height = 720, 1027 .fll_def = 1306, 1028 .fll_min = 1306, 1029 .llp = 1836, 1030 .link_freq_index = IMX355_LINK_FREQ_INDEX, 1031 .reg_list = { 1032 .num_of_regs = ARRAY_SIZE(mode_1284x720_regs), 1033 .regs = mode_1284x720_regs, 1034 }, 1035 }, 1036 { 1037 .width = 1280, 1038 .height = 720, 1039 .fll_def = 1306, 1040 .fll_min = 1306, 1041 .llp = 1836, 1042 .link_freq_index = IMX355_LINK_FREQ_INDEX, 1043 .reg_list = { 1044 .num_of_regs = ARRAY_SIZE(mode_1280x720_regs), 1045 .regs = mode_1280x720_regs, 1046 }, 1047 }, 1048 { 1049 .width = 820, 1050 .height = 616, 1051 .fll_def = 652, 1052 .fll_min = 652, 1053 .llp = 3672, 1054 .link_freq_index = IMX355_LINK_FREQ_INDEX, 1055 .reg_list = { 1056 .num_of_regs = ARRAY_SIZE(mode_820x616_regs), 1057 .regs = mode_820x616_regs, 1058 }, 1059 }, 1060 }; 1061 1062 static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd) 1063 { 1064 return container_of(_sd, struct imx355, sd); 1065 } 1066 1067 /* Get bayer order based on flip setting. */ 1068 static u32 imx355_get_format_code(struct imx355 *imx355) 1069 { 1070 /* 1071 * Only one bayer order is supported. 1072 * It depends on the flip settings. 1073 */ 1074 u32 code; 1075 static const u32 codes[2][2] = { 1076 { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, }, 1077 { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, }, 1078 }; 1079 1080 lockdep_assert_held(&imx355->mutex); 1081 code = codes[imx355->vflip->val][imx355->hflip->val]; 1082 1083 return code; 1084 } 1085 1086 /* Read registers up to 4 at a time */ 1087 static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val) 1088 { 1089 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1090 struct i2c_msg msgs[2]; 1091 u8 addr_buf[2]; 1092 u8 data_buf[4] = { 0 }; 1093 int ret; 1094 1095 if (len > 4) 1096 return -EINVAL; 1097 1098 put_unaligned_be16(reg, addr_buf); 1099 /* Write register address */ 1100 msgs[0].addr = client->addr; 1101 msgs[0].flags = 0; 1102 msgs[0].len = ARRAY_SIZE(addr_buf); 1103 msgs[0].buf = addr_buf; 1104 1105 /* Read data from register */ 1106 msgs[1].addr = client->addr; 1107 msgs[1].flags = I2C_M_RD; 1108 msgs[1].len = len; 1109 msgs[1].buf = &data_buf[4 - len]; 1110 1111 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 1112 if (ret != ARRAY_SIZE(msgs)) 1113 return -EIO; 1114 1115 *val = get_unaligned_be32(data_buf); 1116 1117 return 0; 1118 } 1119 1120 /* Write registers up to 4 at a time */ 1121 static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val) 1122 { 1123 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1124 u8 buf[6]; 1125 1126 if (len > 4) 1127 return -EINVAL; 1128 1129 put_unaligned_be16(reg, buf); 1130 put_unaligned_be32(val << (8 * (4 - len)), buf + 2); 1131 if (i2c_master_send(client, buf, len + 2) != len + 2) 1132 return -EIO; 1133 1134 return 0; 1135 } 1136 1137 /* Write a list of registers */ 1138 static int imx355_write_regs(struct imx355 *imx355, 1139 const struct imx355_reg *regs, u32 len) 1140 { 1141 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1142 int ret; 1143 u32 i; 1144 1145 for (i = 0; i < len; i++) { 1146 ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val); 1147 if (ret) { 1148 dev_err_ratelimited(&client->dev, 1149 "write reg 0x%4.4x return err %d", 1150 regs[i].address, ret); 1151 1152 return ret; 1153 } 1154 } 1155 1156 return 0; 1157 } 1158 1159 /* Open sub-device */ 1160 static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 1161 { 1162 struct imx355 *imx355 = to_imx355(sd); 1163 struct v4l2_mbus_framefmt *try_fmt = 1164 v4l2_subdev_get_try_format(sd, fh->pad, 0); 1165 1166 mutex_lock(&imx355->mutex); 1167 1168 /* Initialize try_fmt */ 1169 try_fmt->width = imx355->cur_mode->width; 1170 try_fmt->height = imx355->cur_mode->height; 1171 try_fmt->code = imx355_get_format_code(imx355); 1172 try_fmt->field = V4L2_FIELD_NONE; 1173 1174 mutex_unlock(&imx355->mutex); 1175 1176 return 0; 1177 } 1178 1179 static int imx355_set_ctrl(struct v4l2_ctrl *ctrl) 1180 { 1181 struct imx355 *imx355 = container_of(ctrl->handler, 1182 struct imx355, ctrl_handler); 1183 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1184 s64 max; 1185 int ret; 1186 1187 /* Propagate change of current control to all related controls */ 1188 switch (ctrl->id) { 1189 case V4L2_CID_VBLANK: 1190 /* Update max exposure while meeting expected vblanking */ 1191 max = imx355->cur_mode->height + ctrl->val - 10; 1192 __v4l2_ctrl_modify_range(imx355->exposure, 1193 imx355->exposure->minimum, 1194 max, imx355->exposure->step, max); 1195 break; 1196 } 1197 1198 /* 1199 * Applying V4L2 control value only happens 1200 * when power is up for streaming 1201 */ 1202 if (!pm_runtime_get_if_in_use(&client->dev)) 1203 return 0; 1204 1205 switch (ctrl->id) { 1206 case V4L2_CID_ANALOGUE_GAIN: 1207 /* Analog gain = 1024/(1024 - ctrl->val) times */ 1208 ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2, 1209 ctrl->val); 1210 break; 1211 case V4L2_CID_DIGITAL_GAIN: 1212 ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2, 1213 ctrl->val); 1214 break; 1215 case V4L2_CID_EXPOSURE: 1216 ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2, 1217 ctrl->val); 1218 break; 1219 case V4L2_CID_VBLANK: 1220 /* Update FLL that meets expected vertical blanking */ 1221 ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2, 1222 imx355->cur_mode->height + ctrl->val); 1223 break; 1224 case V4L2_CID_TEST_PATTERN: 1225 ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN, 1226 2, ctrl->val); 1227 break; 1228 case V4L2_CID_HFLIP: 1229 case V4L2_CID_VFLIP: 1230 ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1, 1231 imx355->hflip->val | 1232 imx355->vflip->val << 1); 1233 break; 1234 default: 1235 ret = -EINVAL; 1236 dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled", 1237 ctrl->id, ctrl->val); 1238 break; 1239 } 1240 1241 pm_runtime_put(&client->dev); 1242 1243 return ret; 1244 } 1245 1246 static const struct v4l2_ctrl_ops imx355_ctrl_ops = { 1247 .s_ctrl = imx355_set_ctrl, 1248 }; 1249 1250 static int imx355_enum_mbus_code(struct v4l2_subdev *sd, 1251 struct v4l2_subdev_pad_config *cfg, 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_pad_config *cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 1334 struct v4l2_subdev_format *fmt) 1335 { 1336 struct imx355 *imx355 = to_imx355(sd); 1337 const struct imx355_mode *mode; 1338 struct v4l2_mbus_framefmt *framefmt; 1339 s32 vblank_def; 1340 s32 vblank_min; 1341 s64 h_blank; 1342 u64 pixel_rate; 1343 u32 height; 1344 1345 mutex_lock(&imx355->mutex); 1346 1347 /* 1348 * Only one bayer order is supported. 1349 * It depends on the flip settings. 1350 */ 1351 fmt->format.code = imx355_get_format_code(imx355); 1352 1353 mode = v4l2_find_nearest_size(supported_modes, 1354 ARRAY_SIZE(supported_modes), 1355 width, height, 1356 fmt->format.width, fmt->format.height); 1357 imx355_update_pad_format(imx355, mode, fmt); 1358 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1359 framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); 1360 *framefmt = fmt->format; 1361 } else { 1362 imx355->cur_mode = mode; 1363 pixel_rate = imx355->link_def_freq * 2 * 4; 1364 do_div(pixel_rate, 10); 1365 __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate); 1366 /* Update limits and set FPS to default */ 1367 height = imx355->cur_mode->height; 1368 vblank_def = imx355->cur_mode->fll_def - height; 1369 vblank_min = imx355->cur_mode->fll_min - height; 1370 height = IMX355_FLL_MAX - height; 1371 __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1, 1372 vblank_def); 1373 __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def); 1374 h_blank = mode->llp - imx355->cur_mode->width; 1375 /* 1376 * Currently hblank is not changeable. 1377 * So FPS control is done only by vblank. 1378 */ 1379 __v4l2_ctrl_modify_range(imx355->hblank, h_blank, 1380 h_blank, 1, h_blank); 1381 } 1382 1383 mutex_unlock(&imx355->mutex); 1384 1385 return 0; 1386 } 1387 1388 /* Start streaming */ 1389 static int imx355_start_streaming(struct imx355 *imx355) 1390 { 1391 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1392 const struct imx355_reg_list *reg_list; 1393 int ret; 1394 1395 /* Global Setting */ 1396 reg_list = &imx355_global_setting; 1397 ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs); 1398 if (ret) { 1399 dev_err(&client->dev, "failed to set global settings"); 1400 return ret; 1401 } 1402 1403 /* Apply default values of current mode */ 1404 reg_list = &imx355->cur_mode->reg_list; 1405 ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs); 1406 if (ret) { 1407 dev_err(&client->dev, "failed to set mode"); 1408 return ret; 1409 } 1410 1411 /* set digital gain control to all color mode */ 1412 ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1); 1413 if (ret) 1414 return ret; 1415 1416 /* Apply customized values from user */ 1417 ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler); 1418 if (ret) 1419 return ret; 1420 1421 return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT, 1422 1, IMX355_MODE_STREAMING); 1423 } 1424 1425 /* Stop streaming */ 1426 static int imx355_stop_streaming(struct imx355 *imx355) 1427 { 1428 return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT, 1429 1, IMX355_MODE_STANDBY); 1430 } 1431 1432 static int imx355_set_stream(struct v4l2_subdev *sd, int enable) 1433 { 1434 struct imx355 *imx355 = to_imx355(sd); 1435 struct i2c_client *client = v4l2_get_subdevdata(sd); 1436 int ret = 0; 1437 1438 mutex_lock(&imx355->mutex); 1439 if (imx355->streaming == enable) { 1440 mutex_unlock(&imx355->mutex); 1441 return 0; 1442 } 1443 1444 if (enable) { 1445 ret = pm_runtime_get_sync(&client->dev); 1446 if (ret < 0) { 1447 pm_runtime_put_noidle(&client->dev); 1448 goto err_unlock; 1449 } 1450 1451 /* 1452 * Apply default & customized values 1453 * and then start streaming. 1454 */ 1455 ret = imx355_start_streaming(imx355); 1456 if (ret) 1457 goto err_rpm_put; 1458 } else { 1459 imx355_stop_streaming(imx355); 1460 pm_runtime_put(&client->dev); 1461 } 1462 1463 imx355->streaming = enable; 1464 1465 /* vflip and hflip cannot change during streaming */ 1466 __v4l2_ctrl_grab(imx355->vflip, enable); 1467 __v4l2_ctrl_grab(imx355->hflip, enable); 1468 1469 mutex_unlock(&imx355->mutex); 1470 1471 return ret; 1472 1473 err_rpm_put: 1474 pm_runtime_put(&client->dev); 1475 err_unlock: 1476 mutex_unlock(&imx355->mutex); 1477 1478 return ret; 1479 } 1480 1481 static int __maybe_unused imx355_suspend(struct device *dev) 1482 { 1483 struct i2c_client *client = to_i2c_client(dev); 1484 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1485 struct imx355 *imx355 = to_imx355(sd); 1486 1487 if (imx355->streaming) 1488 imx355_stop_streaming(imx355); 1489 1490 return 0; 1491 } 1492 1493 static int __maybe_unused imx355_resume(struct device *dev) 1494 { 1495 struct i2c_client *client = to_i2c_client(dev); 1496 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1497 struct imx355 *imx355 = to_imx355(sd); 1498 int ret; 1499 1500 if (imx355->streaming) { 1501 ret = imx355_start_streaming(imx355); 1502 if (ret) 1503 goto error; 1504 } 1505 1506 return 0; 1507 1508 error: 1509 imx355_stop_streaming(imx355); 1510 imx355->streaming = 0; 1511 return ret; 1512 } 1513 1514 /* Verify chip ID */ 1515 static int imx355_identify_module(struct imx355 *imx355) 1516 { 1517 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1518 int ret; 1519 u32 val; 1520 1521 ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val); 1522 if (ret) 1523 return ret; 1524 1525 if (val != IMX355_CHIP_ID) { 1526 dev_err(&client->dev, "chip id mismatch: %x!=%x", 1527 IMX355_CHIP_ID, val); 1528 return -EIO; 1529 } 1530 return 0; 1531 } 1532 1533 static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = { 1534 .subscribe_event = v4l2_ctrl_subdev_subscribe_event, 1535 .unsubscribe_event = v4l2_event_subdev_unsubscribe, 1536 }; 1537 1538 static const struct v4l2_subdev_video_ops imx355_video_ops = { 1539 .s_stream = imx355_set_stream, 1540 }; 1541 1542 static const struct v4l2_subdev_pad_ops imx355_pad_ops = { 1543 .enum_mbus_code = imx355_enum_mbus_code, 1544 .get_fmt = imx355_get_pad_format, 1545 .set_fmt = imx355_set_pad_format, 1546 .enum_frame_size = imx355_enum_frame_size, 1547 }; 1548 1549 static const struct v4l2_subdev_ops imx355_subdev_ops = { 1550 .core = &imx355_subdev_core_ops, 1551 .video = &imx355_video_ops, 1552 .pad = &imx355_pad_ops, 1553 }; 1554 1555 static const struct media_entity_operations imx355_subdev_entity_ops = { 1556 .link_validate = v4l2_subdev_link_validate, 1557 }; 1558 1559 static const struct v4l2_subdev_internal_ops imx355_internal_ops = { 1560 .open = imx355_open, 1561 }; 1562 1563 /* Initialize control handlers */ 1564 static int imx355_init_controls(struct imx355 *imx355) 1565 { 1566 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1567 struct v4l2_ctrl_handler *ctrl_hdlr; 1568 s64 exposure_max; 1569 s64 vblank_def; 1570 s64 vblank_min; 1571 s64 hblank; 1572 u64 pixel_rate; 1573 const struct imx355_mode *mode; 1574 u32 max; 1575 int ret; 1576 1577 ctrl_hdlr = &imx355->ctrl_handler; 1578 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10); 1579 if (ret) 1580 return ret; 1581 1582 ctrl_hdlr->lock = &imx355->mutex; 1583 max = ARRAY_SIZE(link_freq_menu_items) - 1; 1584 imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops, 1585 V4L2_CID_LINK_FREQ, max, 0, 1586 link_freq_menu_items); 1587 if (imx355->link_freq) 1588 imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1589 1590 /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ 1591 pixel_rate = imx355->link_def_freq * 2 * 4; 1592 do_div(pixel_rate, 10); 1593 /* By default, PIXEL_RATE is read only */ 1594 imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1595 V4L2_CID_PIXEL_RATE, pixel_rate, 1596 pixel_rate, 1, pixel_rate); 1597 1598 /* Initialize vblank/hblank/exposure parameters based on current mode */ 1599 mode = imx355->cur_mode; 1600 vblank_def = mode->fll_def - mode->height; 1601 vblank_min = mode->fll_min - mode->height; 1602 imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1603 V4L2_CID_VBLANK, vblank_min, 1604 IMX355_FLL_MAX - mode->height, 1605 1, vblank_def); 1606 1607 hblank = mode->llp - mode->width; 1608 imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1609 V4L2_CID_HBLANK, hblank, hblank, 1610 1, hblank); 1611 if (imx355->hblank) 1612 imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1613 1614 /* fll >= exposure time + adjust parameter (default value is 10) */ 1615 exposure_max = mode->fll_def - 10; 1616 imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1617 V4L2_CID_EXPOSURE, 1618 IMX355_EXPOSURE_MIN, exposure_max, 1619 IMX355_EXPOSURE_STEP, 1620 IMX355_EXPOSURE_DEFAULT); 1621 1622 imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1623 V4L2_CID_HFLIP, 0, 1, 1, 0); 1624 imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, 1625 V4L2_CID_VFLIP, 0, 1, 1, 0); 1626 1627 v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 1628 IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX, 1629 IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT); 1630 1631 /* Digital gain */ 1632 v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN, 1633 IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX, 1634 IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT); 1635 1636 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops, 1637 V4L2_CID_TEST_PATTERN, 1638 ARRAY_SIZE(imx355_test_pattern_menu) - 1, 1639 0, 0, imx355_test_pattern_menu); 1640 if (ctrl_hdlr->error) { 1641 ret = ctrl_hdlr->error; 1642 dev_err(&client->dev, "control init failed: %d", ret); 1643 goto error; 1644 } 1645 1646 imx355->sd.ctrl_handler = ctrl_hdlr; 1647 1648 return 0; 1649 1650 error: 1651 v4l2_ctrl_handler_free(ctrl_hdlr); 1652 1653 return ret; 1654 } 1655 1656 static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev) 1657 { 1658 struct imx355_hwcfg *cfg; 1659 struct v4l2_fwnode_endpoint bus_cfg = { 1660 .bus_type = V4L2_MBUS_CSI2_DPHY 1661 }; 1662 struct fwnode_handle *ep; 1663 struct fwnode_handle *fwnode = dev_fwnode(dev); 1664 unsigned int i; 1665 int ret; 1666 1667 if (!fwnode) 1668 return NULL; 1669 1670 ep = fwnode_graph_get_next_endpoint(fwnode, NULL); 1671 if (!ep) 1672 return NULL; 1673 1674 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); 1675 if (ret) 1676 goto out_err; 1677 1678 cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL); 1679 if (!cfg) 1680 goto out_err; 1681 1682 ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", 1683 &cfg->ext_clk); 1684 if (ret) { 1685 dev_err(dev, "can't get clock frequency"); 1686 goto out_err; 1687 } 1688 1689 dev_dbg(dev, "ext clk: %d", cfg->ext_clk); 1690 if (cfg->ext_clk != IMX355_EXT_CLK) { 1691 dev_err(dev, "external clock %d is not supported", 1692 cfg->ext_clk); 1693 goto out_err; 1694 } 1695 1696 dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies); 1697 if (!bus_cfg.nr_of_link_frequencies) { 1698 dev_warn(dev, "no link frequencies defined"); 1699 goto out_err; 1700 } 1701 1702 cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies; 1703 cfg->link_freqs = devm_kcalloc(dev, 1704 bus_cfg.nr_of_link_frequencies + 1, 1705 sizeof(*cfg->link_freqs), GFP_KERNEL); 1706 if (!cfg->link_freqs) 1707 goto out_err; 1708 1709 for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { 1710 cfg->link_freqs[i] = bus_cfg.link_frequencies[i]; 1711 dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]); 1712 } 1713 1714 v4l2_fwnode_endpoint_free(&bus_cfg); 1715 fwnode_handle_put(ep); 1716 return cfg; 1717 1718 out_err: 1719 v4l2_fwnode_endpoint_free(&bus_cfg); 1720 fwnode_handle_put(ep); 1721 return NULL; 1722 } 1723 1724 static int imx355_probe(struct i2c_client *client) 1725 { 1726 struct imx355 *imx355; 1727 int ret; 1728 u32 i; 1729 1730 imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL); 1731 if (!imx355) 1732 return -ENOMEM; 1733 1734 mutex_init(&imx355->mutex); 1735 1736 /* Initialize subdev */ 1737 v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops); 1738 1739 /* Check module identity */ 1740 ret = imx355_identify_module(imx355); 1741 if (ret) { 1742 dev_err(&client->dev, "failed to find sensor: %d", ret); 1743 goto error_probe; 1744 } 1745 1746 imx355->hwcfg = imx355_get_hwcfg(&client->dev); 1747 if (!imx355->hwcfg) { 1748 dev_err(&client->dev, "failed to get hwcfg"); 1749 ret = -ENODEV; 1750 goto error_probe; 1751 } 1752 1753 imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX]; 1754 for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) { 1755 if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) { 1756 dev_dbg(&client->dev, "link freq index %d matched", i); 1757 break; 1758 } 1759 } 1760 1761 if (i == imx355->hwcfg->nr_of_link_freqs) { 1762 dev_err(&client->dev, "no link frequency supported"); 1763 ret = -EINVAL; 1764 goto error_probe; 1765 } 1766 1767 /* Set default mode to max resolution */ 1768 imx355->cur_mode = &supported_modes[0]; 1769 1770 ret = imx355_init_controls(imx355); 1771 if (ret) { 1772 dev_err(&client->dev, "failed to init controls: %d", ret); 1773 goto error_probe; 1774 } 1775 1776 /* Initialize subdev */ 1777 imx355->sd.internal_ops = &imx355_internal_ops; 1778 imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | 1779 V4L2_SUBDEV_FL_HAS_EVENTS; 1780 imx355->sd.entity.ops = &imx355_subdev_entity_ops; 1781 imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 1782 1783 /* Initialize source pad */ 1784 imx355->pad.flags = MEDIA_PAD_FL_SOURCE; 1785 ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad); 1786 if (ret) { 1787 dev_err(&client->dev, "failed to init entity pads: %d", ret); 1788 goto error_handler_free; 1789 } 1790 1791 ret = v4l2_async_register_subdev_sensor_common(&imx355->sd); 1792 if (ret < 0) 1793 goto error_media_entity; 1794 1795 /* 1796 * Device is already turned on by i2c-core with ACPI domain PM. 1797 * Enable runtime PM and turn off the device. 1798 */ 1799 pm_runtime_set_active(&client->dev); 1800 pm_runtime_enable(&client->dev); 1801 pm_runtime_idle(&client->dev); 1802 1803 return 0; 1804 1805 error_media_entity: 1806 media_entity_cleanup(&imx355->sd.entity); 1807 1808 error_handler_free: 1809 v4l2_ctrl_handler_free(imx355->sd.ctrl_handler); 1810 1811 error_probe: 1812 mutex_destroy(&imx355->mutex); 1813 1814 return ret; 1815 } 1816 1817 static int imx355_remove(struct i2c_client *client) 1818 { 1819 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1820 struct imx355 *imx355 = to_imx355(sd); 1821 1822 v4l2_async_unregister_subdev(sd); 1823 media_entity_cleanup(&sd->entity); 1824 v4l2_ctrl_handler_free(sd->ctrl_handler); 1825 1826 pm_runtime_disable(&client->dev); 1827 pm_runtime_set_suspended(&client->dev); 1828 1829 mutex_destroy(&imx355->mutex); 1830 1831 return 0; 1832 } 1833 1834 static const struct dev_pm_ops imx355_pm_ops = { 1835 SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume) 1836 }; 1837 1838 static const struct acpi_device_id imx355_acpi_ids[] = { 1839 { "SONY355A" }, 1840 { /* sentinel */ } 1841 }; 1842 MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids); 1843 1844 static struct i2c_driver imx355_i2c_driver = { 1845 .driver = { 1846 .name = "imx355", 1847 .pm = &imx355_pm_ops, 1848 .acpi_match_table = ACPI_PTR(imx355_acpi_ids), 1849 }, 1850 .probe_new = imx355_probe, 1851 .remove = imx355_remove, 1852 }; 1853 module_i2c_driver(imx355_i2c_driver); 1854 1855 MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>"); 1856 MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>"); 1857 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>"); 1858 MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>"); 1859 MODULE_DESCRIPTION("Sony imx355 sensor driver"); 1860 MODULE_LICENSE("GPL v2"); 1861