2834 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2017 Intel Corporation.3 4#include <linux/unaligned.h>5#include <linux/acpi.h>6#include <linux/clk.h>7#include <linux/delay.h>8#include <linux/gpio/consumer.h>9#include <linux/i2c.h>10#include <linux/mod_devicetable.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/pm_runtime.h>14#include <linux/regulator/consumer.h>15#include <media/v4l2-ctrls.h>16#include <media/v4l2-device.h>17#include <media/v4l2-event.h>18#include <media/v4l2-fwnode.h>19 20#define OV5670_XVCLK_FREQ 1920000021 22#define OV5670_REG_CHIP_ID 0x300a23#define OV5670_CHIP_ID 0x00567024 25#define OV5670_REG_MODE_SELECT 0x010026#define OV5670_MODE_STANDBY 0x0027#define OV5670_MODE_STREAMING 0x0128 29#define OV5670_REG_SOFTWARE_RST 0x010330#define OV5670_SOFTWARE_RST 0x0131 32#define OV5670_MIPI_SC_CTRL0_REG 0x301833#define OV5670_MIPI_SC_CTRL0_LANES(v) ((((v) - 1) << 5) & \34 GENMASK(7, 5))35#define OV5670_MIPI_SC_CTRL0_MIPI_EN BIT(4)36#define OV5670_MIPI_SC_CTRL0_RESERVED BIT(1)37 38/* vertical-timings from sensor */39#define OV5670_REG_VTS 0x380e40#define OV5670_VTS_30FPS 0x0808 /* default for 30 fps */41#define OV5670_VTS_MAX 0xffff42 43/* horizontal-timings from sensor */44#define OV5670_REG_HTS 0x380c45 46/*47 * Pixels-per-line(PPL) = Time-per-line * pixel-rate48 * In OV5670, Time-per-line = HTS/SCLK.49 * HTS is fixed for all resolutions, not recommended to change.50 */51#define OV5670_FIXED_PPL 2724 /* Pixels per line */52 53/* Exposure controls from sensor */54#define OV5670_REG_EXPOSURE 0x350055#define OV5670_EXPOSURE_MIN 456#define OV5670_EXPOSURE_STEP 157 58/* Analog gain controls from sensor */59#define OV5670_REG_ANALOG_GAIN 0x350860#define ANALOG_GAIN_MIN 061#define ANALOG_GAIN_MAX 819162#define ANALOG_GAIN_STEP 163#define ANALOG_GAIN_DEFAULT 12864 65/* Digital gain controls from sensor */66#define OV5670_REG_R_DGTL_GAIN 0x503267#define OV5670_REG_G_DGTL_GAIN 0x503468#define OV5670_REG_B_DGTL_GAIN 0x503669#define OV5670_DGTL_GAIN_MIN 070#define OV5670_DGTL_GAIN_MAX 409571#define OV5670_DGTL_GAIN_STEP 172#define OV5670_DGTL_GAIN_DEFAULT 102473 74/* Test Pattern Control */75#define OV5670_REG_TEST_PATTERN 0x430376#define OV5670_TEST_PATTERN_ENABLE BIT(3)77#define OV5670_REG_TEST_PATTERN_CTRL 0x432078 79#define OV5670_REG_VALUE_08BIT 180#define OV5670_REG_VALUE_16BIT 281#define OV5670_REG_VALUE_24BIT 382 83/* Pixel Array */84#define OV5670_NATIVE_WIDTH 262485#define OV5670_NATIVE_HEIGHT 198086 87/* Initial number of frames to skip to avoid possible garbage */88#define OV5670_NUM_OF_SKIP_FRAMES 289 90struct ov5670_reg {91 u16 address;92 u8 val;93};94 95struct ov5670_reg_list {96 u32 num_of_regs;97 const struct ov5670_reg *regs;98};99 100struct ov5670_link_freq_config {101 const struct ov5670_reg_list reg_list;102};103 104static const char * const ov5670_supply_names[] = {105 "avdd", /* Analog power */106 "dvdd", /* Digital power */107 "dovdd", /* Digital output power */108};109 110#define OV5670_NUM_SUPPLIES ARRAY_SIZE(ov5670_supply_names)111 112struct ov5670_mode {113 /* Frame width in pixels */114 u32 width;115 116 /* Frame height in pixels */117 u32 height;118 119 /* Default vertical timining size */120 u32 vts_def;121 122 /* Min vertical timining size */123 u32 vts_min;124 125 /* Link frequency needed for this resolution */126 u32 link_freq_index;127 128 /* Analog crop rectangle */129 const struct v4l2_rect *analog_crop;130 131 /* Sensor register settings for this resolution */132 const struct ov5670_reg_list reg_list;133};134 135/*136 * All the modes supported by the driver are obtained by subsampling the137 * full pixel array. The below values are reflected in registers from138 * 0x3800-0x3807 in the modes register-value tables.139 */140static const struct v4l2_rect ov5670_analog_crop = {141 .left = 12,142 .top = 4,143 .width = 2600,144 .height = 1952,145};146 147static const struct ov5670_reg mipi_data_rate_840mbps[] = {148 {0x0300, 0x04},149 {0x0301, 0x00},150 {0x0302, 0x84},151 {0x0303, 0x00},152 {0x0304, 0x03},153 {0x0305, 0x01},154 {0x0306, 0x01},155 {0x030a, 0x00},156 {0x030b, 0x00},157 {0x030c, 0x00},158 {0x030d, 0x26},159 {0x030e, 0x00},160 {0x030f, 0x06},161 {0x0312, 0x01},162 {0x3031, 0x0a},163};164 165static const struct ov5670_reg mode_2592x1944_regs[] = {166 {0x3000, 0x00},167 {0x3002, 0x21},168 {0x3005, 0xf0},169 {0x3007, 0x00},170 {0x3015, 0x0f},171 {0x301a, 0xf0},172 {0x301b, 0xf0},173 {0x301c, 0xf0},174 {0x301d, 0xf0},175 {0x301e, 0xf0},176 {0x3030, 0x00},177 {0x3031, 0x0a},178 {0x303c, 0xff},179 {0x303e, 0xff},180 {0x3040, 0xf0},181 {0x3041, 0x00},182 {0x3042, 0xf0},183 {0x3106, 0x11},184 {0x3500, 0x00},185 {0x3501, 0x80},186 {0x3502, 0x00},187 {0x3503, 0x04},188 {0x3504, 0x03},189 {0x3505, 0x83},190 {0x3508, 0x04},191 {0x3509, 0x00},192 {0x350e, 0x04},193 {0x350f, 0x00},194 {0x3510, 0x00},195 {0x3511, 0x02},196 {0x3512, 0x00},197 {0x3601, 0xc8},198 {0x3610, 0x88},199 {0x3612, 0x48},200 {0x3614, 0x5b},201 {0x3615, 0x96},202 {0x3621, 0xd0},203 {0x3622, 0x00},204 {0x3623, 0x00},205 {0x3633, 0x13},206 {0x3634, 0x13},207 {0x3635, 0x13},208 {0x3636, 0x13},209 {0x3645, 0x13},210 {0x3646, 0x82},211 {0x3650, 0x00},212 {0x3652, 0xff},213 {0x3655, 0x20},214 {0x3656, 0xff},215 {0x365a, 0xff},216 {0x365e, 0xff},217 {0x3668, 0x00},218 {0x366a, 0x07},219 {0x366e, 0x10},220 {0x366d, 0x00},221 {0x366f, 0x80},222 {0x3700, 0x28},223 {0x3701, 0x10},224 {0x3702, 0x3a},225 {0x3703, 0x19},226 {0x3704, 0x10},227 {0x3705, 0x00},228 {0x3706, 0x66},229 {0x3707, 0x08},230 {0x3708, 0x34},231 {0x3709, 0x40},232 {0x370a, 0x01},233 {0x370b, 0x1b},234 {0x3714, 0x24},235 {0x371a, 0x3e},236 {0x3733, 0x00},237 {0x3734, 0x00},238 {0x373a, 0x05},239 {0x373b, 0x06},240 {0x373c, 0x0a},241 {0x373f, 0xa0},242 {0x3755, 0x00},243 {0x3758, 0x00},244 {0x375b, 0x0e},245 {0x3766, 0x5f},246 {0x3768, 0x00},247 {0x3769, 0x22},248 {0x3773, 0x08},249 {0x3774, 0x1f},250 {0x3776, 0x06},251 {0x37a0, 0x88},252 {0x37a1, 0x5c},253 {0x37a7, 0x88},254 {0x37a8, 0x70},255 {0x37aa, 0x88},256 {0x37ab, 0x48},257 {0x37b3, 0x66},258 {0x37c2, 0x04},259 {0x37c5, 0x00},260 {0x37c8, 0x00},261 {0x3800, 0x00},262 {0x3801, 0x0c},263 {0x3802, 0x00},264 {0x3803, 0x04},265 {0x3804, 0x0a},266 {0x3805, 0x33},267 {0x3806, 0x07},268 {0x3807, 0xa3},269 {0x3808, 0x0a},270 {0x3809, 0x20},271 {0x380a, 0x07},272 {0x380b, 0x98},273 {0x380c, 0x06},274 {0x380d, 0x90},275 {0x380e, 0x08},276 {0x380f, 0x08},277 {0x3811, 0x04},278 {0x3813, 0x02},279 {0x3814, 0x01},280 {0x3815, 0x01},281 {0x3816, 0x00},282 {0x3817, 0x00},283 {0x3818, 0x00},284 {0x3819, 0x00},285 {0x3820, 0x84},286 {0x3821, 0x46},287 {0x3822, 0x48},288 {0x3826, 0x00},289 {0x3827, 0x08},290 {0x382a, 0x01},291 {0x382b, 0x01},292 {0x3830, 0x08},293 {0x3836, 0x02},294 {0x3837, 0x00},295 {0x3838, 0x10},296 {0x3841, 0xff},297 {0x3846, 0x48},298 {0x3861, 0x00},299 {0x3862, 0x04},300 {0x3863, 0x06},301 {0x3a11, 0x01},302 {0x3a12, 0x78},303 {0x3b00, 0x00},304 {0x3b02, 0x00},305 {0x3b03, 0x00},306 {0x3b04, 0x00},307 {0x3b05, 0x00},308 {0x3c00, 0x89},309 {0x3c01, 0xab},310 {0x3c02, 0x01},311 {0x3c03, 0x00},312 {0x3c04, 0x00},313 {0x3c05, 0x03},314 {0x3c06, 0x00},315 {0x3c07, 0x05},316 {0x3c0c, 0x00},317 {0x3c0d, 0x00},318 {0x3c0e, 0x00},319 {0x3c0f, 0x00},320 {0x3c40, 0x00},321 {0x3c41, 0xa3},322 {0x3c43, 0x7d},323 {0x3c45, 0xd7},324 {0x3c47, 0xfc},325 {0x3c50, 0x05},326 {0x3c52, 0xaa},327 {0x3c54, 0x71},328 {0x3c56, 0x80},329 {0x3d85, 0x17},330 {0x3f03, 0x00},331 {0x3f0a, 0x00},332 {0x3f0b, 0x00},333 {0x4001, 0x60},334 {0x4009, 0x0d},335 {0x4020, 0x00},336 {0x4021, 0x00},337 {0x4022, 0x00},338 {0x4023, 0x00},339 {0x4024, 0x00},340 {0x4025, 0x00},341 {0x4026, 0x00},342 {0x4027, 0x00},343 {0x4028, 0x00},344 {0x4029, 0x00},345 {0x402a, 0x00},346 {0x402b, 0x00},347 {0x402c, 0x00},348 {0x402d, 0x00},349 {0x402e, 0x00},350 {0x402f, 0x00},351 {0x4040, 0x00},352 {0x4041, 0x03},353 {0x4042, 0x00},354 {0x4043, 0x7A},355 {0x4044, 0x00},356 {0x4045, 0x7A},357 {0x4046, 0x00},358 {0x4047, 0x7A},359 {0x4048, 0x00},360 {0x4049, 0x7A},361 {0x4307, 0x30},362 {0x4500, 0x58},363 {0x4501, 0x04},364 {0x4502, 0x40},365 {0x4503, 0x10},366 {0x4508, 0xaa},367 {0x4509, 0xaa},368 {0x450a, 0x00},369 {0x450b, 0x00},370 {0x4600, 0x01},371 {0x4601, 0x03},372 {0x4700, 0xa4},373 {0x4800, 0x4c},374 {0x4816, 0x53},375 {0x481f, 0x40},376 {0x4837, 0x13},377 {0x5000, 0x56},378 {0x5001, 0x01},379 {0x5002, 0x28},380 {0x5004, 0x0c},381 {0x5006, 0x0c},382 {0x5007, 0xe0},383 {0x5008, 0x01},384 {0x5009, 0xb0},385 {0x5901, 0x00},386 {0x5a01, 0x00},387 {0x5a03, 0x00},388 {0x5a04, 0x0c},389 {0x5a05, 0xe0},390 {0x5a06, 0x09},391 {0x5a07, 0xb0},392 {0x5a08, 0x06},393 {0x5e00, 0x00},394 {0x3734, 0x40},395 {0x5b00, 0x01},396 {0x5b01, 0x10},397 {0x5b02, 0x01},398 {0x5b03, 0xdb},399 {0x3d8c, 0x71},400 {0x3d8d, 0xea},401 {0x4017, 0x08},402 {0x3618, 0x2a},403 {0x5780, 0x3e},404 {0x5781, 0x0f},405 {0x5782, 0x44},406 {0x5783, 0x02},407 {0x5784, 0x01},408 {0x5785, 0x01},409 {0x5786, 0x00},410 {0x5787, 0x04},411 {0x5788, 0x02},412 {0x5789, 0x0f},413 {0x578a, 0xfd},414 {0x578b, 0xf5},415 {0x578c, 0xf5},416 {0x578d, 0x03},417 {0x578e, 0x08},418 {0x578f, 0x0c},419 {0x5790, 0x08},420 {0x5791, 0x06},421 {0x5792, 0x00},422 {0x5793, 0x52},423 {0x5794, 0xa3},424 {0x3503, 0x00},425 {0x5045, 0x05},426 {0x4003, 0x40},427 {0x5048, 0x40}428};429 430static const struct ov5670_reg mode_1296x972_regs[] = {431 {0x3000, 0x00},432 {0x3002, 0x21},433 {0x3005, 0xf0},434 {0x3007, 0x00},435 {0x3015, 0x0f},436 {0x301a, 0xf0},437 {0x301b, 0xf0},438 {0x301c, 0xf0},439 {0x301d, 0xf0},440 {0x301e, 0xf0},441 {0x3030, 0x00},442 {0x3031, 0x0a},443 {0x303c, 0xff},444 {0x303e, 0xff},445 {0x3040, 0xf0},446 {0x3041, 0x00},447 {0x3042, 0xf0},448 {0x3106, 0x11},449 {0x3500, 0x00},450 {0x3501, 0x80},451 {0x3502, 0x00},452 {0x3503, 0x04},453 {0x3504, 0x03},454 {0x3505, 0x83},455 {0x3508, 0x07},456 {0x3509, 0x80},457 {0x350e, 0x04},458 {0x350f, 0x00},459 {0x3510, 0x00},460 {0x3511, 0x02},461 {0x3512, 0x00},462 {0x3601, 0xc8},463 {0x3610, 0x88},464 {0x3612, 0x48},465 {0x3614, 0x5b},466 {0x3615, 0x96},467 {0x3621, 0xd0},468 {0x3622, 0x00},469 {0x3623, 0x00},470 {0x3633, 0x13},471 {0x3634, 0x13},472 {0x3635, 0x13},473 {0x3636, 0x13},474 {0x3645, 0x13},475 {0x3646, 0x82},476 {0x3650, 0x00},477 {0x3652, 0xff},478 {0x3655, 0x20},479 {0x3656, 0xff},480 {0x365a, 0xff},481 {0x365e, 0xff},482 {0x3668, 0x00},483 {0x366a, 0x07},484 {0x366e, 0x08},485 {0x366d, 0x00},486 {0x366f, 0x80},487 {0x3700, 0x28},488 {0x3701, 0x10},489 {0x3702, 0x3a},490 {0x3703, 0x19},491 {0x3704, 0x10},492 {0x3705, 0x00},493 {0x3706, 0x66},494 {0x3707, 0x08},495 {0x3708, 0x34},496 {0x3709, 0x40},497 {0x370a, 0x01},498 {0x370b, 0x1b},499 {0x3714, 0x24},500 {0x371a, 0x3e},501 {0x3733, 0x00},502 {0x3734, 0x00},503 {0x373a, 0x05},504 {0x373b, 0x06},505 {0x373c, 0x0a},506 {0x373f, 0xa0},507 {0x3755, 0x00},508 {0x3758, 0x00},509 {0x375b, 0x0e},510 {0x3766, 0x5f},511 {0x3768, 0x00},512 {0x3769, 0x22},513 {0x3773, 0x08},514 {0x3774, 0x1f},515 {0x3776, 0x06},516 {0x37a0, 0x88},517 {0x37a1, 0x5c},518 {0x37a7, 0x88},519 {0x37a8, 0x70},520 {0x37aa, 0x88},521 {0x37ab, 0x48},522 {0x37b3, 0x66},523 {0x37c2, 0x04},524 {0x37c5, 0x00},525 {0x37c8, 0x00},526 {0x3800, 0x00},527 {0x3801, 0x0c},528 {0x3802, 0x00},529 {0x3803, 0x04},530 {0x3804, 0x0a},531 {0x3805, 0x33},532 {0x3806, 0x07},533 {0x3807, 0xa3},534 {0x3808, 0x05},535 {0x3809, 0x10},536 {0x380a, 0x03},537 {0x380b, 0xcc},538 {0x380c, 0x06},539 {0x380d, 0x90},540 {0x380e, 0x08},541 {0x380f, 0x08},542 {0x3811, 0x04},543 {0x3813, 0x04},544 {0x3814, 0x03},545 {0x3815, 0x01},546 {0x3816, 0x00},547 {0x3817, 0x00},548 {0x3818, 0x00},549 {0x3819, 0x00},550 {0x3820, 0x94},551 {0x3821, 0x47},552 {0x3822, 0x48},553 {0x3826, 0x00},554 {0x3827, 0x08},555 {0x382a, 0x03},556 {0x382b, 0x01},557 {0x3830, 0x08},558 {0x3836, 0x02},559 {0x3837, 0x00},560 {0x3838, 0x10},561 {0x3841, 0xff},562 {0x3846, 0x48},563 {0x3861, 0x00},564 {0x3862, 0x04},565 {0x3863, 0x06},566 {0x3a11, 0x01},567 {0x3a12, 0x78},568 {0x3b00, 0x00},569 {0x3b02, 0x00},570 {0x3b03, 0x00},571 {0x3b04, 0x00},572 {0x3b05, 0x00},573 {0x3c00, 0x89},574 {0x3c01, 0xab},575 {0x3c02, 0x01},576 {0x3c03, 0x00},577 {0x3c04, 0x00},578 {0x3c05, 0x03},579 {0x3c06, 0x00},580 {0x3c07, 0x05},581 {0x3c0c, 0x00},582 {0x3c0d, 0x00},583 {0x3c0e, 0x00},584 {0x3c0f, 0x00},585 {0x3c40, 0x00},586 {0x3c41, 0xa3},587 {0x3c43, 0x7d},588 {0x3c45, 0xd7},589 {0x3c47, 0xfc},590 {0x3c50, 0x05},591 {0x3c52, 0xaa},592 {0x3c54, 0x71},593 {0x3c56, 0x80},594 {0x3d85, 0x17},595 {0x3f03, 0x00},596 {0x3f0a, 0x00},597 {0x3f0b, 0x00},598 {0x4001, 0x60},599 {0x4009, 0x05},600 {0x4020, 0x00},601 {0x4021, 0x00},602 {0x4022, 0x00},603 {0x4023, 0x00},604 {0x4024, 0x00},605 {0x4025, 0x00},606 {0x4026, 0x00},607 {0x4027, 0x00},608 {0x4028, 0x00},609 {0x4029, 0x00},610 {0x402a, 0x00},611 {0x402b, 0x00},612 {0x402c, 0x00},613 {0x402d, 0x00},614 {0x402e, 0x00},615 {0x402f, 0x00},616 {0x4040, 0x00},617 {0x4041, 0x03},618 {0x4042, 0x00},619 {0x4043, 0x7A},620 {0x4044, 0x00},621 {0x4045, 0x7A},622 {0x4046, 0x00},623 {0x4047, 0x7A},624 {0x4048, 0x00},625 {0x4049, 0x7A},626 {0x4307, 0x30},627 {0x4500, 0x58},628 {0x4501, 0x04},629 {0x4502, 0x48},630 {0x4503, 0x10},631 {0x4508, 0x55},632 {0x4509, 0x55},633 {0x450a, 0x00},634 {0x450b, 0x00},635 {0x4600, 0x00},636 {0x4601, 0x81},637 {0x4700, 0xa4},638 {0x4800, 0x4c},639 {0x4816, 0x53},640 {0x481f, 0x40},641 {0x4837, 0x13},642 {0x5000, 0x56},643 {0x5001, 0x01},644 {0x5002, 0x28},645 {0x5004, 0x0c},646 {0x5006, 0x0c},647 {0x5007, 0xe0},648 {0x5008, 0x01},649 {0x5009, 0xb0},650 {0x5901, 0x00},651 {0x5a01, 0x00},652 {0x5a03, 0x00},653 {0x5a04, 0x0c},654 {0x5a05, 0xe0},655 {0x5a06, 0x09},656 {0x5a07, 0xb0},657 {0x5a08, 0x06},658 {0x5e00, 0x00},659 {0x3734, 0x40},660 {0x5b00, 0x01},661 {0x5b01, 0x10},662 {0x5b02, 0x01},663 {0x5b03, 0xdb},664 {0x3d8c, 0x71},665 {0x3d8d, 0xea},666 {0x4017, 0x10},667 {0x3618, 0x2a},668 {0x5780, 0x3e},669 {0x5781, 0x0f},670 {0x5782, 0x44},671 {0x5783, 0x02},672 {0x5784, 0x01},673 {0x5785, 0x01},674 {0x5786, 0x00},675 {0x5787, 0x04},676 {0x5788, 0x02},677 {0x5789, 0x0f},678 {0x578a, 0xfd},679 {0x578b, 0xf5},680 {0x578c, 0xf5},681 {0x578d, 0x03},682 {0x578e, 0x08},683 {0x578f, 0x0c},684 {0x5790, 0x08},685 {0x5791, 0x04},686 {0x5792, 0x00},687 {0x5793, 0x52},688 {0x5794, 0xa3},689 {0x3503, 0x00},690 {0x5045, 0x05},691 {0x4003, 0x40},692 {0x5048, 0x40}693};694 695static const struct ov5670_reg mode_648x486_regs[] = {696 {0x3000, 0x00},697 {0x3002, 0x21},698 {0x3005, 0xf0},699 {0x3007, 0x00},700 {0x3015, 0x0f},701 {0x301a, 0xf0},702 {0x301b, 0xf0},703 {0x301c, 0xf0},704 {0x301d, 0xf0},705 {0x301e, 0xf0},706 {0x3030, 0x00},707 {0x3031, 0x0a},708 {0x303c, 0xff},709 {0x303e, 0xff},710 {0x3040, 0xf0},711 {0x3041, 0x00},712 {0x3042, 0xf0},713 {0x3106, 0x11},714 {0x3500, 0x00},715 {0x3501, 0x80},716 {0x3502, 0x00},717 {0x3503, 0x04},718 {0x3504, 0x03},719 {0x3505, 0x83},720 {0x3508, 0x04},721 {0x3509, 0x00},722 {0x350e, 0x04},723 {0x350f, 0x00},724 {0x3510, 0x00},725 {0x3511, 0x02},726 {0x3512, 0x00},727 {0x3601, 0xc8},728 {0x3610, 0x88},729 {0x3612, 0x48},730 {0x3614, 0x5b},731 {0x3615, 0x96},732 {0x3621, 0xd0},733 {0x3622, 0x00},734 {0x3623, 0x04},735 {0x3633, 0x13},736 {0x3634, 0x13},737 {0x3635, 0x13},738 {0x3636, 0x13},739 {0x3645, 0x13},740 {0x3646, 0x82},741 {0x3650, 0x00},742 {0x3652, 0xff},743 {0x3655, 0x20},744 {0x3656, 0xff},745 {0x365a, 0xff},746 {0x365e, 0xff},747 {0x3668, 0x00},748 {0x366a, 0x07},749 {0x366e, 0x08},750 {0x366d, 0x00},751 {0x366f, 0x80},752 {0x3700, 0x28},753 {0x3701, 0x10},754 {0x3702, 0x3a},755 {0x3703, 0x19},756 {0x3704, 0x10},757 {0x3705, 0x00},758 {0x3706, 0x66},759 {0x3707, 0x08},760 {0x3708, 0x34},761 {0x3709, 0x40},762 {0x370a, 0x01},763 {0x370b, 0x1b},764 {0x3714, 0x24},765 {0x371a, 0x3e},766 {0x3733, 0x00},767 {0x3734, 0x00},768 {0x373a, 0x05},769 {0x373b, 0x06},770 {0x373c, 0x0a},771 {0x373f, 0xa0},772 {0x3755, 0x00},773 {0x3758, 0x00},774 {0x375b, 0x0e},775 {0x3766, 0x5f},776 {0x3768, 0x00},777 {0x3769, 0x22},778 {0x3773, 0x08},779 {0x3774, 0x1f},780 {0x3776, 0x06},781 {0x37a0, 0x88},782 {0x37a1, 0x5c},783 {0x37a7, 0x88},784 {0x37a8, 0x70},785 {0x37aa, 0x88},786 {0x37ab, 0x48},787 {0x37b3, 0x66},788 {0x37c2, 0x04},789 {0x37c5, 0x00},790 {0x37c8, 0x00},791 {0x3800, 0x00},792 {0x3801, 0x0c},793 {0x3802, 0x00},794 {0x3803, 0x04},795 {0x3804, 0x0a},796 {0x3805, 0x33},797 {0x3806, 0x07},798 {0x3807, 0xa3},799 {0x3808, 0x02},800 {0x3809, 0x88},801 {0x380a, 0x01},802 {0x380b, 0xe6},803 {0x380c, 0x06},804 {0x380d, 0x90},805 {0x380e, 0x08},806 {0x380f, 0x08},807 {0x3811, 0x04},808 {0x3813, 0x02},809 {0x3814, 0x07},810 {0x3815, 0x01},811 {0x3816, 0x00},812 {0x3817, 0x00},813 {0x3818, 0x00},814 {0x3819, 0x00},815 {0x3820, 0x94},816 {0x3821, 0xc6},817 {0x3822, 0x48},818 {0x3826, 0x00},819 {0x3827, 0x08},820 {0x382a, 0x07},821 {0x382b, 0x01},822 {0x3830, 0x08},823 {0x3836, 0x02},824 {0x3837, 0x00},825 {0x3838, 0x10},826 {0x3841, 0xff},827 {0x3846, 0x48},828 {0x3861, 0x00},829 {0x3862, 0x04},830 {0x3863, 0x06},831 {0x3a11, 0x01},832 {0x3a12, 0x78},833 {0x3b00, 0x00},834 {0x3b02, 0x00},835 {0x3b03, 0x00},836 {0x3b04, 0x00},837 {0x3b05, 0x00},838 {0x3c00, 0x89},839 {0x3c01, 0xab},840 {0x3c02, 0x01},841 {0x3c03, 0x00},842 {0x3c04, 0x00},843 {0x3c05, 0x03},844 {0x3c06, 0x00},845 {0x3c07, 0x05},846 {0x3c0c, 0x00},847 {0x3c0d, 0x00},848 {0x3c0e, 0x00},849 {0x3c0f, 0x00},850 {0x3c40, 0x00},851 {0x3c41, 0xa3},852 {0x3c43, 0x7d},853 {0x3c45, 0xd7},854 {0x3c47, 0xfc},855 {0x3c50, 0x05},856 {0x3c52, 0xaa},857 {0x3c54, 0x71},858 {0x3c56, 0x80},859 {0x3d85, 0x17},860 {0x3f03, 0x00},861 {0x3f0a, 0x00},862 {0x3f0b, 0x00},863 {0x4001, 0x60},864 {0x4009, 0x05},865 {0x4020, 0x00},866 {0x4021, 0x00},867 {0x4022, 0x00},868 {0x4023, 0x00},869 {0x4024, 0x00},870 {0x4025, 0x00},871 {0x4026, 0x00},872 {0x4027, 0x00},873 {0x4028, 0x00},874 {0x4029, 0x00},875 {0x402a, 0x00},876 {0x402b, 0x00},877 {0x402c, 0x00},878 {0x402d, 0x00},879 {0x402e, 0x00},880 {0x402f, 0x00},881 {0x4040, 0x00},882 {0x4041, 0x03},883 {0x4042, 0x00},884 {0x4043, 0x7A},885 {0x4044, 0x00},886 {0x4045, 0x7A},887 {0x4046, 0x00},888 {0x4047, 0x7A},889 {0x4048, 0x00},890 {0x4049, 0x7A},891 {0x4307, 0x30},892 {0x4500, 0x58},893 {0x4501, 0x04},894 {0x4502, 0x40},895 {0x4503, 0x10},896 {0x4508, 0x55},897 {0x4509, 0x55},898 {0x450a, 0x02},899 {0x450b, 0x00},900 {0x4600, 0x00},901 {0x4601, 0x40},902 {0x4700, 0xa4},903 {0x4800, 0x4c},904 {0x4816, 0x53},905 {0x481f, 0x40},906 {0x4837, 0x13},907 {0x5000, 0x56},908 {0x5001, 0x01},909 {0x5002, 0x28},910 {0x5004, 0x0c},911 {0x5006, 0x0c},912 {0x5007, 0xe0},913 {0x5008, 0x01},914 {0x5009, 0xb0},915 {0x5901, 0x00},916 {0x5a01, 0x00},917 {0x5a03, 0x00},918 {0x5a04, 0x0c},919 {0x5a05, 0xe0},920 {0x5a06, 0x09},921 {0x5a07, 0xb0},922 {0x5a08, 0x06},923 {0x5e00, 0x00},924 {0x3734, 0x40},925 {0x5b00, 0x01},926 {0x5b01, 0x10},927 {0x5b02, 0x01},928 {0x5b03, 0xdb},929 {0x3d8c, 0x71},930 {0x3d8d, 0xea},931 {0x4017, 0x10},932 {0x3618, 0x2a},933 {0x5780, 0x3e},934 {0x5781, 0x0f},935 {0x5782, 0x44},936 {0x5783, 0x02},937 {0x5784, 0x01},938 {0x5785, 0x01},939 {0x5786, 0x00},940 {0x5787, 0x04},941 {0x5788, 0x02},942 {0x5789, 0x0f},943 {0x578a, 0xfd},944 {0x578b, 0xf5},945 {0x578c, 0xf5},946 {0x578d, 0x03},947 {0x578e, 0x08},948 {0x578f, 0x0c},949 {0x5790, 0x08},950 {0x5791, 0x06},951 {0x5792, 0x00},952 {0x5793, 0x52},953 {0x5794, 0xa3},954 {0x3503, 0x00},955 {0x5045, 0x05},956 {0x4003, 0x40},957 {0x5048, 0x40}958};959 960static const struct ov5670_reg mode_2560x1440_regs[] = {961 {0x3000, 0x00},962 {0x3002, 0x21},963 {0x3005, 0xf0},964 {0x3007, 0x00},965 {0x3015, 0x0f},966 {0x301a, 0xf0},967 {0x301b, 0xf0},968 {0x301c, 0xf0},969 {0x301d, 0xf0},970 {0x301e, 0xf0},971 {0x3030, 0x00},972 {0x3031, 0x0a},973 {0x303c, 0xff},974 {0x303e, 0xff},975 {0x3040, 0xf0},976 {0x3041, 0x00},977 {0x3042, 0xf0},978 {0x3106, 0x11},979 {0x3500, 0x00},980 {0x3501, 0x80},981 {0x3502, 0x00},982 {0x3503, 0x04},983 {0x3504, 0x03},984 {0x3505, 0x83},985 {0x3508, 0x04},986 {0x3509, 0x00},987 {0x350e, 0x04},988 {0x350f, 0x00},989 {0x3510, 0x00},990 {0x3511, 0x02},991 {0x3512, 0x00},992 {0x3601, 0xc8},993 {0x3610, 0x88},994 {0x3612, 0x48},995 {0x3614, 0x5b},996 {0x3615, 0x96},997 {0x3621, 0xd0},998 {0x3622, 0x00},999 {0x3623, 0x00},1000 {0x3633, 0x13},1001 {0x3634, 0x13},1002 {0x3635, 0x13},1003 {0x3636, 0x13},1004 {0x3645, 0x13},1005 {0x3646, 0x82},1006 {0x3650, 0x00},1007 {0x3652, 0xff},1008 {0x3655, 0x20},1009 {0x3656, 0xff},1010 {0x365a, 0xff},1011 {0x365e, 0xff},1012 {0x3668, 0x00},1013 {0x366a, 0x07},1014 {0x366e, 0x10},1015 {0x366d, 0x00},1016 {0x366f, 0x80},1017 {0x3700, 0x28},1018 {0x3701, 0x10},1019 {0x3702, 0x3a},1020 {0x3703, 0x19},1021 {0x3704, 0x10},1022 {0x3705, 0x00},1023 {0x3706, 0x66},1024 {0x3707, 0x08},1025 {0x3708, 0x34},1026 {0x3709, 0x40},1027 {0x370a, 0x01},1028 {0x370b, 0x1b},1029 {0x3714, 0x24},1030 {0x371a, 0x3e},1031 {0x3733, 0x00},1032 {0x3734, 0x00},1033 {0x373a, 0x05},1034 {0x373b, 0x06},1035 {0x373c, 0x0a},1036 {0x373f, 0xa0},1037 {0x3755, 0x00},1038 {0x3758, 0x00},1039 {0x375b, 0x0e},1040 {0x3766, 0x5f},1041 {0x3768, 0x00},1042 {0x3769, 0x22},1043 {0x3773, 0x08},1044 {0x3774, 0x1f},1045 {0x3776, 0x06},1046 {0x37a0, 0x88},1047 {0x37a1, 0x5c},1048 {0x37a7, 0x88},1049 {0x37a8, 0x70},1050 {0x37aa, 0x88},1051 {0x37ab, 0x48},1052 {0x37b3, 0x66},1053 {0x37c2, 0x04},1054 {0x37c5, 0x00},1055 {0x37c8, 0x00},1056 {0x3800, 0x00},1057 {0x3801, 0x0c},1058 {0x3802, 0x00},1059 {0x3803, 0x04},1060 {0x3804, 0x0a},1061 {0x3805, 0x33},1062 {0x3806, 0x07},1063 {0x3807, 0xa3},1064 {0x3808, 0x0a},1065 {0x3809, 0x00},1066 {0x380a, 0x05},1067 {0x380b, 0xa0},1068 {0x380c, 0x06},1069 {0x380d, 0x90},1070 {0x380e, 0x08},1071 {0x380f, 0x08},1072 {0x3811, 0x04},1073 {0x3813, 0x02},1074 {0x3814, 0x01},1075 {0x3815, 0x01},1076 {0x3816, 0x00},1077 {0x3817, 0x00},1078 {0x3818, 0x00},1079 {0x3819, 0x00},1080 {0x3820, 0x84},1081 {0x3821, 0x46},1082 {0x3822, 0x48},1083 {0x3826, 0x00},1084 {0x3827, 0x08},1085 {0x382a, 0x01},1086 {0x382b, 0x01},1087 {0x3830, 0x08},1088 {0x3836, 0x02},1089 {0x3837, 0x00},1090 {0x3838, 0x10},1091 {0x3841, 0xff},1092 {0x3846, 0x48},1093 {0x3861, 0x00},1094 {0x3862, 0x04},1095 {0x3863, 0x06},1096 {0x3a11, 0x01},1097 {0x3a12, 0x78},1098 {0x3b00, 0x00},1099 {0x3b02, 0x00},1100 {0x3b03, 0x00},1101 {0x3b04, 0x00},1102 {0x3b05, 0x00},1103 {0x3c00, 0x89},1104 {0x3c01, 0xab},1105 {0x3c02, 0x01},1106 {0x3c03, 0x00},1107 {0x3c04, 0x00},1108 {0x3c05, 0x03},1109 {0x3c06, 0x00},1110 {0x3c07, 0x05},1111 {0x3c0c, 0x00},1112 {0x3c0d, 0x00},1113 {0x3c0e, 0x00},1114 {0x3c0f, 0x00},1115 {0x3c40, 0x00},1116 {0x3c41, 0xa3},1117 {0x3c43, 0x7d},1118 {0x3c45, 0xd7},1119 {0x3c47, 0xfc},1120 {0x3c50, 0x05},1121 {0x3c52, 0xaa},1122 {0x3c54, 0x71},1123 {0x3c56, 0x80},1124 {0x3d85, 0x17},1125 {0x3f03, 0x00},1126 {0x3f0a, 0x00},1127 {0x3f0b, 0x00},1128 {0x4001, 0x60},1129 {0x4009, 0x0d},1130 {0x4020, 0x00},1131 {0x4021, 0x00},1132 {0x4022, 0x00},1133 {0x4023, 0x00},1134 {0x4024, 0x00},1135 {0x4025, 0x00},1136 {0x4026, 0x00},1137 {0x4027, 0x00},1138 {0x4028, 0x00},1139 {0x4029, 0x00},1140 {0x402a, 0x00},1141 {0x402b, 0x00},1142 {0x402c, 0x00},1143 {0x402d, 0x00},1144 {0x402e, 0x00},1145 {0x402f, 0x00},1146 {0x4040, 0x00},1147 {0x4041, 0x03},1148 {0x4042, 0x00},1149 {0x4043, 0x7A},1150 {0x4044, 0x00},1151 {0x4045, 0x7A},1152 {0x4046, 0x00},1153 {0x4047, 0x7A},1154 {0x4048, 0x00},1155 {0x4049, 0x7A},1156 {0x4307, 0x30},1157 {0x4500, 0x58},1158 {0x4501, 0x04},1159 {0x4502, 0x40},1160 {0x4503, 0x10},1161 {0x4508, 0xaa},1162 {0x4509, 0xaa},1163 {0x450a, 0x00},1164 {0x450b, 0x00},1165 {0x4600, 0x01},1166 {0x4601, 0x00},1167 {0x4700, 0xa4},1168 {0x4800, 0x4c},1169 {0x4816, 0x53},1170 {0x481f, 0x40},1171 {0x4837, 0x13},1172 {0x5000, 0x56},1173 {0x5001, 0x01},1174 {0x5002, 0x28},1175 {0x5004, 0x0c},1176 {0x5006, 0x0c},1177 {0x5007, 0xe0},1178 {0x5008, 0x01},1179 {0x5009, 0xb0},1180 {0x5901, 0x00},1181 {0x5a01, 0x00},1182 {0x5a03, 0x00},1183 {0x5a04, 0x0c},1184 {0x5a05, 0xe0},1185 {0x5a06, 0x09},1186 {0x5a07, 0xb0},1187 {0x5a08, 0x06},1188 {0x5e00, 0x00},1189 {0x3734, 0x40},1190 {0x5b00, 0x01},1191 {0x5b01, 0x10},1192 {0x5b02, 0x01},1193 {0x5b03, 0xdb},1194 {0x3d8c, 0x71},1195 {0x3d8d, 0xea},1196 {0x4017, 0x08},1197 {0x3618, 0x2a},1198 {0x5780, 0x3e},1199 {0x5781, 0x0f},1200 {0x5782, 0x44},1201 {0x5783, 0x02},1202 {0x5784, 0x01},1203 {0x5785, 0x01},1204 {0x5786, 0x00},1205 {0x5787, 0x04},1206 {0x5788, 0x02},1207 {0x5789, 0x0f},1208 {0x578a, 0xfd},1209 {0x578b, 0xf5},1210 {0x578c, 0xf5},1211 {0x578d, 0x03},1212 {0x578e, 0x08},1213 {0x578f, 0x0c},1214 {0x5790, 0x08},1215 {0x5791, 0x06},1216 {0x5792, 0x00},1217 {0x5793, 0x52},1218 {0x5794, 0xa3},1219 {0x5045, 0x05},1220 {0x4003, 0x40},1221 {0x5048, 0x40}1222};1223 1224static const struct ov5670_reg mode_1280x720_regs[] = {1225 {0x3000, 0x00},1226 {0x3002, 0x21},1227 {0x3005, 0xf0},1228 {0x3007, 0x00},1229 {0x3015, 0x0f},1230 {0x301a, 0xf0},1231 {0x301b, 0xf0},1232 {0x301c, 0xf0},1233 {0x301d, 0xf0},1234 {0x301e, 0xf0},1235 {0x3030, 0x00},1236 {0x3031, 0x0a},1237 {0x303c, 0xff},1238 {0x303e, 0xff},1239 {0x3040, 0xf0},1240 {0x3041, 0x00},1241 {0x3042, 0xf0},1242 {0x3106, 0x11},1243 {0x3500, 0x00},1244 {0x3501, 0x80},1245 {0x3502, 0x00},1246 {0x3503, 0x04},1247 {0x3504, 0x03},1248 {0x3505, 0x83},1249 {0x3508, 0x04},1250 {0x3509, 0x00},1251 {0x350e, 0x04},1252 {0x350f, 0x00},1253 {0x3510, 0x00},1254 {0x3511, 0x02},1255 {0x3512, 0x00},1256 {0x3601, 0xc8},1257 {0x3610, 0x88},1258 {0x3612, 0x48},1259 {0x3614, 0x5b},1260 {0x3615, 0x96},1261 {0x3621, 0xd0},1262 {0x3622, 0x00},1263 {0x3623, 0x00},1264 {0x3633, 0x13},1265 {0x3634, 0x13},1266 {0x3635, 0x13},1267 {0x3636, 0x13},1268 {0x3645, 0x13},1269 {0x3646, 0x82},1270 {0x3650, 0x00},1271 {0x3652, 0xff},1272 {0x3655, 0x20},1273 {0x3656, 0xff},1274 {0x365a, 0xff},1275 {0x365e, 0xff},1276 {0x3668, 0x00},1277 {0x366a, 0x07},1278 {0x366e, 0x08},1279 {0x366d, 0x00},1280 {0x366f, 0x80},1281 {0x3700, 0x28},1282 {0x3701, 0x10},1283 {0x3702, 0x3a},1284 {0x3703, 0x19},1285 {0x3704, 0x10},1286 {0x3705, 0x00},1287 {0x3706, 0x66},1288 {0x3707, 0x08},1289 {0x3708, 0x34},1290 {0x3709, 0x40},1291 {0x370a, 0x01},1292 {0x370b, 0x1b},1293 {0x3714, 0x24},1294 {0x371a, 0x3e},1295 {0x3733, 0x00},1296 {0x3734, 0x00},1297 {0x373a, 0x05},1298 {0x373b, 0x06},1299 {0x373c, 0x0a},1300 {0x373f, 0xa0},1301 {0x3755, 0x00},1302 {0x3758, 0x00},1303 {0x375b, 0x0e},1304 {0x3766, 0x5f},1305 {0x3768, 0x00},1306 {0x3769, 0x22},1307 {0x3773, 0x08},1308 {0x3774, 0x1f},1309 {0x3776, 0x06},1310 {0x37a0, 0x88},1311 {0x37a1, 0x5c},1312 {0x37a7, 0x88},1313 {0x37a8, 0x70},1314 {0x37aa, 0x88},1315 {0x37ab, 0x48},1316 {0x37b3, 0x66},1317 {0x37c2, 0x04},1318 {0x37c5, 0x00},1319 {0x37c8, 0x00},1320 {0x3800, 0x00},1321 {0x3801, 0x0c},1322 {0x3802, 0x00},1323 {0x3803, 0x04},1324 {0x3804, 0x0a},1325 {0x3805, 0x33},1326 {0x3806, 0x07},1327 {0x3807, 0xa3},1328 {0x3808, 0x05},1329 {0x3809, 0x00},1330 {0x380a, 0x02},1331 {0x380b, 0xd0},1332 {0x380c, 0x06},1333 {0x380d, 0x90},1334 {0x380e, 0x08},1335 {0x380f, 0x08},1336 {0x3811, 0x04},1337 {0x3813, 0x02},1338 {0x3814, 0x03},1339 {0x3815, 0x01},1340 {0x3816, 0x00},1341 {0x3817, 0x00},1342 {0x3818, 0x00},1343 {0x3819, 0x00},1344 {0x3820, 0x94},1345 {0x3821, 0x47},1346 {0x3822, 0x48},1347 {0x3826, 0x00},1348 {0x3827, 0x08},1349 {0x382a, 0x03},1350 {0x382b, 0x01},1351 {0x3830, 0x08},1352 {0x3836, 0x02},1353 {0x3837, 0x00},1354 {0x3838, 0x10},1355 {0x3841, 0xff},1356 {0x3846, 0x48},1357 {0x3861, 0x00},1358 {0x3862, 0x04},1359 {0x3863, 0x06},1360 {0x3a11, 0x01},1361 {0x3a12, 0x78},1362 {0x3b00, 0x00},1363 {0x3b02, 0x00},1364 {0x3b03, 0x00},1365 {0x3b04, 0x00},1366 {0x3b05, 0x00},1367 {0x3c00, 0x89},1368 {0x3c01, 0xab},1369 {0x3c02, 0x01},1370 {0x3c03, 0x00},1371 {0x3c04, 0x00},1372 {0x3c05, 0x03},1373 {0x3c06, 0x00},1374 {0x3c07, 0x05},1375 {0x3c0c, 0x00},1376 {0x3c0d, 0x00},1377 {0x3c0e, 0x00},1378 {0x3c0f, 0x00},1379 {0x3c40, 0x00},1380 {0x3c41, 0xa3},1381 {0x3c43, 0x7d},1382 {0x3c45, 0xd7},1383 {0x3c47, 0xfc},1384 {0x3c50, 0x05},1385 {0x3c52, 0xaa},1386 {0x3c54, 0x71},1387 {0x3c56, 0x80},1388 {0x3d85, 0x17},1389 {0x3f03, 0x00},1390 {0x3f0a, 0x00},1391 {0x3f0b, 0x00},1392 {0x4001, 0x60},1393 {0x4009, 0x05},1394 {0x4020, 0x00},1395 {0x4021, 0x00},1396 {0x4022, 0x00},1397 {0x4023, 0x00},1398 {0x4024, 0x00},1399 {0x4025, 0x00},1400 {0x4026, 0x00},1401 {0x4027, 0x00},1402 {0x4028, 0x00},1403 {0x4029, 0x00},1404 {0x402a, 0x00},1405 {0x402b, 0x00},1406 {0x402c, 0x00},1407 {0x402d, 0x00},1408 {0x402e, 0x00},1409 {0x402f, 0x00},1410 {0x4040, 0x00},1411 {0x4041, 0x03},1412 {0x4042, 0x00},1413 {0x4043, 0x7A},1414 {0x4044, 0x00},1415 {0x4045, 0x7A},1416 {0x4046, 0x00},1417 {0x4047, 0x7A},1418 {0x4048, 0x00},1419 {0x4049, 0x7A},1420 {0x4307, 0x30},1421 {0x4500, 0x58},1422 {0x4501, 0x04},1423 {0x4502, 0x48},1424 {0x4503, 0x10},1425 {0x4508, 0x55},1426 {0x4509, 0x55},1427 {0x450a, 0x00},1428 {0x450b, 0x00},1429 {0x4600, 0x00},1430 {0x4601, 0x80},1431 {0x4700, 0xa4},1432 {0x4800, 0x4c},1433 {0x4816, 0x53},1434 {0x481f, 0x40},1435 {0x4837, 0x13},1436 {0x5000, 0x56},1437 {0x5001, 0x01},1438 {0x5002, 0x28},1439 {0x5004, 0x0c},1440 {0x5006, 0x0c},1441 {0x5007, 0xe0},1442 {0x5008, 0x01},1443 {0x5009, 0xb0},1444 {0x5901, 0x00},1445 {0x5a01, 0x00},1446 {0x5a03, 0x00},1447 {0x5a04, 0x0c},1448 {0x5a05, 0xe0},1449 {0x5a06, 0x09},1450 {0x5a07, 0xb0},1451 {0x5a08, 0x06},1452 {0x5e00, 0x00},1453 {0x3734, 0x40},1454 {0x5b00, 0x01},1455 {0x5b01, 0x10},1456 {0x5b02, 0x01},1457 {0x5b03, 0xdb},1458 {0x3d8c, 0x71},1459 {0x3d8d, 0xea},1460 {0x4017, 0x10},1461 {0x3618, 0x2a},1462 {0x5780, 0x3e},1463 {0x5781, 0x0f},1464 {0x5782, 0x44},1465 {0x5783, 0x02},1466 {0x5784, 0x01},1467 {0x5785, 0x01},1468 {0x5786, 0x00},1469 {0x5787, 0x04},1470 {0x5788, 0x02},1471 {0x5789, 0x0f},1472 {0x578a, 0xfd},1473 {0x578b, 0xf5},1474 {0x578c, 0xf5},1475 {0x578d, 0x03},1476 {0x578e, 0x08},1477 {0x578f, 0x0c},1478 {0x5790, 0x08},1479 {0x5791, 0x06},1480 {0x5792, 0x00},1481 {0x5793, 0x52},1482 {0x5794, 0xa3},1483 {0x3503, 0x00},1484 {0x5045, 0x05},1485 {0x4003, 0x40},1486 {0x5048, 0x40}1487};1488 1489static const struct ov5670_reg mode_640x360_regs[] = {1490 {0x3000, 0x00},1491 {0x3002, 0x21},1492 {0x3005, 0xf0},1493 {0x3007, 0x00},1494 {0x3015, 0x0f},1495 {0x301a, 0xf0},1496 {0x301b, 0xf0},1497 {0x301c, 0xf0},1498 {0x301d, 0xf0},1499 {0x301e, 0xf0},1500 {0x3030, 0x00},1501 {0x3031, 0x0a},1502 {0x303c, 0xff},1503 {0x303e, 0xff},1504 {0x3040, 0xf0},1505 {0x3041, 0x00},1506 {0x3042, 0xf0},1507 {0x3106, 0x11},1508 {0x3500, 0x00},1509 {0x3501, 0x80},1510 {0x3502, 0x00},1511 {0x3503, 0x04},1512 {0x3504, 0x03},1513 {0x3505, 0x83},1514 {0x3508, 0x04},1515 {0x3509, 0x00},1516 {0x350e, 0x04},1517 {0x350f, 0x00},1518 {0x3510, 0x00},1519 {0x3511, 0x02},1520 {0x3512, 0x00},1521 {0x3601, 0xc8},1522 {0x3610, 0x88},1523 {0x3612, 0x48},1524 {0x3614, 0x5b},1525 {0x3615, 0x96},1526 {0x3621, 0xd0},1527 {0x3622, 0x00},1528 {0x3623, 0x04},1529 {0x3633, 0x13},1530 {0x3634, 0x13},1531 {0x3635, 0x13},1532 {0x3636, 0x13},1533 {0x3645, 0x13},1534 {0x3646, 0x82},1535 {0x3650, 0x00},1536 {0x3652, 0xff},1537 {0x3655, 0x20},1538 {0x3656, 0xff},1539 {0x365a, 0xff},1540 {0x365e, 0xff},1541 {0x3668, 0x00},1542 {0x366a, 0x07},1543 {0x366e, 0x08},1544 {0x366d, 0x00},1545 {0x366f, 0x80},1546 {0x3700, 0x28},1547 {0x3701, 0x10},1548 {0x3702, 0x3a},1549 {0x3703, 0x19},1550 {0x3704, 0x10},1551 {0x3705, 0x00},1552 {0x3706, 0x66},1553 {0x3707, 0x08},1554 {0x3708, 0x34},1555 {0x3709, 0x40},1556 {0x370a, 0x01},1557 {0x370b, 0x1b},1558 {0x3714, 0x24},1559 {0x371a, 0x3e},1560 {0x3733, 0x00},1561 {0x3734, 0x00},1562 {0x373a, 0x05},1563 {0x373b, 0x06},1564 {0x373c, 0x0a},1565 {0x373f, 0xa0},1566 {0x3755, 0x00},1567 {0x3758, 0x00},1568 {0x375b, 0x0e},1569 {0x3766, 0x5f},1570 {0x3768, 0x00},1571 {0x3769, 0x22},1572 {0x3773, 0x08},1573 {0x3774, 0x1f},1574 {0x3776, 0x06},1575 {0x37a0, 0x88},1576 {0x37a1, 0x5c},1577 {0x37a7, 0x88},1578 {0x37a8, 0x70},1579 {0x37aa, 0x88},1580 {0x37ab, 0x48},1581 {0x37b3, 0x66},1582 {0x37c2, 0x04},1583 {0x37c5, 0x00},1584 {0x37c8, 0x00},1585 {0x3800, 0x00},1586 {0x3801, 0x0c},1587 {0x3802, 0x00},1588 {0x3803, 0x04},1589 {0x3804, 0x0a},1590 {0x3805, 0x33},1591 {0x3806, 0x07},1592 {0x3807, 0xa3},1593 {0x3808, 0x02},1594 {0x3809, 0x80},1595 {0x380a, 0x01},1596 {0x380b, 0x68},1597 {0x380c, 0x06},1598 {0x380d, 0x90},1599 {0x380e, 0x08},1600 {0x380f, 0x08},1601 {0x3811, 0x04},1602 {0x3813, 0x02},1603 {0x3814, 0x07},1604 {0x3815, 0x01},1605 {0x3816, 0x00},1606 {0x3817, 0x00},1607 {0x3818, 0x00},1608 {0x3819, 0x00},1609 {0x3820, 0x94},1610 {0x3821, 0xc6},1611 {0x3822, 0x48},1612 {0x3826, 0x00},1613 {0x3827, 0x08},1614 {0x382a, 0x07},1615 {0x382b, 0x01},1616 {0x3830, 0x08},1617 {0x3836, 0x02},1618 {0x3837, 0x00},1619 {0x3838, 0x10},1620 {0x3841, 0xff},1621 {0x3846, 0x48},1622 {0x3861, 0x00},1623 {0x3862, 0x04},1624 {0x3863, 0x06},1625 {0x3a11, 0x01},1626 {0x3a12, 0x78},1627 {0x3b00, 0x00},1628 {0x3b02, 0x00},1629 {0x3b03, 0x00},1630 {0x3b04, 0x00},1631 {0x3b05, 0x00},1632 {0x3c00, 0x89},1633 {0x3c01, 0xab},1634 {0x3c02, 0x01},1635 {0x3c03, 0x00},1636 {0x3c04, 0x00},1637 {0x3c05, 0x03},1638 {0x3c06, 0x00},1639 {0x3c07, 0x05},1640 {0x3c0c, 0x00},1641 {0x3c0d, 0x00},1642 {0x3c0e, 0x00},1643 {0x3c0f, 0x00},1644 {0x3c40, 0x00},1645 {0x3c41, 0xa3},1646 {0x3c43, 0x7d},1647 {0x3c45, 0xd7},1648 {0x3c47, 0xfc},1649 {0x3c50, 0x05},1650 {0x3c52, 0xaa},1651 {0x3c54, 0x71},1652 {0x3c56, 0x80},1653 {0x3d85, 0x17},1654 {0x3f03, 0x00},1655 {0x3f0a, 0x00},1656 {0x3f0b, 0x00},1657 {0x4001, 0x60},1658 {0x4009, 0x05},1659 {0x4020, 0x00},1660 {0x4021, 0x00},1661 {0x4022, 0x00},1662 {0x4023, 0x00},1663 {0x4024, 0x00},1664 {0x4025, 0x00},1665 {0x4026, 0x00},1666 {0x4027, 0x00},1667 {0x4028, 0x00},1668 {0x4029, 0x00},1669 {0x402a, 0x00},1670 {0x402b, 0x00},1671 {0x402c, 0x00},1672 {0x402d, 0x00},1673 {0x402e, 0x00},1674 {0x402f, 0x00},1675 {0x4040, 0x00},1676 {0x4041, 0x03},1677 {0x4042, 0x00},1678 {0x4043, 0x7A},1679 {0x4044, 0x00},1680 {0x4045, 0x7A},1681 {0x4046, 0x00},1682 {0x4047, 0x7A},1683 {0x4048, 0x00},1684 {0x4049, 0x7A},1685 {0x4307, 0x30},1686 {0x4500, 0x58},1687 {0x4501, 0x04},1688 {0x4502, 0x40},1689 {0x4503, 0x10},1690 {0x4508, 0x55},1691 {0x4509, 0x55},1692 {0x450a, 0x02},1693 {0x450b, 0x00},1694 {0x4600, 0x00},1695 {0x4601, 0x40},1696 {0x4700, 0xa4},1697 {0x4800, 0x4c},1698 {0x4816, 0x53},1699 {0x481f, 0x40},1700 {0x4837, 0x13},1701 {0x5000, 0x56},1702 {0x5001, 0x01},1703 {0x5002, 0x28},1704 {0x5004, 0x0c},1705 {0x5006, 0x0c},1706 {0x5007, 0xe0},1707 {0x5008, 0x01},1708 {0x5009, 0xb0},1709 {0x5901, 0x00},1710 {0x5a01, 0x00},1711 {0x5a03, 0x00},1712 {0x5a04, 0x0c},1713 {0x5a05, 0xe0},1714 {0x5a06, 0x09},1715 {0x5a07, 0xb0},1716 {0x5a08, 0x06},1717 {0x5e00, 0x00},1718 {0x3734, 0x40},1719 {0x5b00, 0x01},1720 {0x5b01, 0x10},1721 {0x5b02, 0x01},1722 {0x5b03, 0xdb},1723 {0x3d8c, 0x71},1724 {0x3d8d, 0xea},1725 {0x4017, 0x10},1726 {0x3618, 0x2a},1727 {0x5780, 0x3e},1728 {0x5781, 0x0f},1729 {0x5782, 0x44},1730 {0x5783, 0x02},1731 {0x5784, 0x01},1732 {0x5785, 0x01},1733 {0x5786, 0x00},1734 {0x5787, 0x04},1735 {0x5788, 0x02},1736 {0x5789, 0x0f},1737 {0x578a, 0xfd},1738 {0x578b, 0xf5},1739 {0x578c, 0xf5},1740 {0x578d, 0x03},1741 {0x578e, 0x08},1742 {0x578f, 0x0c},1743 {0x5790, 0x08},1744 {0x5791, 0x06},1745 {0x5792, 0x00},1746 {0x5793, 0x52},1747 {0x5794, 0xa3},1748 {0x3503, 0x00},1749 {0x5045, 0x05},1750 {0x4003, 0x40},1751 {0x5048, 0x40}1752};1753 1754static const char * const ov5670_test_pattern_menu[] = {1755 "Disabled",1756 "Vertical Color Bar Type 1",1757};1758 1759/* Supported link frequencies */1760#define OV5670_LINK_FREQ_422MHZ 4224000001761#define OV5670_LINK_FREQ_422MHZ_INDEX 01762static const struct ov5670_link_freq_config link_freq_configs[] = {1763 {1764 .reg_list = {1765 .num_of_regs = ARRAY_SIZE(mipi_data_rate_840mbps),1766 .regs = mipi_data_rate_840mbps,1767 }1768 }1769};1770 1771static const s64 link_freq_menu_items[] = {1772 OV5670_LINK_FREQ_422MHZ1773};1774 1775/*1776 * OV5670 sensor supports following resolutions with full FOV:1777 * 4:3 ==> {2592x1944, 1296x972, 648x486}1778 * 16:9 ==> {2560x1440, 1280x720, 640x360}1779 */1780static const struct ov5670_mode supported_modes[] = {1781 {1782 .width = 2592,1783 .height = 1944,1784 .vts_def = OV5670_VTS_30FPS,1785 .vts_min = OV5670_VTS_30FPS,1786 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1787 .analog_crop = &ov5670_analog_crop,1788 .reg_list = {1789 .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),1790 .regs = mode_2592x1944_regs,1791 },1792 },1793 {1794 .width = 1296,1795 .height = 972,1796 .vts_def = OV5670_VTS_30FPS,1797 .vts_min = 996,1798 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1799 .analog_crop = &ov5670_analog_crop,1800 .reg_list = {1801 .num_of_regs = ARRAY_SIZE(mode_1296x972_regs),1802 .regs = mode_1296x972_regs,1803 },1804 },1805 {1806 .width = 648,1807 .height = 486,1808 .vts_def = OV5670_VTS_30FPS,1809 .vts_min = 516,1810 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1811 .analog_crop = &ov5670_analog_crop,1812 .reg_list = {1813 .num_of_regs = ARRAY_SIZE(mode_648x486_regs),1814 .regs = mode_648x486_regs,1815 },1816 },1817 {1818 .width = 2560,1819 .height = 1440,1820 .vts_def = OV5670_VTS_30FPS,1821 .vts_min = OV5670_VTS_30FPS,1822 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1823 .analog_crop = &ov5670_analog_crop,1824 .reg_list = {1825 .num_of_regs = ARRAY_SIZE(mode_2560x1440_regs),1826 .regs = mode_2560x1440_regs,1827 },1828 },1829 {1830 .width = 1280,1831 .height = 720,1832 .vts_def = OV5670_VTS_30FPS,1833 .vts_min = 1020,1834 1835 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1836 .analog_crop = &ov5670_analog_crop,1837 .reg_list = {1838 .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),1839 .regs = mode_1280x720_regs,1840 },1841 },1842 {1843 .width = 640,1844 .height = 360,1845 .vts_def = OV5670_VTS_30FPS,1846 .vts_min = 510,1847 .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,1848 .analog_crop = &ov5670_analog_crop,1849 .reg_list = {1850 .num_of_regs = ARRAY_SIZE(mode_640x360_regs),1851 .regs = mode_640x360_regs,1852 },1853 }1854};1855 1856struct ov5670 {1857 struct v4l2_subdev sd;1858 struct media_pad pad;1859 struct v4l2_fwnode_endpoint endpoint;1860 1861 struct v4l2_ctrl_handler ctrl_handler;1862 /* V4L2 Controls */1863 struct v4l2_ctrl *link_freq;1864 struct v4l2_ctrl *pixel_rate;1865 struct v4l2_ctrl *vblank;1866 struct v4l2_ctrl *hblank;1867 struct v4l2_ctrl *exposure;1868 1869 /* Current mode */1870 const struct ov5670_mode *cur_mode;1871 1872 /* xvclk input clock */1873 struct clk *xvclk;1874 1875 /* Regulators */1876 struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES];1877 1878 /* Power-down and reset gpios. */1879 struct gpio_desc *pwdn_gpio; /* PWDNB pin. */1880 struct gpio_desc *reset_gpio; /* XSHUTDOWN pin. */1881 1882 /* To serialize asynchronus callbacks */1883 struct mutex mutex;1884 1885 /* True if the device has been identified */1886 bool identified;1887};1888 1889#define to_ov5670(_sd) container_of(_sd, struct ov5670, sd)1890 1891/* Read registers up to 4 at a time */1892static int ov5670_read_reg(struct ov5670 *ov5670, u16 reg, unsigned int len,1893 u32 *val)1894{1895 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);1896 struct i2c_msg msgs[2];1897 u8 *data_be_p;1898 __be32 data_be = 0;1899 __be16 reg_addr_be = cpu_to_be16(reg);1900 int ret;1901 1902 if (len > 4)1903 return -EINVAL;1904 1905 data_be_p = (u8 *)&data_be;1906 /* Write register address */1907 msgs[0].addr = client->addr;1908 msgs[0].flags = 0;1909 msgs[0].len = 2;1910 msgs[0].buf = (u8 *)®_addr_be;1911 1912 /* Read data from register */1913 msgs[1].addr = client->addr;1914 msgs[1].flags = I2C_M_RD;1915 msgs[1].len = len;1916 msgs[1].buf = &data_be_p[4 - len];1917 1918 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));1919 if (ret != ARRAY_SIZE(msgs))1920 return -EIO;1921 1922 *val = be32_to_cpu(data_be);1923 1924 return 0;1925}1926 1927/* Write registers up to 4 at a time */1928static int ov5670_write_reg(struct ov5670 *ov5670, u16 reg, unsigned int len,1929 u32 val)1930{1931 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);1932 int buf_i;1933 int val_i;1934 u8 buf[6];1935 u8 *val_p;1936 __be32 tmp;1937 1938 if (len > 4)1939 return -EINVAL;1940 1941 buf[0] = reg >> 8;1942 buf[1] = reg & 0xff;1943 1944 tmp = cpu_to_be32(val);1945 val_p = (u8 *)&tmp;1946 buf_i = 2;1947 val_i = 4 - len;1948 1949 while (val_i < 4)1950 buf[buf_i++] = val_p[val_i++];1951 1952 if (i2c_master_send(client, buf, len + 2) != len + 2)1953 return -EIO;1954 1955 return 0;1956}1957 1958/* Write a list of registers */1959static int ov5670_write_regs(struct ov5670 *ov5670,1960 const struct ov5670_reg *regs, unsigned int len)1961{1962 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);1963 unsigned int i;1964 int ret;1965 1966 for (i = 0; i < len; i++) {1967 ret = ov5670_write_reg(ov5670, regs[i].address, 1, regs[i].val);1968 if (ret) {1969 dev_err_ratelimited(1970 &client->dev,1971 "Failed to write reg 0x%4.4x. error = %d\n",1972 regs[i].address, ret);1973 1974 return ret;1975 }1976 }1977 1978 return 0;1979}1980 1981static int ov5670_write_reg_list(struct ov5670 *ov5670,1982 const struct ov5670_reg_list *r_list)1983{1984 return ov5670_write_regs(ov5670, r_list->regs, r_list->num_of_regs);1985}1986 1987static int ov5670_update_digital_gain(struct ov5670 *ov5670, u32 d_gain)1988{1989 int ret;1990 1991 ret = ov5670_write_reg(ov5670, OV5670_REG_R_DGTL_GAIN,1992 OV5670_REG_VALUE_16BIT, d_gain);1993 if (ret)1994 return ret;1995 1996 ret = ov5670_write_reg(ov5670, OV5670_REG_G_DGTL_GAIN,1997 OV5670_REG_VALUE_16BIT, d_gain);1998 if (ret)1999 return ret;2000 2001 return ov5670_write_reg(ov5670, OV5670_REG_B_DGTL_GAIN,2002 OV5670_REG_VALUE_16BIT, d_gain);2003}2004 2005static int ov5670_enable_test_pattern(struct ov5670 *ov5670, u32 pattern)2006{2007 u32 val;2008 int ret;2009 2010 /* Set the bayer order that we support */2011 ret = ov5670_write_reg(ov5670, OV5670_REG_TEST_PATTERN_CTRL,2012 OV5670_REG_VALUE_08BIT, 0);2013 if (ret)2014 return ret;2015 2016 ret = ov5670_read_reg(ov5670, OV5670_REG_TEST_PATTERN,2017 OV5670_REG_VALUE_08BIT, &val);2018 if (ret)2019 return ret;2020 2021 if (pattern)2022 val |= OV5670_TEST_PATTERN_ENABLE;2023 else2024 val &= ~OV5670_TEST_PATTERN_ENABLE;2025 2026 return ov5670_write_reg(ov5670, OV5670_REG_TEST_PATTERN,2027 OV5670_REG_VALUE_08BIT, val);2028}2029 2030/* Initialize control handlers */2031static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)2032{2033 struct ov5670 *ov5670 = container_of(ctrl->handler,2034 struct ov5670, ctrl_handler);2035 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2036 s64 max;2037 int ret;2038 2039 /* Propagate change of current control to all related controls */2040 switch (ctrl->id) {2041 case V4L2_CID_VBLANK:2042 /* Update max exposure while meeting expected vblanking */2043 max = ov5670->cur_mode->height + ctrl->val - 8;2044 __v4l2_ctrl_modify_range(ov5670->exposure,2045 ov5670->exposure->minimum, max,2046 ov5670->exposure->step, max);2047 break;2048 }2049 2050 /* V4L2 controls values will be applied only when power is already up */2051 if (!pm_runtime_get_if_in_use(&client->dev))2052 return 0;2053 2054 switch (ctrl->id) {2055 case V4L2_CID_ANALOGUE_GAIN:2056 ret = ov5670_write_reg(ov5670, OV5670_REG_ANALOG_GAIN,2057 OV5670_REG_VALUE_16BIT, ctrl->val);2058 break;2059 case V4L2_CID_DIGITAL_GAIN:2060 ret = ov5670_update_digital_gain(ov5670, ctrl->val);2061 break;2062 case V4L2_CID_EXPOSURE:2063 /* 4 least significant bits of expsoure are fractional part */2064 ret = ov5670_write_reg(ov5670, OV5670_REG_EXPOSURE,2065 OV5670_REG_VALUE_24BIT, ctrl->val << 4);2066 break;2067 case V4L2_CID_VBLANK:2068 /* Update VTS that meets expected vertical blanking */2069 ret = ov5670_write_reg(ov5670, OV5670_REG_VTS,2070 OV5670_REG_VALUE_16BIT,2071 ov5670->cur_mode->height + ctrl->val);2072 break;2073 case V4L2_CID_TEST_PATTERN:2074 ret = ov5670_enable_test_pattern(ov5670, ctrl->val);2075 break;2076 case V4L2_CID_HBLANK:2077 case V4L2_CID_LINK_FREQ:2078 case V4L2_CID_PIXEL_RATE:2079 ret = 0;2080 break;2081 default:2082 ret = -EINVAL;2083 dev_info(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",2084 __func__, ctrl->id, ctrl->val);2085 break;2086 }2087 2088 pm_runtime_put(&client->dev);2089 2090 return ret;2091}2092 2093static const struct v4l2_ctrl_ops ov5670_ctrl_ops = {2094 .s_ctrl = ov5670_set_ctrl,2095};2096 2097/* Initialize control handlers */2098static int ov5670_init_controls(struct ov5670 *ov5670)2099{2100 struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =2101 &ov5670->endpoint.bus.mipi_csi2;2102 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2103 struct v4l2_fwnode_device_properties props;2104 struct v4l2_ctrl_handler *ctrl_hdlr;2105 unsigned int lanes_count;2106 s64 mipi_pixel_rate;2107 s64 vblank_max;2108 s64 vblank_def;2109 s64 vblank_min;2110 s64 exposure_max;2111 int ret;2112 2113 ctrl_hdlr = &ov5670->ctrl_handler;2114 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);2115 if (ret)2116 return ret;2117 2118 ctrl_hdlr->lock = &ov5670->mutex;2119 ov5670->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,2120 &ov5670_ctrl_ops,2121 V4L2_CID_LINK_FREQ,2122 0, 0, link_freq_menu_items);2123 if (ov5670->link_freq)2124 ov5670->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;2125 2126 /* By default, V4L2_CID_PIXEL_RATE is read only */2127 lanes_count = bus_mipi_csi2->num_data_lanes;2128 mipi_pixel_rate = OV5670_LINK_FREQ_422MHZ * 2 * lanes_count / 10;2129 2130 ov5670->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops,2131 V4L2_CID_PIXEL_RATE,2132 mipi_pixel_rate,2133 mipi_pixel_rate,2134 1,2135 mipi_pixel_rate);2136 2137 vblank_max = OV5670_VTS_MAX - ov5670->cur_mode->height;2138 vblank_def = ov5670->cur_mode->vts_def - ov5670->cur_mode->height;2139 vblank_min = ov5670->cur_mode->vts_min - ov5670->cur_mode->height;2140 ov5670->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops,2141 V4L2_CID_VBLANK, vblank_min,2142 vblank_max, 1, vblank_def);2143 2144 ov5670->hblank = v4l2_ctrl_new_std(2145 ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_HBLANK,2146 OV5670_FIXED_PPL - ov5670->cur_mode->width,2147 OV5670_FIXED_PPL - ov5670->cur_mode->width, 1,2148 OV5670_FIXED_PPL - ov5670->cur_mode->width);2149 if (ov5670->hblank)2150 ov5670->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;2151 2152 /* Get min, max, step, default from sensor */2153 v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,2154 ANALOG_GAIN_MIN, ANALOG_GAIN_MAX, ANALOG_GAIN_STEP,2155 ANALOG_GAIN_DEFAULT);2156 2157 /* Digital gain */2158 v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_DIGITAL_GAIN,2159 OV5670_DGTL_GAIN_MIN, OV5670_DGTL_GAIN_MAX,2160 OV5670_DGTL_GAIN_STEP, OV5670_DGTL_GAIN_DEFAULT);2161 2162 /* Get min, max, step, default from sensor */2163 exposure_max = ov5670->cur_mode->vts_def - 8;2164 ov5670->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops,2165 V4L2_CID_EXPOSURE,2166 OV5670_EXPOSURE_MIN,2167 exposure_max, OV5670_EXPOSURE_STEP,2168 exposure_max);2169 2170 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5670_ctrl_ops,2171 V4L2_CID_TEST_PATTERN,2172 ARRAY_SIZE(ov5670_test_pattern_menu) - 1,2173 0, 0, ov5670_test_pattern_menu);2174 2175 if (ctrl_hdlr->error) {2176 ret = ctrl_hdlr->error;2177 goto error;2178 }2179 2180 ret = v4l2_fwnode_device_parse(&client->dev, &props);2181 if (ret)2182 goto error;2183 2184 ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov5670_ctrl_ops,2185 &props);2186 if (ret)2187 goto error;2188 2189 ov5670->sd.ctrl_handler = ctrl_hdlr;2190 2191 return 0;2192 2193error:2194 v4l2_ctrl_handler_free(ctrl_hdlr);2195 2196 return ret;2197}2198 2199static int ov5670_init_state(struct v4l2_subdev *sd,2200 struct v4l2_subdev_state *state)2201{2202 struct v4l2_mbus_framefmt *fmt =2203 v4l2_subdev_state_get_format(state, 0);2204 const struct ov5670_mode *default_mode = &supported_modes[0];2205 struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);2206 2207 fmt->width = default_mode->width;2208 fmt->height = default_mode->height;2209 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;2210 fmt->field = V4L2_FIELD_NONE;2211 fmt->colorspace = V4L2_COLORSPACE_SRGB;2212 fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB);2213 fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;2214 fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB);2215 2216 *crop = *default_mode->analog_crop;2217 2218 return 0;2219}2220 2221static int ov5670_enum_mbus_code(struct v4l2_subdev *sd,2222 struct v4l2_subdev_state *sd_state,2223 struct v4l2_subdev_mbus_code_enum *code)2224{2225 /* Only one bayer order GRBG is supported */2226 if (code->index > 0)2227 return -EINVAL;2228 2229 code->code = MEDIA_BUS_FMT_SGRBG10_1X10;2230 2231 return 0;2232}2233 2234static int ov5670_enum_frame_size(struct v4l2_subdev *sd,2235 struct v4l2_subdev_state *sd_state,2236 struct v4l2_subdev_frame_size_enum *fse)2237{2238 if (fse->index >= ARRAY_SIZE(supported_modes))2239 return -EINVAL;2240 2241 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)2242 return -EINVAL;2243 2244 fse->min_width = supported_modes[fse->index].width;2245 fse->max_width = fse->min_width;2246 fse->min_height = supported_modes[fse->index].height;2247 fse->max_height = fse->min_height;2248 2249 return 0;2250}2251 2252static void ov5670_update_pad_format(const struct ov5670_mode *mode,2253 struct v4l2_subdev_format *fmt)2254{2255 fmt->format.width = mode->width;2256 fmt->format.height = mode->height;2257 fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;2258 fmt->format.field = V4L2_FIELD_NONE;2259}2260 2261static int ov5670_do_get_pad_format(struct ov5670 *ov5670,2262 struct v4l2_subdev_state *sd_state,2263 struct v4l2_subdev_format *fmt)2264{2265 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)2266 fmt->format = *v4l2_subdev_state_get_format(sd_state,2267 fmt->pad);2268 else2269 ov5670_update_pad_format(ov5670->cur_mode, fmt);2270 2271 return 0;2272}2273 2274static int ov5670_get_pad_format(struct v4l2_subdev *sd,2275 struct v4l2_subdev_state *sd_state,2276 struct v4l2_subdev_format *fmt)2277{2278 struct ov5670 *ov5670 = to_ov5670(sd);2279 int ret;2280 2281 mutex_lock(&ov5670->mutex);2282 ret = ov5670_do_get_pad_format(ov5670, sd_state, fmt);2283 mutex_unlock(&ov5670->mutex);2284 2285 return ret;2286}2287 2288static int ov5670_set_pad_format(struct v4l2_subdev *sd,2289 struct v4l2_subdev_state *sd_state,2290 struct v4l2_subdev_format *fmt)2291{2292 struct ov5670 *ov5670 = to_ov5670(sd);2293 struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =2294 &ov5670->endpoint.bus.mipi_csi2;2295 const struct ov5670_mode *mode;2296 unsigned int lanes_count;2297 s64 mipi_pixel_rate;2298 s32 vblank_def;2299 s64 link_freq;2300 s32 h_blank;2301 2302 mutex_lock(&ov5670->mutex);2303 2304 fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;2305 2306 mode = v4l2_find_nearest_size(supported_modes,2307 ARRAY_SIZE(supported_modes),2308 width, height,2309 fmt->format.width, fmt->format.height);2310 ov5670_update_pad_format(mode, fmt);2311 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {2312 *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;2313 } else {2314 ov5670->cur_mode = mode;2315 __v4l2_ctrl_s_ctrl(ov5670->link_freq, mode->link_freq_index);2316 2317 lanes_count = bus_mipi_csi2->num_data_lanes;2318 link_freq = link_freq_menu_items[mode->link_freq_index];2319 /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */2320 mipi_pixel_rate = div_s64(link_freq * 2 * lanes_count, 10);2321 __v4l2_ctrl_s_ctrl_int64(2322 ov5670->pixel_rate,2323 mipi_pixel_rate);2324 /* Update limits and set FPS to default */2325 vblank_def = ov5670->cur_mode->vts_def -2326 ov5670->cur_mode->height;2327 __v4l2_ctrl_modify_range(2328 ov5670->vblank,2329 ov5670->cur_mode->vts_min - ov5670->cur_mode->height,2330 OV5670_VTS_MAX - ov5670->cur_mode->height, 1,2331 vblank_def);2332 __v4l2_ctrl_s_ctrl(ov5670->vblank, vblank_def);2333 h_blank = OV5670_FIXED_PPL - ov5670->cur_mode->width;2334 __v4l2_ctrl_modify_range(ov5670->hblank, h_blank, h_blank, 1,2335 h_blank);2336 }2337 2338 mutex_unlock(&ov5670->mutex);2339 2340 return 0;2341}2342 2343static int ov5670_get_skip_frames(struct v4l2_subdev *sd, u32 *frames)2344{2345 *frames = OV5670_NUM_OF_SKIP_FRAMES;2346 2347 return 0;2348}2349 2350/* Verify chip ID */2351static int ov5670_identify_module(struct ov5670 *ov5670)2352{2353 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2354 int ret;2355 u32 val;2356 2357 if (ov5670->identified)2358 return 0;2359 2360 ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID,2361 OV5670_REG_VALUE_24BIT, &val);2362 if (ret)2363 return ret;2364 2365 if (val != OV5670_CHIP_ID) {2366 dev_err(&client->dev, "chip id mismatch: %x!=%x\n",2367 OV5670_CHIP_ID, val);2368 return -ENXIO;2369 }2370 2371 ov5670->identified = true;2372 2373 return 0;2374}2375 2376static int ov5670_mipi_configure(struct ov5670 *ov5670)2377{2378 struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =2379 &ov5670->endpoint.bus.mipi_csi2;2380 unsigned int lanes_count = bus_mipi_csi2->num_data_lanes;2381 2382 return ov5670_write_reg(ov5670, OV5670_MIPI_SC_CTRL0_REG,2383 OV5670_REG_VALUE_08BIT,2384 OV5670_MIPI_SC_CTRL0_LANES(lanes_count) |2385 OV5670_MIPI_SC_CTRL0_MIPI_EN |2386 OV5670_MIPI_SC_CTRL0_RESERVED);2387}2388 2389/* Prepare streaming by writing default values and customized values */2390static int ov5670_start_streaming(struct ov5670 *ov5670)2391{2392 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2393 const struct ov5670_reg_list *reg_list;2394 int link_freq_index;2395 int ret;2396 2397 ret = ov5670_identify_module(ov5670);2398 if (ret)2399 return ret;2400 2401 /* Get out of from software reset */2402 ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST,2403 OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST);2404 if (ret) {2405 dev_err(&client->dev, "%s failed to set powerup registers\n",2406 __func__);2407 return ret;2408 }2409 2410 /* Setup PLL */2411 link_freq_index = ov5670->cur_mode->link_freq_index;2412 reg_list = &link_freq_configs[link_freq_index].reg_list;2413 ret = ov5670_write_reg_list(ov5670, reg_list);2414 if (ret) {2415 dev_err(&client->dev, "%s failed to set plls\n", __func__);2416 return ret;2417 }2418 2419 /* Apply default values of current mode */2420 reg_list = &ov5670->cur_mode->reg_list;2421 ret = ov5670_write_reg_list(ov5670, reg_list);2422 if (ret) {2423 dev_err(&client->dev, "%s failed to set mode\n", __func__);2424 return ret;2425 }2426 2427 ret = ov5670_mipi_configure(ov5670);2428 if (ret) {2429 dev_err(&client->dev, "%s failed to configure MIPI\n", __func__);2430 return ret;2431 }2432 2433 ret = __v4l2_ctrl_handler_setup(ov5670->sd.ctrl_handler);2434 if (ret)2435 return ret;2436 2437 /* Write stream on list */2438 ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT,2439 OV5670_REG_VALUE_08BIT, OV5670_MODE_STREAMING);2440 if (ret) {2441 dev_err(&client->dev, "%s failed to set stream\n", __func__);2442 return ret;2443 }2444 2445 return 0;2446}2447 2448static int ov5670_stop_streaming(struct ov5670 *ov5670)2449{2450 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2451 int ret;2452 2453 ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT,2454 OV5670_REG_VALUE_08BIT, OV5670_MODE_STANDBY);2455 if (ret)2456 dev_err(&client->dev, "%s failed to set stream\n", __func__);2457 2458 /* Return success even if it was an error, as there is nothing the2459 * caller can do about it.2460 */2461 return 0;2462}2463 2464static int ov5670_set_stream(struct v4l2_subdev *sd, int enable)2465{2466 struct ov5670 *ov5670 = to_ov5670(sd);2467 struct i2c_client *client = v4l2_get_subdevdata(sd);2468 int ret = 0;2469 2470 mutex_lock(&ov5670->mutex);2471 2472 if (enable) {2473 ret = pm_runtime_resume_and_get(&client->dev);2474 if (ret < 0)2475 goto unlock_and_return;2476 2477 ret = ov5670_start_streaming(ov5670);2478 if (ret)2479 goto error;2480 } else {2481 ret = ov5670_stop_streaming(ov5670);2482 pm_runtime_put(&client->dev);2483 }2484 goto unlock_and_return;2485 2486error:2487 pm_runtime_put(&client->dev);2488 2489unlock_and_return:2490 mutex_unlock(&ov5670->mutex);2491 2492 return ret;2493}2494 2495static int __maybe_unused ov5670_runtime_resume(struct device *dev)2496{2497 struct i2c_client *client = to_i2c_client(dev);2498 struct v4l2_subdev *sd = i2c_get_clientdata(client);2499 struct ov5670 *ov5670 = to_ov5670(sd);2500 unsigned long delay_us;2501 int ret;2502 2503 ret = clk_prepare_enable(ov5670->xvclk);2504 if (ret)2505 return ret;2506 2507 ret = regulator_bulk_enable(OV5670_NUM_SUPPLIES, ov5670->supplies);2508 if (ret) {2509 clk_disable_unprepare(ov5670->xvclk);2510 return ret;2511 }2512 2513 gpiod_set_value_cansleep(ov5670->pwdn_gpio, 0);2514 gpiod_set_value_cansleep(ov5670->reset_gpio, 0);2515 2516 /* 8192 * 2 clock pulses before the first SCCB transaction. */2517 delay_us = DIV_ROUND_UP(8192 * 2 * 1000,2518 DIV_ROUND_UP(OV5670_XVCLK_FREQ, 1000));2519 fsleep(delay_us);2520 2521 return 0;2522}2523 2524static int __maybe_unused ov5670_runtime_suspend(struct device *dev)2525{2526 struct i2c_client *client = to_i2c_client(dev);2527 struct v4l2_subdev *sd = i2c_get_clientdata(client);2528 struct ov5670 *ov5670 = to_ov5670(sd);2529 2530 gpiod_set_value_cansleep(ov5670->reset_gpio, 1);2531 gpiod_set_value_cansleep(ov5670->pwdn_gpio, 1);2532 regulator_bulk_disable(OV5670_NUM_SUPPLIES, ov5670->supplies);2533 clk_disable_unprepare(ov5670->xvclk);2534 2535 return 0;2536}2537 2538static const struct v4l2_subdev_core_ops ov5670_core_ops = {2539 .log_status = v4l2_ctrl_subdev_log_status,2540 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,2541 .unsubscribe_event = v4l2_event_subdev_unsubscribe,2542};2543 2544static const struct v4l2_rect *2545__ov5670_get_pad_crop(struct ov5670 *sensor, struct v4l2_subdev_state *state,2546 unsigned int pad, enum v4l2_subdev_format_whence which)2547{2548 const struct ov5670_mode *mode = sensor->cur_mode;2549 2550 switch (which) {2551 case V4L2_SUBDEV_FORMAT_TRY:2552 return v4l2_subdev_state_get_crop(state, pad);2553 case V4L2_SUBDEV_FORMAT_ACTIVE:2554 return mode->analog_crop;2555 }2556 2557 return NULL;2558}2559 2560static int ov5670_get_selection(struct v4l2_subdev *subdev,2561 struct v4l2_subdev_state *state,2562 struct v4l2_subdev_selection *sel)2563{2564 struct ov5670 *sensor = to_ov5670(subdev);2565 2566 switch (sel->target) {2567 case V4L2_SEL_TGT_CROP:2568 mutex_lock(&sensor->mutex);2569 sel->r = *__ov5670_get_pad_crop(sensor, state, sel->pad,2570 sel->which);2571 mutex_unlock(&sensor->mutex);2572 break;2573 case V4L2_SEL_TGT_NATIVE_SIZE:2574 case V4L2_SEL_TGT_CROP_BOUNDS:2575 sel->r.top = 0;2576 sel->r.left = 0;2577 sel->r.width = OV5670_NATIVE_WIDTH;2578 sel->r.height = OV5670_NATIVE_HEIGHT;2579 break;2580 case V4L2_SEL_TGT_CROP_DEFAULT:2581 sel->r = ov5670_analog_crop;2582 break;2583 default:2584 return -EINVAL;2585 }2586 2587 return 0;2588}2589 2590static const struct v4l2_subdev_video_ops ov5670_video_ops = {2591 .s_stream = ov5670_set_stream,2592};2593 2594static const struct v4l2_subdev_pad_ops ov5670_pad_ops = {2595 .enum_mbus_code = ov5670_enum_mbus_code,2596 .get_fmt = ov5670_get_pad_format,2597 .set_fmt = ov5670_set_pad_format,2598 .enum_frame_size = ov5670_enum_frame_size,2599 .get_selection = ov5670_get_selection,2600 .set_selection = ov5670_get_selection,2601};2602 2603static const struct v4l2_subdev_sensor_ops ov5670_sensor_ops = {2604 .g_skip_frames = ov5670_get_skip_frames,2605};2606 2607static const struct v4l2_subdev_ops ov5670_subdev_ops = {2608 .core = &ov5670_core_ops,2609 .video = &ov5670_video_ops,2610 .pad = &ov5670_pad_ops,2611 .sensor = &ov5670_sensor_ops,2612};2613 2614static const struct v4l2_subdev_internal_ops ov5670_internal_ops = {2615 .init_state = ov5670_init_state,2616};2617 2618static const struct media_entity_operations ov5670_subdev_entity_ops = {2619 .link_validate = v4l2_subdev_link_validate,2620};2621 2622static int ov5670_regulators_probe(struct ov5670 *ov5670)2623{2624 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2625 unsigned int i;2626 2627 for (i = 0; i < OV5670_NUM_SUPPLIES; i++)2628 ov5670->supplies[i].supply = ov5670_supply_names[i];2629 2630 return devm_regulator_bulk_get(&client->dev, OV5670_NUM_SUPPLIES,2631 ov5670->supplies);2632}2633 2634static int ov5670_gpio_probe(struct ov5670 *ov5670)2635{2636 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);2637 2638 ov5670->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",2639 GPIOD_OUT_LOW);2640 if (IS_ERR(ov5670->pwdn_gpio))2641 return PTR_ERR(ov5670->pwdn_gpio);2642 2643 ov5670->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",2644 GPIOD_OUT_LOW);2645 if (IS_ERR(ov5670->reset_gpio))2646 return PTR_ERR(ov5670->reset_gpio);2647 2648 return 0;2649}2650 2651static int ov5670_probe(struct i2c_client *client)2652{2653 struct fwnode_handle *handle;2654 struct ov5670 *ov5670;2655 u32 input_clk = 0;2656 bool full_power;2657 int ret;2658 2659 ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL);2660 if (!ov5670)2661 return -ENOMEM;2662 2663 ov5670->xvclk = devm_clk_get_optional(&client->dev, NULL);2664 if (!IS_ERR_OR_NULL(ov5670->xvclk))2665 input_clk = clk_get_rate(ov5670->xvclk);2666 else if (!ov5670->xvclk || PTR_ERR(ov5670->xvclk) == -ENOENT)2667 device_property_read_u32(&client->dev, "clock-frequency",2668 &input_clk);2669 else2670 return dev_err_probe(&client->dev, PTR_ERR(ov5670->xvclk),2671 "error getting clock\n");2672 2673 if (input_clk != OV5670_XVCLK_FREQ) {2674 dev_err(&client->dev,2675 "Unsupported clock frequency %u\n", input_clk);2676 return -EINVAL;2677 }2678 2679 /* Initialize subdev */2680 v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);2681 ov5670->sd.internal_ops = &ov5670_internal_ops;2682 2683 ret = ov5670_regulators_probe(ov5670);2684 if (ret)2685 return dev_err_probe(&client->dev, ret, "Regulators probe failed\n");2686 2687 ret = ov5670_gpio_probe(ov5670);2688 if (ret)2689 return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");2690 2691 /* Graph Endpoint */2692 handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);2693 if (!handle)2694 return dev_err_probe(&client->dev, -ENXIO, "Endpoint for node get failed\n");2695 2696 ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;2697 ov5670->endpoint.bus.mipi_csi2.num_data_lanes = 2;2698 2699 ret = v4l2_fwnode_endpoint_alloc_parse(handle, &ov5670->endpoint);2700 fwnode_handle_put(handle);2701 if (ret)2702 return dev_err_probe(&client->dev, ret, "Endpoint parse failed\n");2703 2704 full_power = acpi_dev_state_d0(&client->dev);2705 if (full_power) {2706 ret = ov5670_runtime_resume(&client->dev);2707 if (ret) {2708 dev_err_probe(&client->dev, ret, "Power up failed\n");2709 goto error_endpoint;2710 }2711 2712 /* Check module identity */2713 ret = ov5670_identify_module(ov5670);2714 if (ret) {2715 dev_err_probe(&client->dev, ret, "ov5670_identify_module() error\n");2716 goto error_power_off;2717 }2718 }2719 2720 mutex_init(&ov5670->mutex);2721 2722 /* Set default mode to max resolution */2723 ov5670->cur_mode = &supported_modes[0];2724 2725 ret = ov5670_init_controls(ov5670);2726 if (ret) {2727 dev_err_probe(&client->dev, ret, "ov5670_init_controls() error\n");2728 goto error_mutex_destroy;2729 }2730 2731 ov5670->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |2732 V4L2_SUBDEV_FL_HAS_EVENTS;2733 ov5670->sd.entity.ops = &ov5670_subdev_entity_ops;2734 ov5670->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;2735 2736 /* Source pad initialization */2737 ov5670->pad.flags = MEDIA_PAD_FL_SOURCE;2738 ret = media_entity_pads_init(&ov5670->sd.entity, 1, &ov5670->pad);2739 if (ret) {2740 dev_err_probe(&client->dev, ret, "media_entity_pads_init() error\n");2741 goto error_handler_free;2742 }2743 2744 /* Set the device's state to active if it's in D0 state. */2745 if (full_power)2746 pm_runtime_set_active(&client->dev);2747 pm_runtime_enable(&client->dev);2748 2749 /* Async register for subdev */2750 ret = v4l2_async_register_subdev_sensor(&ov5670->sd);2751 if (ret < 0) {2752 dev_err_probe(&client->dev, ret, "v4l2_async_register_subdev() error\n");2753 goto error_pm_disable;2754 }2755 2756 pm_runtime_idle(&client->dev);2757 2758 return 0;2759 2760error_pm_disable:2761 pm_runtime_disable(&client->dev);2762 2763 media_entity_cleanup(&ov5670->sd.entity);2764 2765error_handler_free:2766 v4l2_ctrl_handler_free(ov5670->sd.ctrl_handler);2767 2768error_mutex_destroy:2769 mutex_destroy(&ov5670->mutex);2770 2771error_power_off:2772 if (full_power)2773 ov5670_runtime_suspend(&client->dev);2774 2775error_endpoint:2776 v4l2_fwnode_endpoint_free(&ov5670->endpoint);2777 2778 return ret;2779}2780 2781static void ov5670_remove(struct i2c_client *client)2782{2783 struct v4l2_subdev *sd = i2c_get_clientdata(client);2784 struct ov5670 *ov5670 = to_ov5670(sd);2785 2786 v4l2_async_unregister_subdev(sd);2787 media_entity_cleanup(&sd->entity);2788 v4l2_ctrl_handler_free(sd->ctrl_handler);2789 mutex_destroy(&ov5670->mutex);2790 2791 pm_runtime_disable(&client->dev);2792 ov5670_runtime_suspend(&client->dev);2793 2794 v4l2_fwnode_endpoint_free(&ov5670->endpoint);2795}2796 2797static const struct dev_pm_ops ov5670_pm_ops = {2798 SET_RUNTIME_PM_OPS(ov5670_runtime_suspend, ov5670_runtime_resume, NULL)2799};2800 2801#ifdef CONFIG_ACPI2802static const struct acpi_device_id ov5670_acpi_ids[] = {2803 { "INT3479" },2804 { /* sentinel */ }2805};2806 2807MODULE_DEVICE_TABLE(acpi, ov5670_acpi_ids);2808#endif2809 2810static const struct of_device_id ov5670_of_ids[] = {2811 { .compatible = "ovti,ov5670" },2812 { /* sentinel */ }2813};2814MODULE_DEVICE_TABLE(of, ov5670_of_ids);2815 2816static struct i2c_driver ov5670_i2c_driver = {2817 .driver = {2818 .name = "ov5670",2819 .pm = &ov5670_pm_ops,2820 .acpi_match_table = ACPI_PTR(ov5670_acpi_ids),2821 .of_match_table = ov5670_of_ids,2822 },2823 .probe = ov5670_probe,2824 .remove = ov5670_remove,2825 .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,2826};2827 2828module_i2c_driver(ov5670_i2c_driver);2829 2830MODULE_AUTHOR("Rapolu, Chiranjeevi");2831MODULE_AUTHOR("Yang, Hyungwoo");2832MODULE_DESCRIPTION("Omnivision ov5670 sensor driver");2833MODULE_LICENSE("GPL v2");2834