File Index
Files and directories
Sign in
FILE

ov5670.c

File preview with syntax highlighting.

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