1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * V4L2 driver for Sony IMX678 4 * 5 * Diagonal 8.86 mm (Type 1/1.8) CMOS image sensor with 8.40 M effective pixels. 6 * 7 * Copyright (C) 2026 Ideas On Board Oy. 8 * 9 * Based on Sony IMX678 driver prepared by Will Whang & Soho Enterprise Ltd. 10 */ 11 #include <linux/clk.h> 12 #include <linux/delay.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/i2c.h> 15 #include <linux/media-bus-format.h> 16 #include <linux/module.h> 17 #include <linux/property.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/regulator/consumer.h> 20 #include <media/v4l2-cci.h> 21 #include <media/v4l2-ctrls.h> 22 #include <media/v4l2-device.h> 23 #include <media/v4l2-fwnode.h> 24 #include <media/v4l2-mediabus.h> 25 #include <media/v4l2-rect.h> 26 #include <media/v4l2-subdev.h> 27 28 /* Standby or streaming mode */ 29 #define IMX678_REG_MODE_SELECT CCI_REG8(0x3000) 30 #define IMX678_MODE_STANDBY 0x01 31 #define IMX678_MODE_STREAMING 0x00 32 #define IMX678_STREAM_DELAY_US 25000 33 #define IMX678_STREAM_DELAY_RANGE_US 1000 34 35 /* XVS/XHS sync control */ 36 #define IMX678_REG_XMSTA CCI_REG8(0x3002) 37 #define IMX678_REG_XXS_DRV CCI_REG8(0x30a6) 38 #define IMX678_REG_XXS_OUTSEL CCI_REG8(0x30a4) 39 40 /* Clk selection */ 41 #define IMX678_REG_INCK_SEL CCI_REG8(0x3014) 42 43 /* Link Speed */ 44 #define IMX678_REG_DATARATE_SEL CCI_REG8(0x3015) 45 46 /* Lane Count */ 47 #define IMX678_REG_LANEMODE CCI_REG8(0x3040) 48 49 /* 50 * The internal readout clock runs at 74.25 MHz. In one cycle the AD reads 8 51 * pixels, thus giving us a rate of 74.25 * 8 = 594 MPix/s 52 */ 53 #define IMX678_PIXEL_RATE 594000000 54 #define IMX678_PIX_PER_CLK 8 55 56 /* VMAX - Frame Length in Lines */ 57 #define IMX678_REG_VMAX CCI_REG24_LE(0x3028) 58 #define IMX678_VMAX_MAX 0xfffff 59 #define IMX678_VMAX_DEFAULT 2250 60 61 /* HMAX - Line Length in Cycles (8 Pixels) */ 62 #define IMX678_REG_HMAX CCI_REG16_LE(0x302c) 63 #define IMX678_HMAX_MAX 0xffff 64 65 /* SHR internal */ 66 #define IMX678_REG_SHR CCI_REG24_LE(0x3050) 67 #define IMX678_SHR_MIN 8 68 69 /* Exposure control */ 70 #define IMX678_EXPOSURE_MIN 2 71 #define IMX678_EXPOSURE_STEP 1 72 #define IMX678_EXPOSURE_DEFAULT 1000 73 74 /* 75 * Analogue gain control 76 * Range is from 0 to 100 (0dB - 30dB) with 0.3dB step size 77 * Values from 101 to 240 are valid but correspond to additional digital gain 78 * (0.3dB - 42dB) so don't expose it to userspace 79 */ 80 #define IMX678_REG_GAIN CCI_REG16_LE(0x3070) 81 #define IMX678_ANA_GAIN_MIN_NORMAL 0 82 #define IMX678_ANA_GAIN_MAX_NORMAL 100 83 #define IMX678_ANA_GAIN_STEP 1 84 #define IMX678_ANA_GAIN_DEFAULT 0 85 86 /* Crop */ 87 #define IMX678_REG_WINMODE CCI_REG8(0x3018) 88 #define IMX678_REG_PIX_HST CCI_REG16_LE(0x303c) 89 #define IMX678_REG_PIX_HWIDTH CCI_REG16_LE(0x303e) 90 #define IMX678_REG_PIX_VST CCI_REG16_LE(0x3044) 91 #define IMX678_REG_PIX_VWIDTH CCI_REG16_LE(0x3046) 92 93 /* Flip */ 94 #define IMX678_REG_WINMODEH CCI_REG8(0x3020) 95 #define IMX678_REG_WINMODEV CCI_REG8(0x3021) 96 97 /* Sensor Identification */ 98 #define IMX678_REG_MONOCHROME CCI_REG8(0x4d18) 99 #define IMX678_TYPE BIT(0) 100 #define IMX678_REG_MODULE_ID CCI_REG16_LE(0x4d1c) 101 #define IMX678_ID 0x02a6 102 #define IMX678_MODULE_ID_DELAY 80000 103 104 /* Common configuration registers */ 105 #define IMX678_REG_WDMODE CCI_REG8(0x301a) 106 #define IMX678_REG_ADDMODE CCI_REG8(0x301b) 107 #define IMX678_REG_THIN_V_EN CCI_REG8(0x301c) 108 #define IMX678_REG_VCMODE CCI_REG8(0x301e) 109 #define IMX678_REG_ADBIT CCI_REG8(0x3022) 110 #define IMX678_REG_MDBIT CCI_REG8(0x3023) 111 #define IMX678_REG_GAIN_PGC_FIDMD CCI_REG8(0x3400) 112 113 /* Test pattern generator */ 114 #define IMX678_REG_TPG_EN_DUOUT CCI_REG8(0x30e0) 115 #define IMX678_REG_TPG_PATSEL_DUOUT CCI_REG8(0x30e2) 116 #define IMX678_TPG_ALL_000 0 117 #define IMX678_TPG_ALL_FFF 1 118 #define IMX678_TPG_ALL_555 2 119 #define IMX678_TPG_ALL_AAA 3 120 #define IMX678_TPG_TOG_555_AAA 4 121 #define IMX678_TPG_TOG_AAA_555 5 122 #define IMX678_TPG_TOG_000_555 6 123 #define IMX678_TPG_TOG_555_000 7 124 #define IMX678_TPG_TOG_000_FFF 8 125 #define IMX678_TPG_TOG_FFF_000 9 126 #define IMX678_TPG_H_COLOR_BARS 10 127 #define IMX678_TPG_V_COLOR_BARS 11 128 #define IMX678_REG_TPG_COLORWIDTH CCI_REG8(0x30e4) 129 #define IMX678_TPG_COLORWIDTH_80PIX 0 130 #define IMX678_TPG_COLORWIDTH_160PIX 1 131 #define IMX678_TPG_COLORWIDTH_320PIX 2 132 #define IMX678_TPG_COLORWIDTH_640PIX 3 133 134 #define IMX678_REG_INTERFACE_SEL CCI_REG8(0x4e3c) 135 #define IMX678_INTERFACE_2L_4L 0x07 136 #define IMX678_INTERFACE_8L_2x4L 0x7f 137 138 /* Minimum output resolution */ 139 #define IMX678_PIXEL_ARRAY_MIN_WIDTH 1040 140 #define IMX678_PIXEL_ARRAY_MIN_HEIGHT 956 141 142 /* Sensor windowing register alignment */ 143 #define IMX678_CROP_HWIDTH_ALIGN 16 144 #define IMX678_CROP_VWIDTH_ALIGN 4 145 #define IMX678_CROP_HST_ALIGN 4 146 #define IMX678_CROP_VST_ALIGN 4 147 148 /* Subdev pads */ 149 #define IMX678_SOURCE_PAD 0 150 151 /* IMX678 native and active pixel array size. */ 152 static const struct v4l2_rect imx678_native_area = { 153 .top = 0, 154 .left = 0, 155 .width = 3857, 156 .height = 2201, 157 }; 158 159 static const struct v4l2_rect imx678_active_area = { 160 .top = 20, 161 .left = 0, 162 .width = 3856, 163 .height = 2180, 164 }; 165 166 enum imx678_type { 167 IMX678_COLOR = 0, 168 IMX678_MONOCHROME = 1, 169 }; 170 171 struct imx678_model_info { 172 enum imx678_type type; 173 const u32 *codes; 174 unsigned int num_codes; 175 }; 176 177 enum imx678_lanemode { 178 IMX678_LANEMODE_2L = 1, 179 IMX678_LANEMODE_4L = 3, 180 }; 181 182 /* Link frequency setup (DDR: lane rate = 2 x link freq) */ 183 enum { 184 IMX678_LINK_FREQ_297MHZ, 185 IMX678_LINK_FREQ_360MHZ, 186 IMX678_LINK_FREQ_445MHZ, 187 IMX678_LINK_FREQ_594MHZ, 188 IMX678_LINK_FREQ_720MHZ, 189 IMX678_LINK_FREQ_891MHZ, 190 IMX678_LINK_FREQ_1039MHZ, 191 IMX678_LINK_FREQ_1188MHZ, 192 }; 193 194 static const u8 link_freqs_reg_value[] = { 195 [IMX678_LINK_FREQ_297MHZ] = 0x07, 196 [IMX678_LINK_FREQ_360MHZ] = 0x06, 197 [IMX678_LINK_FREQ_445MHZ] = 0x05, 198 [IMX678_LINK_FREQ_594MHZ] = 0x04, 199 [IMX678_LINK_FREQ_720MHZ] = 0x03, 200 [IMX678_LINK_FREQ_891MHZ] = 0x02, 201 [IMX678_LINK_FREQ_1039MHZ] = 0x01, 202 [IMX678_LINK_FREQ_1188MHZ] = 0x00, 203 }; 204 205 static const u64 link_freqs[] = { 206 [IMX678_LINK_FREQ_297MHZ] = 297000000, 207 [IMX678_LINK_FREQ_360MHZ] = 360000000, 208 [IMX678_LINK_FREQ_445MHZ] = 445500000, 209 [IMX678_LINK_FREQ_594MHZ] = 594000000, 210 [IMX678_LINK_FREQ_720MHZ] = 720000000, 211 [IMX678_LINK_FREQ_891MHZ] = 891000000, 212 [IMX678_LINK_FREQ_1039MHZ] = 1039500000, 213 [IMX678_LINK_FREQ_1188MHZ] = 1188000000, 214 }; 215 216 static const u16 min_hmax_4lane[] = { 217 [IMX678_LINK_FREQ_297MHZ] = 1584, 218 [IMX678_LINK_FREQ_360MHZ] = 1320, 219 [IMX678_LINK_FREQ_445MHZ] = 1100, 220 [IMX678_LINK_FREQ_594MHZ] = 792, 221 [IMX678_LINK_FREQ_720MHZ] = 660, 222 [IMX678_LINK_FREQ_891MHZ] = 550, 223 [IMX678_LINK_FREQ_1039MHZ] = 550, 224 [IMX678_LINK_FREQ_1188MHZ] = 550, 225 }; 226 227 struct imx678_inck_cfg { 228 u32 xclk_hz; /* platform clock rate */ 229 u8 inck_sel; /* value for reg */ 230 }; 231 232 static const struct imx678_inck_cfg imx678_inck_table[] = { 233 { 74250000, 0x00 }, 234 { 37125000, 0x01 }, 235 { 72000000, 0x02 }, 236 { 27000000, 0x03 }, 237 { 24000000, 0x04 }, 238 { 36000000, 0x05 }, 239 { 18000000, 0x06 }, 240 { 13500000, 0x07 }, 241 }; 242 243 static const char * const imx678_tpg_menu[] = { 244 "Disabled", 245 "All 000h", 246 "All FFFh", 247 "All 555h", 248 "All AAAh", 249 "Toggle 555/AAAh", 250 "Toggle AAA/555h", 251 "Toggle 000/555h", 252 "Toggle 555/000h", 253 "Toggle 000/FFFh", 254 "Toggle FFF/000h", 255 "Horizontal color bars", 256 "Vertical color bars", 257 }; 258 259 static const int imx678_tpg_val[] = { 260 IMX678_TPG_ALL_000, 261 IMX678_TPG_ALL_000, 262 IMX678_TPG_ALL_FFF, 263 IMX678_TPG_ALL_555, 264 IMX678_TPG_ALL_AAA, 265 IMX678_TPG_TOG_555_AAA, 266 IMX678_TPG_TOG_AAA_555, 267 IMX678_TPG_TOG_000_555, 268 IMX678_TPG_TOG_555_000, 269 IMX678_TPG_TOG_000_FFF, 270 IMX678_TPG_TOG_FFF_000, 271 IMX678_TPG_H_COLOR_BARS, 272 IMX678_TPG_V_COLOR_BARS, 273 }; 274 275 /* Common configuration */ 276 static const struct cci_reg_sequence common_regs[] = { 277 { IMX678_REG_THIN_V_EN, 0x00 }, 278 { IMX678_REG_VCMODE, 0x01 }, 279 { CCI_REG8(0x306b), 0x00 }, 280 { IMX678_REG_GAIN_PGC_FIDMD, 0x01 }, 281 { CCI_REG8(0x3460), 0x22 }, 282 { CCI_REG8(0x355a), 0x64 }, 283 { CCI_REG8(0x3a02), 0x7a }, 284 { CCI_REG8(0x3a10), 0xec }, 285 { CCI_REG8(0x3a12), 0x71 }, 286 { CCI_REG8(0x3a14), 0xde }, 287 { CCI_REG8(0x3a20), 0x2b }, 288 { CCI_REG8(0x3a24), 0x22 }, 289 { CCI_REG8(0x3a25), 0x25 }, 290 { CCI_REG8(0x3a26), 0x2a }, 291 { CCI_REG8(0x3a27), 0x2c }, 292 { CCI_REG8(0x3a28), 0x39 }, 293 { CCI_REG8(0x3a29), 0x38 }, 294 { CCI_REG8(0x3a30), 0x04 }, 295 { CCI_REG8(0x3a31), 0x04 }, 296 { CCI_REG8(0x3a32), 0x03 }, 297 { CCI_REG8(0x3a33), 0x03 }, 298 { CCI_REG8(0x3a34), 0x09 }, 299 { CCI_REG8(0x3a35), 0x06 }, 300 { CCI_REG8(0x3a38), 0xcd }, 301 { CCI_REG8(0x3a3a), 0x4c }, 302 { CCI_REG8(0x3a3c), 0xb9 }, 303 { CCI_REG8(0x3a3e), 0x30 }, 304 { CCI_REG8(0x3a40), 0x2c }, 305 { CCI_REG8(0x3a42), 0x39 }, 306 { CCI_REG8(0x3a4e), 0x00 }, 307 { CCI_REG8(0x3a52), 0x00 }, 308 { CCI_REG8(0x3a56), 0x00 }, 309 { CCI_REG8(0x3a5a), 0x00 }, 310 { CCI_REG8(0x3a5e), 0x00 }, 311 { CCI_REG8(0x3a62), 0x00 }, 312 { CCI_REG8(0x3a64), 0x00 }, 313 { CCI_REG8(0x3a6e), 0xa0 }, 314 { CCI_REG8(0x3a70), 0x50 }, 315 { CCI_REG8(0x3a8c), 0x04 }, 316 { CCI_REG8(0x3a8d), 0x03 }, 317 { CCI_REG8(0x3a8e), 0x09 }, 318 { CCI_REG8(0x3a90), 0x38 }, 319 { CCI_REG8(0x3a91), 0x42 }, 320 { CCI_REG8(0x3a92), 0x3c }, 321 { CCI_REG8(0x3b0e), 0xf3 }, 322 { CCI_REG8(0x3b12), 0xe5 }, 323 { CCI_REG8(0x3b27), 0xc0 }, 324 { CCI_REG8(0x3b2e), 0xef }, 325 { CCI_REG8(0x3b30), 0x6a }, 326 { CCI_REG8(0x3b32), 0xf6 }, 327 { CCI_REG8(0x3b36), 0xe1 }, 328 { CCI_REG8(0x3b3a), 0xe8 }, 329 { CCI_REG8(0x3b5a), 0x17 }, 330 { CCI_REG8(0x3b5e), 0xef }, 331 { CCI_REG8(0x3b60), 0x6a }, 332 { CCI_REG8(0x3b62), 0xf6 }, 333 { CCI_REG8(0x3b66), 0xe1 }, 334 { CCI_REG8(0x3b6a), 0xe8 }, 335 { CCI_REG8(0x3b88), 0xec }, 336 { CCI_REG8(0x3b8a), 0xed }, 337 { CCI_REG8(0x3b94), 0x71 }, 338 { CCI_REG8(0x3b96), 0x72 }, 339 { CCI_REG8(0x3b98), 0xde }, 340 { CCI_REG8(0x3b9a), 0xdf }, 341 { CCI_REG8(0x3c0f), 0x06 }, 342 { CCI_REG8(0x3c10), 0x06 }, 343 { CCI_REG8(0x3c11), 0x06 }, 344 { CCI_REG8(0x3c12), 0x06 }, 345 { CCI_REG8(0x3c13), 0x06 }, 346 { CCI_REG8(0x3c18), 0x20 }, 347 { CCI_REG8(0x3c37), 0x10 }, 348 { CCI_REG8(0x3c3a), 0x7a }, 349 { CCI_REG8(0x3c40), 0xf4 }, 350 { CCI_REG8(0x3c48), 0xe6 }, 351 { CCI_REG8(0x3c54), 0xce }, 352 { CCI_REG8(0x3c56), 0xd0 }, 353 { CCI_REG8(0x3c6c), 0x53 }, 354 { CCI_REG8(0x3c6e), 0x55 }, 355 { CCI_REG8(0x3c70), 0xc0 }, 356 { CCI_REG8(0x3c72), 0xc2 }, 357 { CCI_REG8(0x3c7e), 0xce }, 358 { CCI_REG8(0x3c8c), 0xcf }, 359 { CCI_REG8(0x3c8e), 0xeb }, 360 { CCI_REG8(0x3c98), 0x54 }, 361 { CCI_REG8(0x3c9a), 0x70 }, 362 { CCI_REG8(0x3c9c), 0xc1 }, 363 { CCI_REG8(0x3c9e), 0xdd }, 364 { CCI_REG8(0x3cb0), 0x7a }, 365 { CCI_REG8(0x3cb2), 0xba }, 366 { CCI_REG8(0x3cc8), 0xbc }, 367 { CCI_REG8(0x3cca), 0x7c }, 368 { CCI_REG8(0x3cd4), 0xea }, 369 { CCI_REG8(0x3cd5), 0x01 }, 370 { CCI_REG8(0x3cd6), 0x4a }, 371 { CCI_REG8(0x3cd8), 0x00 }, 372 { CCI_REG8(0x3cd9), 0x00 }, 373 { CCI_REG8(0x3cda), 0xff }, 374 { CCI_REG8(0x3cdb), 0x03 }, 375 { CCI_REG8(0x3cdc), 0x00 }, 376 { CCI_REG8(0x3cdd), 0x00 }, 377 { CCI_REG8(0x3cde), 0xff }, 378 { CCI_REG8(0x3cdf), 0x03 }, 379 { CCI_REG8(0x3ce4), 0x4c }, 380 { CCI_REG8(0x3ce6), 0xec }, 381 { CCI_REG8(0x3ce7), 0x01 }, 382 { CCI_REG8(0x3ce8), 0xff }, 383 { CCI_REG8(0x3ce9), 0x03 }, 384 { CCI_REG8(0x3cea), 0x00 }, 385 { CCI_REG8(0x3ceb), 0x00 }, 386 { CCI_REG8(0x3cec), 0xff }, 387 { CCI_REG8(0x3ced), 0x03 }, 388 { CCI_REG8(0x3cee), 0x00 }, 389 { CCI_REG8(0x3cef), 0x00 }, 390 { CCI_REG8(0x3cf2), 0xff }, 391 { CCI_REG8(0x3cf3), 0x03 }, 392 { CCI_REG8(0x3cf4), 0x00 }, 393 { CCI_REG8(0x3e28), 0x82 }, 394 { CCI_REG8(0x3e2a), 0x80 }, 395 { CCI_REG8(0x3e30), 0x85 }, 396 { CCI_REG8(0x3e32), 0x7d }, 397 { CCI_REG8(0x3e5c), 0xce }, 398 { CCI_REG8(0x3e5e), 0xd3 }, 399 { CCI_REG8(0x3e70), 0x53 }, 400 { CCI_REG8(0x3e72), 0x58 }, 401 { CCI_REG8(0x3e74), 0xc0 }, 402 { CCI_REG8(0x3e76), 0xc5 }, 403 { CCI_REG8(0x3e78), 0xc0 }, 404 { CCI_REG8(0x3e79), 0x01 }, 405 { CCI_REG8(0x3e7a), 0xd4 }, 406 { CCI_REG8(0x3e7b), 0x01 }, 407 { CCI_REG8(0x3eb4), 0x0b }, 408 { CCI_REG8(0x3eb5), 0x02 }, 409 { CCI_REG8(0x3eb6), 0x4d }, 410 { CCI_REG8(0x3eb7), 0x42 }, 411 { CCI_REG8(0x3eec), 0xf3 }, 412 { CCI_REG8(0x3eee), 0xe7 }, 413 { CCI_REG8(0x3f01), 0x01 }, 414 { CCI_REG8(0x3f24), 0x10 }, 415 { CCI_REG8(0x3f28), 0x2d }, 416 { CCI_REG8(0x3f2a), 0x2d }, 417 { CCI_REG8(0x3f2c), 0x2d }, 418 { CCI_REG8(0x3f2e), 0x2d }, 419 { CCI_REG8(0x3f30), 0x23 }, 420 { CCI_REG8(0x3f38), 0x2d }, 421 { CCI_REG8(0x3f3a), 0x2d }, 422 { CCI_REG8(0x3f3c), 0x2d }, 423 { CCI_REG8(0x3f3e), 0x28 }, 424 { CCI_REG8(0x3f40), 0x1e }, 425 { CCI_REG8(0x3f48), 0x2d }, 426 { CCI_REG8(0x3f4a), 0x2d }, 427 { CCI_REG8(0x3f4c), 0x00 }, 428 { CCI_REG8(0x4004), 0xe4 }, 429 { CCI_REG8(0x4006), 0xff }, 430 { CCI_REG8(0x4018), 0x69 }, 431 { CCI_REG8(0x401a), 0x84 }, 432 { CCI_REG8(0x401c), 0xd6 }, 433 { CCI_REG8(0x401e), 0xf1 }, 434 { CCI_REG8(0x4038), 0xde }, 435 { CCI_REG8(0x403a), 0x00 }, 436 { CCI_REG8(0x403b), 0x01 }, 437 { CCI_REG8(0x404c), 0x63 }, 438 { CCI_REG8(0x404e), 0x85 }, 439 { CCI_REG8(0x4050), 0xd0 }, 440 { CCI_REG8(0x4052), 0xf2 }, 441 { CCI_REG8(0x4108), 0xdd }, 442 { CCI_REG8(0x410a), 0xf7 }, 443 { CCI_REG8(0x411c), 0x62 }, 444 { CCI_REG8(0x411e), 0x7c }, 445 { CCI_REG8(0x4120), 0xcf }, 446 { CCI_REG8(0x4122), 0xe9 }, 447 { CCI_REG8(0x4138), 0xe6 }, 448 { CCI_REG8(0x413a), 0xf1 }, 449 { CCI_REG8(0x414c), 0x6b }, 450 { CCI_REG8(0x414e), 0x76 }, 451 { CCI_REG8(0x4150), 0xd8 }, 452 { CCI_REG8(0x4152), 0xe3 }, 453 { CCI_REG8(0x417e), 0x03 }, 454 { CCI_REG8(0x417f), 0x01 }, 455 { CCI_REG8(0x4186), 0xe0 }, 456 { CCI_REG8(0x4190), 0xf3 }, 457 { CCI_REG8(0x4192), 0xf7 }, 458 { CCI_REG8(0x419c), 0x78 }, 459 { CCI_REG8(0x419e), 0x7c }, 460 { CCI_REG8(0x41a0), 0xe5 }, 461 { CCI_REG8(0x41a2), 0xe9 }, 462 { CCI_REG8(0x41c8), 0xe2 }, 463 { CCI_REG8(0x41ca), 0xfd }, 464 { CCI_REG8(0x41dc), 0x67 }, 465 { CCI_REG8(0x41de), 0x82 }, 466 { CCI_REG8(0x41e0), 0xd4 }, 467 { CCI_REG8(0x41e2), 0xef }, 468 { CCI_REG8(0x4200), 0xde }, 469 { CCI_REG8(0x4202), 0xda }, 470 { CCI_REG8(0x4218), 0x63 }, 471 { CCI_REG8(0x421a), 0x5f }, 472 { CCI_REG8(0x421c), 0xd0 }, 473 { CCI_REG8(0x421e), 0xcc }, 474 { CCI_REG8(0x425a), 0x82 }, 475 { CCI_REG8(0x425c), 0xef }, 476 { CCI_REG8(0x4348), 0xfe }, 477 { CCI_REG8(0x4349), 0x06 }, 478 { CCI_REG8(0x4352), 0xce }, 479 { CCI_REG8(0x4420), 0x0b }, 480 { CCI_REG8(0x4421), 0x02 }, 481 { CCI_REG8(0x4422), 0x4d }, 482 { CCI_REG8(0x4423), 0x0a }, 483 { CCI_REG8(0x4426), 0xf5 }, 484 { CCI_REG8(0x442a), 0xe7 }, 485 { CCI_REG8(0x4432), 0xf5 }, 486 { CCI_REG8(0x4436), 0xe7 }, 487 { CCI_REG8(0x4466), 0xb4 }, 488 { CCI_REG8(0x446e), 0x32 }, 489 { CCI_REG8(0x449f), 0x1c }, 490 { CCI_REG8(0x44a4), 0x2c }, 491 { CCI_REG8(0x44a6), 0x2c }, 492 { CCI_REG8(0x44a8), 0x2c }, 493 { CCI_REG8(0x44aa), 0x2c }, 494 { CCI_REG8(0x44b4), 0x2c }, 495 { CCI_REG8(0x44b6), 0x2c }, 496 { CCI_REG8(0x44b8), 0x2c }, 497 { CCI_REG8(0x44ba), 0x2c }, 498 { CCI_REG8(0x44c4), 0x2c }, 499 { CCI_REG8(0x44c6), 0x2c }, 500 { CCI_REG8(0x44c8), 0x2c }, 501 { CCI_REG8(0x4506), 0xf3 }, 502 { CCI_REG8(0x450e), 0xe5 }, 503 { CCI_REG8(0x4516), 0xf3 }, 504 { CCI_REG8(0x4522), 0xe5 }, 505 { CCI_REG8(0x4524), 0xf3 }, 506 { CCI_REG8(0x452c), 0xe5 }, 507 { CCI_REG8(0x453c), 0x22 }, 508 { CCI_REG8(0x453d), 0x1b }, 509 { CCI_REG8(0x453e), 0x1b }, 510 { CCI_REG8(0x453f), 0x15 }, 511 { CCI_REG8(0x4540), 0x15 }, 512 { CCI_REG8(0x4541), 0x15 }, 513 { CCI_REG8(0x4542), 0x15 }, 514 { CCI_REG8(0x4543), 0x15 }, 515 { CCI_REG8(0x4544), 0x15 }, 516 { CCI_REG8(0x4548), 0x00 }, 517 { CCI_REG8(0x4549), 0x01 }, 518 { CCI_REG8(0x454a), 0x01 }, 519 { CCI_REG8(0x454b), 0x06 }, 520 { CCI_REG8(0x454c), 0x06 }, 521 { CCI_REG8(0x454d), 0x06 }, 522 { CCI_REG8(0x454e), 0x06 }, 523 { CCI_REG8(0x454f), 0x06 }, 524 { CCI_REG8(0x4550), 0x06 }, 525 { CCI_REG8(0x4554), 0x55 }, 526 { CCI_REG8(0x4555), 0x02 }, 527 { CCI_REG8(0x4556), 0x42 }, 528 { CCI_REG8(0x4557), 0x05 }, 529 { CCI_REG8(0x4558), 0xfd }, 530 { CCI_REG8(0x4559), 0x05 }, 531 { CCI_REG8(0x455a), 0x94 }, 532 { CCI_REG8(0x455b), 0x06 }, 533 { CCI_REG8(0x455d), 0x06 }, 534 { CCI_REG8(0x455e), 0x49 }, 535 { CCI_REG8(0x455f), 0x07 }, 536 { CCI_REG8(0x4560), 0x7f }, 537 { CCI_REG8(0x4561), 0x07 }, 538 { CCI_REG8(0x4562), 0xa5 }, 539 { CCI_REG8(0x4564), 0x55 }, 540 { CCI_REG8(0x4565), 0x02 }, 541 { CCI_REG8(0x4566), 0x42 }, 542 { CCI_REG8(0x4567), 0x05 }, 543 { CCI_REG8(0x4568), 0xfd }, 544 { CCI_REG8(0x4569), 0x05 }, 545 { CCI_REG8(0x456a), 0x94 }, 546 { CCI_REG8(0x456b), 0x06 }, 547 { CCI_REG8(0x456d), 0x06 }, 548 { CCI_REG8(0x456e), 0x49 }, 549 { CCI_REG8(0x456f), 0x07 }, 550 { CCI_REG8(0x4572), 0xa5 }, 551 { CCI_REG8(0x460c), 0x7d }, 552 { CCI_REG8(0x460e), 0xb1 }, 553 { CCI_REG8(0x4614), 0xa8 }, 554 { CCI_REG8(0x4616), 0xb2 }, 555 { CCI_REG8(0x461c), 0x7e }, 556 { CCI_REG8(0x461e), 0xa7 }, 557 { CCI_REG8(0x4624), 0xa8 }, 558 { CCI_REG8(0x4626), 0xb2 }, 559 { CCI_REG8(0x462c), 0x7e }, 560 { CCI_REG8(0x462e), 0x8a }, 561 { CCI_REG8(0x4630), 0x94 }, 562 { CCI_REG8(0x4632), 0xa7 }, 563 { CCI_REG8(0x4634), 0xfb }, 564 { CCI_REG8(0x4636), 0x2f }, 565 { CCI_REG8(0x4638), 0x81 }, 566 { CCI_REG8(0x4639), 0x01 }, 567 { CCI_REG8(0x463a), 0xb5 }, 568 { CCI_REG8(0x463b), 0x01 }, 569 { CCI_REG8(0x463c), 0x26 }, 570 { CCI_REG8(0x463e), 0x30 }, 571 { CCI_REG8(0x4640), 0xac }, 572 { CCI_REG8(0x4641), 0x01 }, 573 { CCI_REG8(0x4642), 0xb6 }, 574 { CCI_REG8(0x4643), 0x01 }, 575 { CCI_REG8(0x4644), 0xfc }, 576 { CCI_REG8(0x4646), 0x25 }, 577 { CCI_REG8(0x4648), 0x82 }, 578 { CCI_REG8(0x4649), 0x01 }, 579 { CCI_REG8(0x464a), 0xab }, 580 { CCI_REG8(0x464b), 0x01 }, 581 { CCI_REG8(0x464c), 0x26 }, 582 { CCI_REG8(0x464e), 0x30 }, 583 { CCI_REG8(0x4654), 0xfc }, 584 { CCI_REG8(0x4656), 0x08 }, 585 { CCI_REG8(0x4658), 0x12 }, 586 { CCI_REG8(0x465a), 0x25 }, 587 { CCI_REG8(0x4662), 0xfc }, 588 { CCI_REG8(0x46a2), 0xfb }, 589 { CCI_REG8(0x46d6), 0xf3 }, 590 { CCI_REG8(0x46e6), 0x00 }, 591 { CCI_REG8(0x46e8), 0xff }, 592 { CCI_REG8(0x46e9), 0x03 }, 593 { CCI_REG8(0x46ec), 0x7a }, 594 { CCI_REG8(0x46ee), 0xe5 }, 595 { CCI_REG8(0x46f4), 0xee }, 596 { CCI_REG8(0x46f6), 0xf2 }, 597 { CCI_REG8(0x470c), 0xff }, 598 { CCI_REG8(0x470d), 0x03 }, 599 { CCI_REG8(0x470e), 0x00 }, 600 { CCI_REG8(0x4714), 0xe0 }, 601 { CCI_REG8(0x4716), 0xe4 }, 602 { CCI_REG8(0x471e), 0xed }, 603 { CCI_REG8(0x472e), 0x00 }, 604 { CCI_REG8(0x4730), 0xff }, 605 { CCI_REG8(0x4731), 0x03 }, 606 { CCI_REG8(0x4734), 0x7b }, 607 { CCI_REG8(0x4736), 0xdf }, 608 { CCI_REG8(0x4754), 0x7d }, 609 { CCI_REG8(0x4756), 0x8b }, 610 { CCI_REG8(0x4758), 0x93 }, 611 { CCI_REG8(0x475a), 0xb1 }, 612 { CCI_REG8(0x475c), 0xfb }, 613 { CCI_REG8(0x475e), 0x09 }, 614 { CCI_REG8(0x4760), 0x11 }, 615 { CCI_REG8(0x4762), 0x2f }, 616 { CCI_REG8(0x4766), 0xcc }, 617 { CCI_REG8(0x4776), 0xcb }, 618 { CCI_REG8(0x477e), 0x4a }, 619 { CCI_REG8(0x478e), 0x49 }, 620 { CCI_REG8(0x4794), 0x7c }, 621 { CCI_REG8(0x4796), 0x8f }, 622 { CCI_REG8(0x4798), 0xb3 }, 623 { CCI_REG8(0x4799), 0x00 }, 624 { CCI_REG8(0x479a), 0xcc }, 625 { CCI_REG8(0x479c), 0xc1 }, 626 { CCI_REG8(0x479e), 0xcb }, 627 { CCI_REG8(0x47a4), 0x7d }, 628 { CCI_REG8(0x47a6), 0x8e }, 629 { CCI_REG8(0x47a8), 0xb4 }, 630 { CCI_REG8(0x47a9), 0x00 }, 631 { CCI_REG8(0x47aa), 0xc0 }, 632 { CCI_REG8(0x47ac), 0xfa }, 633 { CCI_REG8(0x47ae), 0x0d }, 634 { CCI_REG8(0x47b0), 0x31 }, 635 { CCI_REG8(0x47b1), 0x01 }, 636 { CCI_REG8(0x47b2), 0x4a }, 637 { CCI_REG8(0x47b3), 0x01 }, 638 { CCI_REG8(0x47b4), 0x3f }, 639 { CCI_REG8(0x47b6), 0x49 }, 640 { CCI_REG8(0x47bc), 0xfb }, 641 { CCI_REG8(0x47be), 0x0c }, 642 { CCI_REG8(0x47c0), 0x32 }, 643 { CCI_REG8(0x47c1), 0x01 }, 644 { CCI_REG8(0x47c2), 0x3e }, 645 { CCI_REG8(0x47c3), 0x01 }, 646 { IMX678_REG_WDMODE, 0x00 }, 647 { IMX678_REG_MDBIT, 0x01 }, 648 { IMX678_REG_XXS_DRV, 0x00 }, 649 }; 650 651 static const u32 codes_bayer[] = { 652 MEDIA_BUS_FMT_SRGGB12_1X12, 653 }; 654 655 static const u32 codes_monochrome[] = { 656 MEDIA_BUS_FMT_Y12_1X12, 657 }; 658 659 static const struct imx678_model_info imx678_aaqr_info = { 660 .type = IMX678_COLOR, 661 .codes = codes_bayer, 662 .num_codes = ARRAY_SIZE(codes_bayer), 663 }; 664 665 static const struct imx678_model_info imx678_aamr_info = { 666 .type = IMX678_MONOCHROME, 667 .codes = codes_monochrome, 668 .num_codes = ARRAY_SIZE(codes_monochrome), 669 }; 670 671 static const char * const imx678_supply_name[] = { 672 "avdd", /* Analog (3.3V) supply */ 673 "dvdd", /* Digital Core (1.1V) supply */ 674 "ovdd", /* IF (1.8V) supply */ 675 }; 676 677 struct imx678 { 678 struct v4l2_subdev sd; 679 struct media_pad pad; 680 struct regmap *cci; 681 682 const struct imx678_model_info *info; 683 684 struct clk *xclk; 685 u32 xclk_freq; 686 687 /* chosen INCK_SEL register value */ 688 u8 inck_sel_val; 689 690 /* Link configurations */ 691 enum imx678_lanemode lane_mode; 692 unsigned long link_freq_bitmap; 693 694 struct gpio_desc *reset_gpio; 695 struct regulator_bulk_data supplies[ARRAY_SIZE(imx678_supply_name)]; 696 697 struct v4l2_ctrl_handler ctrl_handler; 698 699 /* V4L2 Controls */ 700 struct v4l2_ctrl *exposure; 701 struct v4l2_ctrl *vblank; 702 struct v4l2_ctrl *hblank; 703 704 /* Track VMAX for exposure updates */ 705 u32 vmax; 706 }; 707 708 static inline struct imx678 *to_imx678(struct v4l2_subdev *_sd) 709 { 710 return container_of_const(_sd, struct imx678, sd); 711 } 712 713 static u32 imx678_default_mbus_code(struct imx678 *imx678) 714 { 715 return imx678->info->codes[0]; 716 } 717 718 static bool imx678_mbus_code_supported(struct imx678 *imx678, u32 code) 719 { 720 for (unsigned int i = 0; i < imx678->info->num_codes; i++) { 721 if (imx678->info->codes[i] == code) 722 return true; 723 } 724 725 return false; 726 } 727 728 static int imx678_set_ctrl(struct v4l2_ctrl *ctrl) 729 { 730 struct imx678 *imx678 = container_of_const(ctrl->handler, struct 731 imx678, ctrl_handler); 732 struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd); 733 const struct v4l2_mbus_framefmt *format; 734 struct v4l2_subdev_state *state; 735 int ret = 0; 736 737 state = v4l2_subdev_get_locked_active_state(&imx678->sd); 738 format = v4l2_subdev_state_get_format(state, IMX678_SOURCE_PAD); 739 740 if (ctrl->id == V4L2_CID_VBLANK) { 741 u32 current_exposure = imx678->exposure->cur.val; 742 743 imx678->vmax = format->height + ctrl->val; 744 745 current_exposure = clamp_t(u32, current_exposure, 746 IMX678_EXPOSURE_MIN, 747 imx678->vmax - IMX678_SHR_MIN); 748 ret = __v4l2_ctrl_modify_range(imx678->exposure, 749 IMX678_EXPOSURE_MIN, 750 imx678->vmax - IMX678_SHR_MIN, 751 1, current_exposure); 752 if (ret) 753 return ret; 754 } 755 756 /* 757 * Only apply control values when device is powered on (RPM ACTIVE) 758 * and streaming (usage count != 0) 759 */ 760 if (!pm_runtime_get_if_in_use(&client->dev)) 761 return 0; 762 763 switch (ctrl->id) { 764 case V4L2_CID_VBLANK: 765 cci_write(imx678->cci, IMX678_REG_VMAX, imx678->vmax, &ret); 766 fallthrough; /* SHR = VMAX - exposure, so update it */ 767 case V4L2_CID_EXPOSURE: { 768 u32 shr = imx678->vmax - imx678->exposure->val; 769 770 cci_write(imx678->cci, IMX678_REG_SHR, shr, &ret); 771 break; 772 } 773 case V4L2_CID_ANALOGUE_GAIN: 774 cci_write(imx678->cci, IMX678_REG_GAIN, ctrl->val, &ret); 775 break; 776 case V4L2_CID_HBLANK: { 777 u32 hmax = (format->width + ctrl->val) / IMX678_PIX_PER_CLK; 778 779 cci_write(imx678->cci, IMX678_REG_HMAX, hmax, &ret); 780 break; 781 } 782 case V4L2_CID_TEST_PATTERN: { 783 cci_write(imx678->cci, IMX678_REG_TPG_COLORWIDTH, 784 IMX678_TPG_COLORWIDTH_160PIX, &ret); 785 cci_write(imx678->cci, IMX678_REG_TPG_PATSEL_DUOUT, 786 imx678_tpg_val[ctrl->val], &ret); 787 cci_write(imx678->cci, IMX678_REG_TPG_EN_DUOUT, 788 (ctrl->val) ? 1 : 0, 789 &ret); 790 break; 791 } 792 case V4L2_CID_HFLIP: 793 cci_write(imx678->cci, IMX678_REG_WINMODEH, ctrl->val, &ret); 794 break; 795 case V4L2_CID_VFLIP: 796 cci_write(imx678->cci, IMX678_REG_WINMODEV, ctrl->val, &ret); 797 break; 798 default: 799 dev_warn(&client->dev, 800 "ctrl(id:0x%x,val:0x%x) is not handled\n", 801 ctrl->id, ctrl->val); 802 break; 803 } 804 805 pm_runtime_put(&client->dev); 806 807 return ret; 808 } 809 810 static const struct v4l2_ctrl_ops imx678_ctrl_ops = { 811 .s_ctrl = imx678_set_ctrl, 812 }; 813 814 static int imx678_enum_mbus_code(struct v4l2_subdev *sd, 815 struct v4l2_subdev_state *sd_state, 816 struct v4l2_subdev_mbus_code_enum *code) 817 { 818 struct imx678 *imx678 = to_imx678(sd); 819 820 if (code->index >= imx678->info->num_codes) 821 return -EINVAL; 822 823 code->code = imx678->info->codes[code->index]; 824 825 return 0; 826 } 827 828 static int imx678_enum_frame_size(struct v4l2_subdev *sd, 829 struct v4l2_subdev_state *sd_state, 830 struct v4l2_subdev_frame_size_enum *fse) 831 { 832 struct imx678 *imx678 = to_imx678(sd); 833 const struct v4l2_rect *crop; 834 835 if (fse->index) 836 return -EINVAL; 837 838 if (!imx678_mbus_code_supported(imx678, fse->code)) 839 return -EINVAL; 840 841 crop = v4l2_subdev_state_get_crop(sd_state, fse->pad); 842 843 fse->min_width = crop->width; 844 fse->max_width = fse->min_width; 845 fse->min_height = crop->height; 846 fse->max_height = fse->min_height; 847 848 return 0; 849 } 850 851 static int imx678_get_selection(struct v4l2_subdev *sd, 852 struct v4l2_subdev_state *sd_state, 853 struct v4l2_subdev_selection *sel) 854 { 855 switch (sel->target) { 856 case V4L2_SEL_TGT_CROP: 857 sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad); 858 return 0; 859 860 case V4L2_SEL_TGT_NATIVE_SIZE: 861 sel->r = imx678_native_area; 862 return 0; 863 864 case V4L2_SEL_TGT_CROP_DEFAULT: 865 case V4L2_SEL_TGT_CROP_BOUNDS: 866 sel->r = imx678_active_area; 867 return 0; 868 } 869 870 return -EINVAL; 871 } 872 873 static int imx678_init_state(struct v4l2_subdev *sd, 874 struct v4l2_subdev_state *state) 875 { 876 struct imx678 *imx678 = to_imx678(sd); 877 struct v4l2_mbus_framefmt *format; 878 struct v4l2_rect *crop; 879 880 crop = v4l2_subdev_state_get_crop(state, IMX678_SOURCE_PAD); 881 *crop = imx678_active_area; 882 883 format = v4l2_subdev_state_get_format(state, IMX678_SOURCE_PAD); 884 format->code = imx678_default_mbus_code(imx678); 885 format->width = imx678_active_area.width; 886 format->height = imx678_active_area.height; 887 format->field = V4L2_FIELD_NONE; 888 format->colorspace = V4L2_COLORSPACE_RAW; 889 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 890 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; 891 format->xfer_func = V4L2_XFER_FUNC_NONE; 892 893 return 0; 894 } 895 896 static int imx678_write_common(struct imx678 *imx678) 897 { 898 int ret = 0; 899 900 cci_multi_reg_write(imx678->cci, common_regs, ARRAY_SIZE(common_regs), 901 &ret); 902 903 cci_write(imx678->cci, IMX678_REG_INCK_SEL, imx678->inck_sel_val, &ret); 904 cci_write(imx678->cci, IMX678_REG_DATARATE_SEL, 905 link_freqs_reg_value[__ffs(imx678->link_freq_bitmap)], &ret); 906 cci_write(imx678->cci, IMX678_REG_LANEMODE, imx678->lane_mode, &ret); 907 908 cci_write(imx678->cci, IMX678_REG_INTERFACE_SEL, IMX678_INTERFACE_2L_4L, 909 &ret); 910 911 return ret; 912 } 913 914 static int imx678_program_window(struct imx678 *imx678, 915 const struct v4l2_rect *crop) 916 { 917 int ret = 0; 918 919 cci_write(imx678->cci, IMX678_REG_ADDMODE, 0x00, &ret); 920 cci_write(imx678->cci, IMX678_REG_WINMODE, 921 v4l2_rect_equal(crop, &imx678_active_area) ? 0x00 : 0x04, 922 &ret); 923 cci_write(imx678->cci, IMX678_REG_PIX_HST, 924 crop->left - imx678_active_area.left, &ret); 925 cci_write(imx678->cci, IMX678_REG_PIX_HWIDTH, crop->width, &ret); 926 cci_write(imx678->cci, IMX678_REG_PIX_VST, 927 crop->top - imx678_active_area.top, &ret); 928 cci_write(imx678->cci, IMX678_REG_PIX_VWIDTH, crop->height, &ret); 929 cci_write(imx678->cci, IMX678_REG_ADBIT, 0x01, &ret); 930 931 return ret; 932 } 933 934 static int imx678_enable_streams(struct v4l2_subdev *sd, 935 struct v4l2_subdev_state *state, u32 pad, 936 u64 mask) 937 { 938 struct i2c_client *client = v4l2_get_subdevdata(sd); 939 struct imx678 *imx678 = to_imx678(sd); 940 const struct v4l2_rect *crop; 941 int ret; 942 943 ret = pm_runtime_resume_and_get(&client->dev); 944 if (ret < 0) 945 return ret; 946 947 crop = v4l2_subdev_state_get_crop(state, pad); 948 ret = imx678_program_window(imx678, crop); 949 if (ret) { 950 dev_err(&client->dev, "%s failed to set mode\n", __func__); 951 goto err_rpm_put; 952 } 953 954 ret = __v4l2_ctrl_handler_setup(imx678->sd.ctrl_handler); 955 if (ret) { 956 dev_err(&client->dev, "%s failed to apply user values\n", 957 __func__); 958 goto err_rpm_put; 959 } 960 961 cci_write(imx678->cci, IMX678_REG_MODE_SELECT, IMX678_MODE_STREAMING, 962 &ret); 963 usleep_range(IMX678_STREAM_DELAY_US, IMX678_STREAM_DELAY_US + 964 IMX678_STREAM_DELAY_RANGE_US); 965 cci_write(imx678->cci, IMX678_REG_XMSTA, 0x00, &ret); 966 967 if (ret) { 968 dev_err(&client->dev, "%s failed to start streaming\n", 969 __func__); 970 goto err_rpm_put; 971 } 972 973 return 0; 974 975 err_rpm_put: 976 pm_runtime_put(&client->dev); 977 978 return ret; 979 } 980 981 static int imx678_disable_streams(struct v4l2_subdev *sd, 982 struct v4l2_subdev_state *state, 983 u32 pad, u64 mask) 984 { 985 struct i2c_client *client = v4l2_get_subdevdata(sd); 986 struct imx678 *imx678 = to_imx678(sd); 987 int ret = 0; 988 989 /* Master mode disable */ 990 cci_write(imx678->cci, IMX678_REG_XMSTA, 0x01, &ret); 991 /* Standby */ 992 cci_write(imx678->cci, IMX678_REG_MODE_SELECT, IMX678_MODE_STANDBY, 993 &ret); 994 if (ret) 995 dev_err(&client->dev, "%s failed to stop stream\n", __func__); 996 997 pm_runtime_put(&client->dev); 998 999 return ret; 1000 } 1001 1002 static int imx678_power_on(struct device *dev) 1003 { 1004 struct i2c_client *client = to_i2c_client(dev); 1005 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1006 struct imx678 *imx678 = to_imx678(sd); 1007 int ret; 1008 1009 ret = regulator_bulk_enable(ARRAY_SIZE(imx678_supply_name), 1010 imx678->supplies); 1011 if (ret) { 1012 dev_err(&client->dev, "%s: failed to enable regulators\n", 1013 __func__); 1014 return ret; 1015 } 1016 1017 fsleep(1); /* Tlow > 500ns */ 1018 1019 gpiod_set_value_cansleep(imx678->reset_gpio, 0); 1020 1021 fsleep(1); /* T3 > 1us */ 1022 1023 ret = clk_prepare_enable(imx678->xclk); 1024 if (ret) { 1025 dev_err(&client->dev, "%s: failed to enable clock\n", 1026 __func__); 1027 goto reg_off; 1028 } 1029 1030 fsleep(20); /* T4 > 20us */ 1031 1032 ret = imx678_write_common(imx678); 1033 if (ret) { 1034 dev_err(&client->dev, "%s failed to write registers\n", 1035 __func__); 1036 goto clk_off; 1037 } 1038 1039 return 0; 1040 1041 clk_off: 1042 clk_disable_unprepare(imx678->xclk); 1043 1044 reg_off: 1045 gpiod_set_value_cansleep(imx678->reset_gpio, 1); 1046 regulator_bulk_disable(ARRAY_SIZE(imx678_supply_name), 1047 imx678->supplies); 1048 1049 return ret; 1050 } 1051 1052 static int imx678_power_off(struct device *dev) 1053 { 1054 struct i2c_client *client = to_i2c_client(dev); 1055 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1056 struct imx678 *imx678 = to_imx678(sd); 1057 1058 clk_disable_unprepare(imx678->xclk); 1059 gpiod_set_value_cansleep(imx678->reset_gpio, 1); 1060 regulator_bulk_disable(ARRAY_SIZE(imx678_supply_name), 1061 imx678->supplies); 1062 1063 return 0; 1064 } 1065 1066 static int imx678_identify_model(struct imx678 *imx678) 1067 { 1068 struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd); 1069 const struct imx678_model_info *info; 1070 enum imx678_type detected; 1071 int ret = 0; 1072 u64 val = 0; 1073 1074 info = device_get_match_data(&client->dev); 1075 1076 /* 1077 * This sensor's ID registers become accessible 80ms after coming out 1078 * of STANDBY mode. 1079 */ 1080 cci_write(imx678->cci, IMX678_REG_MODE_SELECT, 0, &ret); 1081 fsleep(IMX678_MODULE_ID_DELAY); 1082 1083 cci_read(imx678->cci, IMX678_REG_MODULE_ID, &val, &ret); 1084 1085 if (ret) { 1086 dev_err(&client->dev, 1087 "I2C transaction failed ret = %d\n", ret); 1088 return ret; 1089 } 1090 1091 if (val != IMX678_ID) { 1092 dev_err(&client->dev, 1093 "Chip ID mismatch: %x!=%llx\n", IMX678_ID, val); 1094 return -ENXIO; 1095 } 1096 1097 cci_read(imx678->cci, IMX678_REG_MONOCHROME, &val, &ret); 1098 1099 if (ret) { 1100 dev_err(&client->dev, 1101 "I2C transaction failed ret = %d\n", ret); 1102 return ret; 1103 } 1104 1105 detected = val & IMX678_TYPE; 1106 1107 /* Prefer to use sensor type specified in device tree */ 1108 if (info) { 1109 imx678->info = info; 1110 if (detected != info->type) 1111 dev_err(&client->dev, 1112 "detected %s sensor, DT specifies %s; using DT value\n", 1113 detected == IMX678_COLOR ? "color" : "mono", 1114 info->type == IMX678_COLOR ? "color" : "mono"); 1115 } else { 1116 imx678->info = detected == IMX678_MONOCHROME ? 1117 &imx678_aamr_info : &imx678_aaqr_info; 1118 dev_info(&client->dev, 1119 "sensor type missing in DT; detected %s sensor\n", 1120 detected == IMX678_MONOCHROME ? "mono" : "color"); 1121 } 1122 1123 return 0; 1124 } 1125 1126 static const struct v4l2_subdev_video_ops imx678_video_ops = { 1127 .s_stream = v4l2_subdev_s_stream_helper, 1128 }; 1129 1130 static const struct v4l2_subdev_pad_ops imx678_pad_ops = { 1131 .enum_mbus_code = imx678_enum_mbus_code, 1132 .get_fmt = v4l2_subdev_get_fmt, 1133 .set_fmt = v4l2_subdev_get_fmt, 1134 .get_selection = imx678_get_selection, 1135 .enum_frame_size = imx678_enum_frame_size, 1136 .enable_streams = imx678_enable_streams, 1137 .disable_streams = imx678_disable_streams, 1138 }; 1139 1140 static const struct v4l2_subdev_ops imx678_subdev_ops = { 1141 .video = &imx678_video_ops, 1142 .pad = &imx678_pad_ops, 1143 }; 1144 1145 static const struct v4l2_subdev_internal_ops imx678_internal_ops = { 1146 .init_state = imx678_init_state, 1147 }; 1148 1149 static int imx678_init_controls(struct imx678 *imx678) 1150 { 1151 struct v4l2_ctrl_handler *ctrl_hdlr; 1152 const u32 hmax_4lane = min_hmax_4lane[__ffs(imx678->link_freq_bitmap)]; 1153 const u32 lane_scale = imx678->lane_mode == IMX678_LANEMODE_2L ? 2 : 1; 1154 struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd); 1155 struct v4l2_fwnode_device_properties props; 1156 struct v4l2_ctrl *link_freq; 1157 s32 hblank, max_hblank, vblank, max_vblank; 1158 u32 hmax; 1159 int ret; 1160 1161 ret = v4l2_fwnode_device_parse(&client->dev, &props); 1162 if (ret < 0) 1163 return ret; 1164 1165 ctrl_hdlr = &imx678->ctrl_handler; 1166 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11); 1167 if (ret) 1168 return ret; 1169 1170 imx678->vmax = IMX678_VMAX_DEFAULT; 1171 hmax = hmax_4lane * lane_scale; 1172 1173 /* PIXEL_RATE is fixed and read-only */ 1174 v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_PIXEL_RATE, 1175 IMX678_PIXEL_RATE, IMX678_PIXEL_RATE, 1, 1176 IMX678_PIXEL_RATE); 1177 1178 /* LINK_FREQ is also read only */ 1179 link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx678_ctrl_ops, 1180 V4L2_CID_LINK_FREQ, 1181 ARRAY_SIZE(link_freqs) - 1, 1182 __ffs(imx678->link_freq_bitmap), 1183 link_freqs); 1184 1185 if (link_freq) 1186 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1187 1188 vblank = imx678->vmax - imx678_active_area.height; 1189 max_vblank = IMX678_VMAX_MAX - imx678_active_area.height; 1190 imx678->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, 1191 V4L2_CID_VBLANK, vblank, max_vblank, 1192 2, vblank); 1193 1194 hblank = hmax * IMX678_PIX_PER_CLK - imx678_active_area.width; 1195 max_hblank = IMX678_HMAX_MAX * IMX678_PIX_PER_CLK - 1196 imx678_active_area.width; 1197 imx678->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, 1198 V4L2_CID_HBLANK, hblank, max_hblank, 1199 IMX678_PIX_PER_CLK, hblank); 1200 1201 imx678->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, 1202 V4L2_CID_EXPOSURE, 1203 IMX678_EXPOSURE_MIN, 1204 IMX678_VMAX_DEFAULT - 1205 IMX678_SHR_MIN, 1206 IMX678_EXPOSURE_STEP, 1207 IMX678_EXPOSURE_DEFAULT); 1208 1209 v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 1210 IMX678_ANA_GAIN_MIN_NORMAL, 1211 IMX678_ANA_GAIN_MAX_NORMAL, IMX678_ANA_GAIN_STEP, 1212 IMX678_ANA_GAIN_DEFAULT); 1213 1214 v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_HFLIP, 1215 0, 1, 1, 0); 1216 v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_VFLIP, 1217 0, 1, 1, 0); 1218 1219 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx678_ctrl_ops, 1220 V4L2_CID_TEST_PATTERN, 1221 ARRAY_SIZE(imx678_tpg_menu) - 1, 0, 0, 1222 imx678_tpg_menu); 1223 1224 v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx678_ctrl_ops, &props); 1225 1226 if (ctrl_hdlr->error) { 1227 ret = ctrl_hdlr->error; 1228 dev_err(&client->dev, "%s control init failed (%d)\n", 1229 __func__, ret); 1230 v4l2_ctrl_handler_free(ctrl_hdlr); 1231 return ret; 1232 } 1233 1234 imx678->sd.ctrl_handler = ctrl_hdlr; 1235 1236 return 0; 1237 } 1238 1239 static int imx678_check_hwcfg(struct device *dev, struct imx678 *imx678) 1240 { 1241 struct fwnode_handle *endpoint; 1242 struct v4l2_fwnode_endpoint ep_cfg = { 1243 .bus_type = V4L2_MBUS_CSI2_DPHY 1244 }; 1245 int ret = -EINVAL; 1246 1247 endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0); 1248 if (!endpoint) { 1249 dev_err(dev, "endpoint node not found\n"); 1250 return -EINVAL; 1251 } 1252 1253 if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) { 1254 dev_err(dev, "could not parse endpoint\n"); 1255 goto error_out; 1256 } 1257 1258 switch (ep_cfg.bus.mipi_csi2.num_data_lanes) { 1259 case 2: 1260 imx678->lane_mode = IMX678_LANEMODE_2L; 1261 break; 1262 case 4: 1263 imx678->lane_mode = IMX678_LANEMODE_4L; 1264 break; 1265 default: 1266 dev_err(dev, 1267 "only 2 or 4 CSI2 data lanes are currently supported\n"); 1268 goto error_out; 1269 } 1270 1271 ret = v4l2_link_freq_to_bitmap(dev, ep_cfg.link_frequencies, 1272 ep_cfg.nr_of_link_frequencies, 1273 link_freqs, ARRAY_SIZE(link_freqs), 1274 &imx678->link_freq_bitmap); 1275 1276 error_out: 1277 v4l2_fwnode_endpoint_free(&ep_cfg); 1278 fwnode_handle_put(endpoint); 1279 1280 return ret; 1281 } 1282 1283 static int imx678_probe(struct i2c_client *client) 1284 { 1285 struct device *dev = &client->dev; 1286 struct imx678 *imx678; 1287 int ret, i; 1288 1289 imx678 = devm_kzalloc(&client->dev, sizeof(*imx678), GFP_KERNEL); 1290 if (!imx678) 1291 return -ENOMEM; 1292 1293 v4l2_i2c_subdev_init(&imx678->sd, client, &imx678_subdev_ops); 1294 1295 imx678->cci = devm_cci_regmap_init_i2c(client, 16); 1296 if (IS_ERR(imx678->cci)) 1297 return dev_err_probe(dev, PTR_ERR(imx678->cci), 1298 "failed to init CCI\n"); 1299 1300 if (imx678_check_hwcfg(dev, imx678)) 1301 return -EINVAL; 1302 1303 imx678->xclk = devm_v4l2_sensor_clk_get(dev, NULL); 1304 if (IS_ERR(imx678->xclk)) 1305 return dev_err_probe(dev, PTR_ERR(imx678->xclk), 1306 "failed to get xclk\n"); 1307 1308 imx678->xclk_freq = clk_get_rate(imx678->xclk); 1309 1310 for (i = 0; i < ARRAY_SIZE(imx678_inck_table); ++i) { 1311 if (imx678_inck_table[i].xclk_hz == imx678->xclk_freq) { 1312 imx678->inck_sel_val = imx678_inck_table[i].inck_sel; 1313 break; 1314 } 1315 } 1316 1317 if (i == ARRAY_SIZE(imx678_inck_table)) 1318 return dev_err_probe(dev, -EINVAL, 1319 "unsupported XCLK rate %u Hz\n", 1320 imx678->xclk_freq); 1321 1322 for (i = 0; i < ARRAY_SIZE(imx678_supply_name); i++) 1323 imx678->supplies[i].supply = imx678_supply_name[i]; 1324 1325 ret = devm_regulator_bulk_get(&client->dev, 1326 ARRAY_SIZE(imx678_supply_name), 1327 imx678->supplies); 1328 if (ret) 1329 return dev_err_probe(dev, ret, "failed to get regulators\n"); 1330 1331 imx678->reset_gpio = devm_gpiod_get_optional(dev, "reset", 1332 GPIOD_OUT_HIGH); 1333 if (IS_ERR(imx678->reset_gpio)) 1334 return dev_err_probe(dev, PTR_ERR(imx678->reset_gpio), 1335 "failed to get reset GPIO\n"); 1336 1337 ret = imx678_power_on(dev); 1338 if (ret) 1339 return ret; 1340 1341 ret = imx678_identify_model(imx678); 1342 if (ret) 1343 goto error_power_off; 1344 1345 pm_runtime_set_active(dev); 1346 pm_runtime_enable(dev); 1347 1348 ret = imx678_init_controls(imx678); 1349 if (ret) 1350 goto error_pm_runtime; 1351 1352 imx678->sd.internal_ops = &imx678_internal_ops; 1353 imx678->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1354 imx678->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 1355 1356 imx678->pad.flags = MEDIA_PAD_FL_SOURCE; 1357 1358 ret = media_entity_pads_init(&imx678->sd.entity, 1, &imx678->pad); 1359 if (ret) { 1360 dev_err_probe(dev, ret, "failed to init entity pads\n"); 1361 goto error_handler_free; 1362 } 1363 1364 imx678->sd.state_lock = imx678->ctrl_handler.lock; 1365 ret = v4l2_subdev_init_finalize(&imx678->sd); 1366 if (ret < 0) { 1367 dev_err_probe(dev, ret, "subdev init error\n"); 1368 goto error_media_entity; 1369 } 1370 1371 ret = v4l2_async_register_subdev_sensor(&imx678->sd); 1372 if (ret < 0) { 1373 dev_err_probe(dev, ret, 1374 "failed to register sensor sub-device\n"); 1375 goto error_subdev_cleanup; 1376 } 1377 1378 pm_runtime_idle(dev); 1379 1380 return 0; 1381 1382 error_subdev_cleanup: 1383 v4l2_subdev_cleanup(&imx678->sd); 1384 1385 error_media_entity: 1386 media_entity_cleanup(&imx678->sd.entity); 1387 1388 error_handler_free: 1389 v4l2_ctrl_handler_free(imx678->sd.ctrl_handler); 1390 1391 error_pm_runtime: 1392 pm_runtime_disable(&client->dev); 1393 pm_runtime_set_suspended(&client->dev); 1394 1395 error_power_off: 1396 imx678_power_off(&client->dev); 1397 1398 return ret; 1399 } 1400 1401 static void imx678_remove(struct i2c_client *client) 1402 { 1403 struct v4l2_subdev *sd = i2c_get_clientdata(client); 1404 struct imx678 *imx678 = to_imx678(sd); 1405 1406 v4l2_async_unregister_subdev(sd); 1407 v4l2_subdev_cleanup(sd); 1408 media_entity_cleanup(&sd->entity); 1409 v4l2_ctrl_handler_free(imx678->sd.ctrl_handler); 1410 1411 pm_runtime_disable(&client->dev); 1412 if (!pm_runtime_status_suspended(&client->dev)) 1413 imx678_power_off(&client->dev); 1414 pm_runtime_set_suspended(&client->dev); 1415 } 1416 1417 static const struct dev_pm_ops imx678_pm_ops = { 1418 SET_RUNTIME_PM_OPS(imx678_power_off, imx678_power_on, NULL) 1419 }; 1420 1421 static const struct of_device_id imx678_of_match[] = { 1422 { .compatible = "sony,imx678-aamr", .data = &imx678_aamr_info }, 1423 { .compatible = "sony,imx678-aaqr", .data = &imx678_aaqr_info }, 1424 /* for non-conforming DTs that rely on runtime check */ 1425 { .compatible = "sony,imx678" }, 1426 { /* sentinel */ } 1427 }; 1428 1429 MODULE_DEVICE_TABLE(of, imx678_of_match); 1430 1431 static struct i2c_driver imx678_i2c_driver = { 1432 .driver = { 1433 .name = "imx678", 1434 .of_match_table = imx678_of_match, 1435 .pm = pm_ptr(&imx678_pm_ops), 1436 }, 1437 .probe = imx678_probe, 1438 .remove = imx678_remove, 1439 }; 1440 1441 module_i2c_driver(imx678_i2c_driver); 1442 1443 MODULE_AUTHOR("Will Whang <will@willwhang.com>"); 1444 MODULE_AUTHOR("Tetsuya NOMURA <tetsuya.nomura@soho-enterprise.com>"); 1445 MODULE_AUTHOR("Jai Luthra <jai.luthra@ideasonboard.com>"); 1446 MODULE_DESCRIPTION("Sony imx678 sensor driver"); 1447 MODULE_LICENSE("GPL"); 1448