brintos

brintos / linux-shallow public Read only

0
0
Text · 57.8 KiB · f051045 Raw
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 *)&reg_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