xref: /linux/drivers/media/i2c/ov5675.c (revision bf27502b1f3bf8095bf81736e506d354a2ce9ec4)
1*bf27502bSShawn Tu // SPDX-License-Identifier: GPL-2.0
2*bf27502bSShawn Tu // Copyright (c) 2019 Intel Corporation.
3*bf27502bSShawn Tu 
4*bf27502bSShawn Tu #include <asm/unaligned.h>
5*bf27502bSShawn Tu #include <linux/acpi.h>
6*bf27502bSShawn Tu #include <linux/delay.h>
7*bf27502bSShawn Tu #include <linux/i2c.h>
8*bf27502bSShawn Tu #include <linux/module.h>
9*bf27502bSShawn Tu #include <linux/pm_runtime.h>
10*bf27502bSShawn Tu #include <media/v4l2-ctrls.h>
11*bf27502bSShawn Tu #include <media/v4l2-device.h>
12*bf27502bSShawn Tu #include <media/v4l2-fwnode.h>
13*bf27502bSShawn Tu 
14*bf27502bSShawn Tu #define OV5675_REG_VALUE_08BIT		1
15*bf27502bSShawn Tu #define OV5675_REG_VALUE_16BIT		2
16*bf27502bSShawn Tu #define OV5675_REG_VALUE_24BIT		3
17*bf27502bSShawn Tu 
18*bf27502bSShawn Tu #define OV5675_LINK_FREQ_450MHZ		450000000ULL
19*bf27502bSShawn Tu #define OV5675_SCLK			90000000LL
20*bf27502bSShawn Tu #define OV5675_MCLK			19200000
21*bf27502bSShawn Tu #define OV5675_DATA_LANES		2
22*bf27502bSShawn Tu #define OV5675_RGB_DEPTH		10
23*bf27502bSShawn Tu 
24*bf27502bSShawn Tu #define OV5675_REG_CHIP_ID		0x300a
25*bf27502bSShawn Tu #define OV5675_CHIP_ID			0x5675
26*bf27502bSShawn Tu 
27*bf27502bSShawn Tu #define OV5675_REG_MODE_SELECT		0x0100
28*bf27502bSShawn Tu #define OV5675_MODE_STANDBY		0x00
29*bf27502bSShawn Tu #define OV5675_MODE_STREAMING		0x01
30*bf27502bSShawn Tu 
31*bf27502bSShawn Tu /* vertical-timings from sensor */
32*bf27502bSShawn Tu #define OV5675_REG_VTS			0x380e
33*bf27502bSShawn Tu #define OV5675_VTS_30FPS		0x07e4
34*bf27502bSShawn Tu #define OV5675_VTS_30FPS_MIN		0x07e4
35*bf27502bSShawn Tu #define OV5675_VTS_MAX			0x7fff
36*bf27502bSShawn Tu 
37*bf27502bSShawn Tu /* horizontal-timings from sensor */
38*bf27502bSShawn Tu #define OV5675_REG_HTS			0x380c
39*bf27502bSShawn Tu 
40*bf27502bSShawn Tu /* Exposure controls from sensor */
41*bf27502bSShawn Tu #define OV5675_REG_EXPOSURE		0x3500
42*bf27502bSShawn Tu #define	OV5675_EXPOSURE_MIN		4
43*bf27502bSShawn Tu #define OV5675_EXPOSURE_MAX_MARGIN	4
44*bf27502bSShawn Tu #define	OV5675_EXPOSURE_STEP		1
45*bf27502bSShawn Tu 
46*bf27502bSShawn Tu /* Analog gain controls from sensor */
47*bf27502bSShawn Tu #define OV5675_REG_ANALOG_GAIN		0x3508
48*bf27502bSShawn Tu #define	OV5675_ANAL_GAIN_MIN		128
49*bf27502bSShawn Tu #define	OV5675_ANAL_GAIN_MAX		2047
50*bf27502bSShawn Tu #define	OV5675_ANAL_GAIN_STEP		1
51*bf27502bSShawn Tu 
52*bf27502bSShawn Tu /* Digital gain controls from sensor */
53*bf27502bSShawn Tu #define OV5675_REG_MWB_R_GAIN		0x5019
54*bf27502bSShawn Tu #define OV5675_REG_MWB_G_GAIN		0x501b
55*bf27502bSShawn Tu #define OV5675_REG_MWB_B_GAIN		0x501d
56*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_MIN		0
57*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_MAX		4095
58*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_STEP		1
59*bf27502bSShawn Tu #define OV5675_DGTL_GAIN_DEFAULT	1024
60*bf27502bSShawn Tu 
61*bf27502bSShawn Tu /* Test Pattern Control */
62*bf27502bSShawn Tu #define OV5675_REG_TEST_PATTERN		0x4503
63*bf27502bSShawn Tu #define OV5675_TEST_PATTERN_ENABLE	BIT(7)
64*bf27502bSShawn Tu #define OV5675_TEST_PATTERN_BAR_SHIFT	2
65*bf27502bSShawn Tu 
66*bf27502bSShawn Tu #define to_ov5675(_sd)			container_of(_sd, struct ov5675, sd)
67*bf27502bSShawn Tu 
68*bf27502bSShawn Tu enum {
69*bf27502bSShawn Tu 	OV5675_LINK_FREQ_900MBPS,
70*bf27502bSShawn Tu };
71*bf27502bSShawn Tu 
72*bf27502bSShawn Tu struct ov5675_reg {
73*bf27502bSShawn Tu 	u16 address;
74*bf27502bSShawn Tu 	u8 val;
75*bf27502bSShawn Tu };
76*bf27502bSShawn Tu 
77*bf27502bSShawn Tu struct ov5675_reg_list {
78*bf27502bSShawn Tu 	u32 num_of_regs;
79*bf27502bSShawn Tu 	const struct ov5675_reg *regs;
80*bf27502bSShawn Tu };
81*bf27502bSShawn Tu 
82*bf27502bSShawn Tu struct ov5675_link_freq_config {
83*bf27502bSShawn Tu 	const struct ov5675_reg_list reg_list;
84*bf27502bSShawn Tu };
85*bf27502bSShawn Tu 
86*bf27502bSShawn Tu struct ov5675_mode {
87*bf27502bSShawn Tu 	/* Frame width in pixels */
88*bf27502bSShawn Tu 	u32 width;
89*bf27502bSShawn Tu 
90*bf27502bSShawn Tu 	/* Frame height in pixels */
91*bf27502bSShawn Tu 	u32 height;
92*bf27502bSShawn Tu 
93*bf27502bSShawn Tu 	/* Horizontal timining size */
94*bf27502bSShawn Tu 	u32 hts;
95*bf27502bSShawn Tu 
96*bf27502bSShawn Tu 	/* Default vertical timining size */
97*bf27502bSShawn Tu 	u32 vts_def;
98*bf27502bSShawn Tu 
99*bf27502bSShawn Tu 	/* Min vertical timining size */
100*bf27502bSShawn Tu 	u32 vts_min;
101*bf27502bSShawn Tu 
102*bf27502bSShawn Tu 	/* Link frequency needed for this resolution */
103*bf27502bSShawn Tu 	u32 link_freq_index;
104*bf27502bSShawn Tu 
105*bf27502bSShawn Tu 	/* Sensor register settings for this resolution */
106*bf27502bSShawn Tu 	const struct ov5675_reg_list reg_list;
107*bf27502bSShawn Tu };
108*bf27502bSShawn Tu 
109*bf27502bSShawn Tu static const struct ov5675_reg mipi_data_rate_900mbps[] = {
110*bf27502bSShawn Tu 	{0x0103, 0x01},
111*bf27502bSShawn Tu 	{0x0100, 0x00},
112*bf27502bSShawn Tu 	{0x0300, 0x04},
113*bf27502bSShawn Tu 	{0x0302, 0x8d},
114*bf27502bSShawn Tu 	{0x0303, 0x00},
115*bf27502bSShawn Tu 	{0x030d, 0x26},
116*bf27502bSShawn Tu };
117*bf27502bSShawn Tu 
118*bf27502bSShawn Tu static const struct ov5675_reg mode_2592x1944_regs[] = {
119*bf27502bSShawn Tu 	{0x3002, 0x21},
120*bf27502bSShawn Tu 	{0x3107, 0x23},
121*bf27502bSShawn Tu 	{0x3501, 0x20},
122*bf27502bSShawn Tu 	{0x3503, 0x0c},
123*bf27502bSShawn Tu 	{0x3508, 0x03},
124*bf27502bSShawn Tu 	{0x3509, 0x00},
125*bf27502bSShawn Tu 	{0x3600, 0x66},
126*bf27502bSShawn Tu 	{0x3602, 0x30},
127*bf27502bSShawn Tu 	{0x3610, 0xa5},
128*bf27502bSShawn Tu 	{0x3612, 0x93},
129*bf27502bSShawn Tu 	{0x3620, 0x80},
130*bf27502bSShawn Tu 	{0x3642, 0x0e},
131*bf27502bSShawn Tu 	{0x3661, 0x00},
132*bf27502bSShawn Tu 	{0x3662, 0x10},
133*bf27502bSShawn Tu 	{0x3664, 0xf3},
134*bf27502bSShawn Tu 	{0x3665, 0x9e},
135*bf27502bSShawn Tu 	{0x3667, 0xa5},
136*bf27502bSShawn Tu 	{0x366e, 0x55},
137*bf27502bSShawn Tu 	{0x366f, 0x55},
138*bf27502bSShawn Tu 	{0x3670, 0x11},
139*bf27502bSShawn Tu 	{0x3671, 0x11},
140*bf27502bSShawn Tu 	{0x3672, 0x11},
141*bf27502bSShawn Tu 	{0x3673, 0x11},
142*bf27502bSShawn Tu 	{0x3714, 0x24},
143*bf27502bSShawn Tu 	{0x371a, 0x3e},
144*bf27502bSShawn Tu 	{0x3733, 0x10},
145*bf27502bSShawn Tu 	{0x3734, 0x00},
146*bf27502bSShawn Tu 	{0x373d, 0x24},
147*bf27502bSShawn Tu 	{0x3764, 0x20},
148*bf27502bSShawn Tu 	{0x3765, 0x20},
149*bf27502bSShawn Tu 	{0x3766, 0x12},
150*bf27502bSShawn Tu 	{0x37a1, 0x14},
151*bf27502bSShawn Tu 	{0x37a8, 0x1c},
152*bf27502bSShawn Tu 	{0x37ab, 0x0f},
153*bf27502bSShawn Tu 	{0x37c2, 0x04},
154*bf27502bSShawn Tu 	{0x37cb, 0x00},
155*bf27502bSShawn Tu 	{0x37cc, 0x00},
156*bf27502bSShawn Tu 	{0x37cd, 0x00},
157*bf27502bSShawn Tu 	{0x37ce, 0x00},
158*bf27502bSShawn Tu 	{0x37d8, 0x02},
159*bf27502bSShawn Tu 	{0x37d9, 0x08},
160*bf27502bSShawn Tu 	{0x37dc, 0x04},
161*bf27502bSShawn Tu 	{0x3800, 0x00},
162*bf27502bSShawn Tu 	{0x3801, 0x00},
163*bf27502bSShawn Tu 	{0x3802, 0x00},
164*bf27502bSShawn Tu 	{0x3803, 0x04},
165*bf27502bSShawn Tu 	{0x3804, 0x0a},
166*bf27502bSShawn Tu 	{0x3805, 0x3f},
167*bf27502bSShawn Tu 	{0x3806, 0x07},
168*bf27502bSShawn Tu 	{0x3807, 0xb3},
169*bf27502bSShawn Tu 	{0x3808, 0x0a},
170*bf27502bSShawn Tu 	{0x3809, 0x20},
171*bf27502bSShawn Tu 	{0x380a, 0x07},
172*bf27502bSShawn Tu 	{0x380b, 0x98},
173*bf27502bSShawn Tu 	{0x380c, 0x02},
174*bf27502bSShawn Tu 	{0x380d, 0xee},
175*bf27502bSShawn Tu 	{0x380e, 0x07},
176*bf27502bSShawn Tu 	{0x380f, 0xe4},
177*bf27502bSShawn Tu 	{0x3811, 0x10},
178*bf27502bSShawn Tu 	{0x3813, 0x0d},
179*bf27502bSShawn Tu 	{0x3814, 0x01},
180*bf27502bSShawn Tu 	{0x3815, 0x01},
181*bf27502bSShawn Tu 	{0x3816, 0x01},
182*bf27502bSShawn Tu 	{0x3817, 0x01},
183*bf27502bSShawn Tu 	{0x381e, 0x02},
184*bf27502bSShawn Tu 	{0x3820, 0x88},
185*bf27502bSShawn Tu 	{0x3821, 0x01},
186*bf27502bSShawn Tu 	{0x3832, 0x04},
187*bf27502bSShawn Tu 	{0x3c80, 0x01},
188*bf27502bSShawn Tu 	{0x3c82, 0x00},
189*bf27502bSShawn Tu 	{0x3c83, 0xc8},
190*bf27502bSShawn Tu 	{0x3c8c, 0x0f},
191*bf27502bSShawn Tu 	{0x3c8d, 0xa0},
192*bf27502bSShawn Tu 	{0x3c90, 0x07},
193*bf27502bSShawn Tu 	{0x3c91, 0x00},
194*bf27502bSShawn Tu 	{0x3c92, 0x00},
195*bf27502bSShawn Tu 	{0x3c93, 0x00},
196*bf27502bSShawn Tu 	{0x3c94, 0xd0},
197*bf27502bSShawn Tu 	{0x3c95, 0x50},
198*bf27502bSShawn Tu 	{0x3c96, 0x35},
199*bf27502bSShawn Tu 	{0x3c97, 0x00},
200*bf27502bSShawn Tu 	{0x4001, 0xe0},
201*bf27502bSShawn Tu 	{0x4008, 0x02},
202*bf27502bSShawn Tu 	{0x4009, 0x0d},
203*bf27502bSShawn Tu 	{0x400f, 0x80},
204*bf27502bSShawn Tu 	{0x4013, 0x02},
205*bf27502bSShawn Tu 	{0x4040, 0x00},
206*bf27502bSShawn Tu 	{0x4041, 0x07},
207*bf27502bSShawn Tu 	{0x404c, 0x50},
208*bf27502bSShawn Tu 	{0x404e, 0x20},
209*bf27502bSShawn Tu 	{0x4500, 0x06},
210*bf27502bSShawn Tu 	{0x4503, 0x00},
211*bf27502bSShawn Tu 	{0x450a, 0x04},
212*bf27502bSShawn Tu 	{0x4809, 0x04},
213*bf27502bSShawn Tu 	{0x480c, 0x12},
214*bf27502bSShawn Tu 	{0x4819, 0x70},
215*bf27502bSShawn Tu 	{0x4825, 0x32},
216*bf27502bSShawn Tu 	{0x4826, 0x32},
217*bf27502bSShawn Tu 	{0x482a, 0x06},
218*bf27502bSShawn Tu 	{0x4833, 0x08},
219*bf27502bSShawn Tu 	{0x4837, 0x0d},
220*bf27502bSShawn Tu 	{0x5000, 0x77},
221*bf27502bSShawn Tu 	{0x5b00, 0x01},
222*bf27502bSShawn Tu 	{0x5b01, 0x10},
223*bf27502bSShawn Tu 	{0x5b02, 0x01},
224*bf27502bSShawn Tu 	{0x5b03, 0xdb},
225*bf27502bSShawn Tu 	{0x5b05, 0x6c},
226*bf27502bSShawn Tu 	{0x5e10, 0xfc},
227*bf27502bSShawn Tu 	{0x3500, 0x00},
228*bf27502bSShawn Tu 	{0x3501, 0x3E},
229*bf27502bSShawn Tu 	{0x3502, 0x60},
230*bf27502bSShawn Tu 	{0x3503, 0x08},
231*bf27502bSShawn Tu 	{0x3508, 0x04},
232*bf27502bSShawn Tu 	{0x3509, 0x00},
233*bf27502bSShawn Tu 	{0x3832, 0x48},
234*bf27502bSShawn Tu 	{0x5780, 0x3e},
235*bf27502bSShawn Tu 	{0x5781, 0x0f},
236*bf27502bSShawn Tu 	{0x5782, 0x44},
237*bf27502bSShawn Tu 	{0x5783, 0x02},
238*bf27502bSShawn Tu 	{0x5784, 0x01},
239*bf27502bSShawn Tu 	{0x5785, 0x01},
240*bf27502bSShawn Tu 	{0x5786, 0x00},
241*bf27502bSShawn Tu 	{0x5787, 0x04},
242*bf27502bSShawn Tu 	{0x5788, 0x02},
243*bf27502bSShawn Tu 	{0x5789, 0x0f},
244*bf27502bSShawn Tu 	{0x578a, 0xfd},
245*bf27502bSShawn Tu 	{0x578b, 0xf5},
246*bf27502bSShawn Tu 	{0x578c, 0xf5},
247*bf27502bSShawn Tu 	{0x578d, 0x03},
248*bf27502bSShawn Tu 	{0x578e, 0x08},
249*bf27502bSShawn Tu 	{0x578f, 0x0c},
250*bf27502bSShawn Tu 	{0x5790, 0x08},
251*bf27502bSShawn Tu 	{0x5791, 0x06},
252*bf27502bSShawn Tu 	{0x5792, 0x00},
253*bf27502bSShawn Tu 	{0x5793, 0x52},
254*bf27502bSShawn Tu 	{0x5794, 0xa3},
255*bf27502bSShawn Tu 	{0x4003, 0x40},
256*bf27502bSShawn Tu 	{0x3107, 0x01},
257*bf27502bSShawn Tu 	{0x3c80, 0x08},
258*bf27502bSShawn Tu 	{0x3c83, 0xb1},
259*bf27502bSShawn Tu 	{0x3c8c, 0x10},
260*bf27502bSShawn Tu 	{0x3c8d, 0x00},
261*bf27502bSShawn Tu 	{0x3c90, 0x00},
262*bf27502bSShawn Tu 	{0x3c94, 0x00},
263*bf27502bSShawn Tu 	{0x3c95, 0x00},
264*bf27502bSShawn Tu 	{0x3c96, 0x00},
265*bf27502bSShawn Tu 	{0x37cb, 0x09},
266*bf27502bSShawn Tu 	{0x37cc, 0x15},
267*bf27502bSShawn Tu 	{0x37cd, 0x1f},
268*bf27502bSShawn Tu 	{0x37ce, 0x1f},
269*bf27502bSShawn Tu };
270*bf27502bSShawn Tu 
271*bf27502bSShawn Tu static const struct ov5675_reg mode_1296x972_regs[] = {
272*bf27502bSShawn Tu 	{0x3002, 0x21},
273*bf27502bSShawn Tu 	{0x3107, 0x23},
274*bf27502bSShawn Tu 	{0x3501, 0x20},
275*bf27502bSShawn Tu 	{0x3503, 0x0c},
276*bf27502bSShawn Tu 	{0x3508, 0x03},
277*bf27502bSShawn Tu 	{0x3509, 0x00},
278*bf27502bSShawn Tu 	{0x3600, 0x66},
279*bf27502bSShawn Tu 	{0x3602, 0x30},
280*bf27502bSShawn Tu 	{0x3610, 0xa5},
281*bf27502bSShawn Tu 	{0x3612, 0x93},
282*bf27502bSShawn Tu 	{0x3620, 0x80},
283*bf27502bSShawn Tu 	{0x3642, 0x0e},
284*bf27502bSShawn Tu 	{0x3661, 0x00},
285*bf27502bSShawn Tu 	{0x3662, 0x08},
286*bf27502bSShawn Tu 	{0x3664, 0xf3},
287*bf27502bSShawn Tu 	{0x3665, 0x9e},
288*bf27502bSShawn Tu 	{0x3667, 0xa5},
289*bf27502bSShawn Tu 	{0x366e, 0x55},
290*bf27502bSShawn Tu 	{0x366f, 0x55},
291*bf27502bSShawn Tu 	{0x3670, 0x11},
292*bf27502bSShawn Tu 	{0x3671, 0x11},
293*bf27502bSShawn Tu 	{0x3672, 0x11},
294*bf27502bSShawn Tu 	{0x3673, 0x11},
295*bf27502bSShawn Tu 	{0x3714, 0x28},
296*bf27502bSShawn Tu 	{0x371a, 0x3e},
297*bf27502bSShawn Tu 	{0x3733, 0x10},
298*bf27502bSShawn Tu 	{0x3734, 0x00},
299*bf27502bSShawn Tu 	{0x373d, 0x24},
300*bf27502bSShawn Tu 	{0x3764, 0x20},
301*bf27502bSShawn Tu 	{0x3765, 0x20},
302*bf27502bSShawn Tu 	{0x3766, 0x12},
303*bf27502bSShawn Tu 	{0x37a1, 0x14},
304*bf27502bSShawn Tu 	{0x37a8, 0x1c},
305*bf27502bSShawn Tu 	{0x37ab, 0x0f},
306*bf27502bSShawn Tu 	{0x37c2, 0x14},
307*bf27502bSShawn Tu 	{0x37cb, 0x00},
308*bf27502bSShawn Tu 	{0x37cc, 0x00},
309*bf27502bSShawn Tu 	{0x37cd, 0x00},
310*bf27502bSShawn Tu 	{0x37ce, 0x00},
311*bf27502bSShawn Tu 	{0x37d8, 0x02},
312*bf27502bSShawn Tu 	{0x37d9, 0x04},
313*bf27502bSShawn Tu 	{0x37dc, 0x04},
314*bf27502bSShawn Tu 	{0x3800, 0x00},
315*bf27502bSShawn Tu 	{0x3801, 0x00},
316*bf27502bSShawn Tu 	{0x3802, 0x00},
317*bf27502bSShawn Tu 	{0x3803, 0xf4},
318*bf27502bSShawn Tu 	{0x3804, 0x0a},
319*bf27502bSShawn Tu 	{0x3805, 0x3f},
320*bf27502bSShawn Tu 	{0x3806, 0x06},
321*bf27502bSShawn Tu 	{0x3807, 0xb3},
322*bf27502bSShawn Tu 	{0x3808, 0x05},
323*bf27502bSShawn Tu 	{0x3809, 0x00},
324*bf27502bSShawn Tu 	{0x380a, 0x02},
325*bf27502bSShawn Tu 	{0x380b, 0xd0},
326*bf27502bSShawn Tu 	{0x380c, 0x02},
327*bf27502bSShawn Tu 	{0x380d, 0xee},
328*bf27502bSShawn Tu 	{0x380e, 0x07},
329*bf27502bSShawn Tu 	{0x380f, 0xe4},
330*bf27502bSShawn Tu 	{0x3811, 0x10},
331*bf27502bSShawn Tu 	{0x3813, 0x09},
332*bf27502bSShawn Tu 	{0x3814, 0x03},
333*bf27502bSShawn Tu 	{0x3815, 0x01},
334*bf27502bSShawn Tu 	{0x3816, 0x03},
335*bf27502bSShawn Tu 	{0x3817, 0x01},
336*bf27502bSShawn Tu 	{0x381e, 0x02},
337*bf27502bSShawn Tu 	{0x3820, 0x8b},
338*bf27502bSShawn Tu 	{0x3821, 0x01},
339*bf27502bSShawn Tu 	{0x3832, 0x04},
340*bf27502bSShawn Tu 	{0x3c80, 0x01},
341*bf27502bSShawn Tu 	{0x3c82, 0x00},
342*bf27502bSShawn Tu 	{0x3c83, 0xc8},
343*bf27502bSShawn Tu 	{0x3c8c, 0x0f},
344*bf27502bSShawn Tu 	{0x3c8d, 0xa0},
345*bf27502bSShawn Tu 	{0x3c90, 0x07},
346*bf27502bSShawn Tu 	{0x3c91, 0x00},
347*bf27502bSShawn Tu 	{0x3c92, 0x00},
348*bf27502bSShawn Tu 	{0x3c93, 0x00},
349*bf27502bSShawn Tu 	{0x3c94, 0xd0},
350*bf27502bSShawn Tu 	{0x3c95, 0x50},
351*bf27502bSShawn Tu 	{0x3c96, 0x35},
352*bf27502bSShawn Tu 	{0x3c97, 0x00},
353*bf27502bSShawn Tu 	{0x4001, 0xe0},
354*bf27502bSShawn Tu 	{0x4008, 0x00},
355*bf27502bSShawn Tu 	{0x4009, 0x07},
356*bf27502bSShawn Tu 	{0x400f, 0x80},
357*bf27502bSShawn Tu 	{0x4013, 0x02},
358*bf27502bSShawn Tu 	{0x4040, 0x00},
359*bf27502bSShawn Tu 	{0x4041, 0x03},
360*bf27502bSShawn Tu 	{0x404c, 0x50},
361*bf27502bSShawn Tu 	{0x404e, 0x20},
362*bf27502bSShawn Tu 	{0x4500, 0x06},
363*bf27502bSShawn Tu 	{0x4503, 0x00},
364*bf27502bSShawn Tu 	{0x450a, 0x04},
365*bf27502bSShawn Tu 	{0x4809, 0x04},
366*bf27502bSShawn Tu 	{0x480c, 0x12},
367*bf27502bSShawn Tu 	{0x4819, 0x70},
368*bf27502bSShawn Tu 	{0x4825, 0x32},
369*bf27502bSShawn Tu 	{0x4826, 0x32},
370*bf27502bSShawn Tu 	{0x482a, 0x06},
371*bf27502bSShawn Tu 	{0x4833, 0x08},
372*bf27502bSShawn Tu 	{0x4837, 0x0d},
373*bf27502bSShawn Tu 	{0x5000, 0x77},
374*bf27502bSShawn Tu 	{0x5b00, 0x01},
375*bf27502bSShawn Tu 	{0x5b01, 0x10},
376*bf27502bSShawn Tu 	{0x5b02, 0x01},
377*bf27502bSShawn Tu 	{0x5b03, 0xdb},
378*bf27502bSShawn Tu 	{0x5b05, 0x6c},
379*bf27502bSShawn Tu 	{0x5e10, 0xfc},
380*bf27502bSShawn Tu 	{0x3500, 0x00},
381*bf27502bSShawn Tu 	{0x3501, 0x1F},
382*bf27502bSShawn Tu 	{0x3502, 0x20},
383*bf27502bSShawn Tu 	{0x3503, 0x08},
384*bf27502bSShawn Tu 	{0x3508, 0x04},
385*bf27502bSShawn Tu 	{0x3509, 0x00},
386*bf27502bSShawn Tu 	{0x3832, 0x48},
387*bf27502bSShawn Tu 	{0x5780, 0x3e},
388*bf27502bSShawn Tu 	{0x5781, 0x0f},
389*bf27502bSShawn Tu 	{0x5782, 0x44},
390*bf27502bSShawn Tu 	{0x5783, 0x02},
391*bf27502bSShawn Tu 	{0x5784, 0x01},
392*bf27502bSShawn Tu 	{0x5785, 0x01},
393*bf27502bSShawn Tu 	{0x5786, 0x00},
394*bf27502bSShawn Tu 	{0x5787, 0x04},
395*bf27502bSShawn Tu 	{0x5788, 0x02},
396*bf27502bSShawn Tu 	{0x5789, 0x0f},
397*bf27502bSShawn Tu 	{0x578a, 0xfd},
398*bf27502bSShawn Tu 	{0x578b, 0xf5},
399*bf27502bSShawn Tu 	{0x578c, 0xf5},
400*bf27502bSShawn Tu 	{0x578d, 0x03},
401*bf27502bSShawn Tu 	{0x578e, 0x08},
402*bf27502bSShawn Tu 	{0x578f, 0x0c},
403*bf27502bSShawn Tu 	{0x5790, 0x08},
404*bf27502bSShawn Tu 	{0x5791, 0x06},
405*bf27502bSShawn Tu 	{0x5792, 0x00},
406*bf27502bSShawn Tu 	{0x5793, 0x52},
407*bf27502bSShawn Tu 	{0x5794, 0xa3},
408*bf27502bSShawn Tu 	{0x4003, 0x40},
409*bf27502bSShawn Tu 	{0x3107, 0x01},
410*bf27502bSShawn Tu 	{0x3c80, 0x08},
411*bf27502bSShawn Tu 	{0x3c83, 0xb1},
412*bf27502bSShawn Tu 	{0x3c8c, 0x10},
413*bf27502bSShawn Tu 	{0x3c8d, 0x00},
414*bf27502bSShawn Tu 	{0x3c90, 0x00},
415*bf27502bSShawn Tu 	{0x3c94, 0x00},
416*bf27502bSShawn Tu 	{0x3c95, 0x00},
417*bf27502bSShawn Tu 	{0x3c96, 0x00},
418*bf27502bSShawn Tu 	{0x37cb, 0x09},
419*bf27502bSShawn Tu 	{0x37cc, 0x15},
420*bf27502bSShawn Tu 	{0x37cd, 0x1f},
421*bf27502bSShawn Tu 	{0x37ce, 0x1f},
422*bf27502bSShawn Tu };
423*bf27502bSShawn Tu 
424*bf27502bSShawn Tu static const char * const ov5675_test_pattern_menu[] = {
425*bf27502bSShawn Tu 	"Disabled",
426*bf27502bSShawn Tu 	"Standard Color Bar",
427*bf27502bSShawn Tu 	"Top-Bottom Darker Color Bar",
428*bf27502bSShawn Tu 	"Right-Left Darker Color Bar",
429*bf27502bSShawn Tu 	"Bottom-Top Darker Color Bar"
430*bf27502bSShawn Tu };
431*bf27502bSShawn Tu 
432*bf27502bSShawn Tu static const s64 link_freq_menu_items[] = {
433*bf27502bSShawn Tu 	OV5675_LINK_FREQ_450MHZ,
434*bf27502bSShawn Tu };
435*bf27502bSShawn Tu 
436*bf27502bSShawn Tu static const struct ov5675_link_freq_config link_freq_configs[] = {
437*bf27502bSShawn Tu 	[OV5675_LINK_FREQ_900MBPS] = {
438*bf27502bSShawn Tu 		.reg_list = {
439*bf27502bSShawn Tu 			.num_of_regs = ARRAY_SIZE(mipi_data_rate_900mbps),
440*bf27502bSShawn Tu 			.regs = mipi_data_rate_900mbps,
441*bf27502bSShawn Tu 		}
442*bf27502bSShawn Tu 	}
443*bf27502bSShawn Tu };
444*bf27502bSShawn Tu 
445*bf27502bSShawn Tu static const struct ov5675_mode supported_modes[] = {
446*bf27502bSShawn Tu 	{
447*bf27502bSShawn Tu 		.width = 2592,
448*bf27502bSShawn Tu 		.height = 1944,
449*bf27502bSShawn Tu 		.hts = 1500,
450*bf27502bSShawn Tu 		.vts_def = OV5675_VTS_30FPS,
451*bf27502bSShawn Tu 		.vts_min = OV5675_VTS_30FPS_MIN,
452*bf27502bSShawn Tu 		.reg_list = {
453*bf27502bSShawn Tu 			.num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),
454*bf27502bSShawn Tu 			.regs = mode_2592x1944_regs,
455*bf27502bSShawn Tu 		},
456*bf27502bSShawn Tu 		.link_freq_index = OV5675_LINK_FREQ_900MBPS,
457*bf27502bSShawn Tu 	},
458*bf27502bSShawn Tu 	{
459*bf27502bSShawn Tu 		.width = 1296,
460*bf27502bSShawn Tu 		.height = 972,
461*bf27502bSShawn Tu 		.hts = 1500,
462*bf27502bSShawn Tu 		.vts_def = OV5675_VTS_30FPS,
463*bf27502bSShawn Tu 		.vts_min = OV5675_VTS_30FPS_MIN,
464*bf27502bSShawn Tu 		.reg_list = {
465*bf27502bSShawn Tu 			.num_of_regs = ARRAY_SIZE(mode_1296x972_regs),
466*bf27502bSShawn Tu 			.regs = mode_1296x972_regs,
467*bf27502bSShawn Tu 		},
468*bf27502bSShawn Tu 		.link_freq_index = OV5675_LINK_FREQ_900MBPS,
469*bf27502bSShawn Tu 	}
470*bf27502bSShawn Tu };
471*bf27502bSShawn Tu 
472*bf27502bSShawn Tu struct ov5675 {
473*bf27502bSShawn Tu 	struct v4l2_subdev sd;
474*bf27502bSShawn Tu 	struct media_pad pad;
475*bf27502bSShawn Tu 	struct v4l2_ctrl_handler ctrl_handler;
476*bf27502bSShawn Tu 
477*bf27502bSShawn Tu 	/* V4L2 Controls */
478*bf27502bSShawn Tu 	struct v4l2_ctrl *link_freq;
479*bf27502bSShawn Tu 	struct v4l2_ctrl *pixel_rate;
480*bf27502bSShawn Tu 	struct v4l2_ctrl *vblank;
481*bf27502bSShawn Tu 	struct v4l2_ctrl *hblank;
482*bf27502bSShawn Tu 	struct v4l2_ctrl *exposure;
483*bf27502bSShawn Tu 
484*bf27502bSShawn Tu 	/* Current mode */
485*bf27502bSShawn Tu 	const struct ov5675_mode *cur_mode;
486*bf27502bSShawn Tu 
487*bf27502bSShawn Tu 	/* To serialize asynchronus callbacks */
488*bf27502bSShawn Tu 	struct mutex mutex;
489*bf27502bSShawn Tu 
490*bf27502bSShawn Tu 	/* Streaming on/off */
491*bf27502bSShawn Tu 	bool streaming;
492*bf27502bSShawn Tu };
493*bf27502bSShawn Tu 
494*bf27502bSShawn Tu static u64 to_pixel_rate(u32 f_index)
495*bf27502bSShawn Tu {
496*bf27502bSShawn Tu 	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV5675_DATA_LANES;
497*bf27502bSShawn Tu 
498*bf27502bSShawn Tu 	do_div(pixel_rate, OV5675_RGB_DEPTH);
499*bf27502bSShawn Tu 
500*bf27502bSShawn Tu 	return pixel_rate;
501*bf27502bSShawn Tu }
502*bf27502bSShawn Tu 
503*bf27502bSShawn Tu static u64 to_pixels_per_line(u32 hts, u32 f_index)
504*bf27502bSShawn Tu {
505*bf27502bSShawn Tu 	u64 ppl = hts * to_pixel_rate(f_index);
506*bf27502bSShawn Tu 
507*bf27502bSShawn Tu 	do_div(ppl, OV5675_SCLK);
508*bf27502bSShawn Tu 
509*bf27502bSShawn Tu 	return ppl;
510*bf27502bSShawn Tu }
511*bf27502bSShawn Tu 
512*bf27502bSShawn Tu static int ov5675_read_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 *val)
513*bf27502bSShawn Tu {
514*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
515*bf27502bSShawn Tu 	struct i2c_msg msgs[2];
516*bf27502bSShawn Tu 	u8 addr_buf[2];
517*bf27502bSShawn Tu 	u8 data_buf[4] = {0};
518*bf27502bSShawn Tu 	int ret;
519*bf27502bSShawn Tu 
520*bf27502bSShawn Tu 	if (len > 4)
521*bf27502bSShawn Tu 		return -EINVAL;
522*bf27502bSShawn Tu 
523*bf27502bSShawn Tu 	put_unaligned_be16(reg, addr_buf);
524*bf27502bSShawn Tu 	msgs[0].addr = client->addr;
525*bf27502bSShawn Tu 	msgs[0].flags = 0;
526*bf27502bSShawn Tu 	msgs[0].len = sizeof(addr_buf);
527*bf27502bSShawn Tu 	msgs[0].buf = addr_buf;
528*bf27502bSShawn Tu 	msgs[1].addr = client->addr;
529*bf27502bSShawn Tu 	msgs[1].flags = I2C_M_RD;
530*bf27502bSShawn Tu 	msgs[1].len = len;
531*bf27502bSShawn Tu 	msgs[1].buf = &data_buf[4 - len];
532*bf27502bSShawn Tu 
533*bf27502bSShawn Tu 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
534*bf27502bSShawn Tu 	if (ret != ARRAY_SIZE(msgs))
535*bf27502bSShawn Tu 		return -EIO;
536*bf27502bSShawn Tu 
537*bf27502bSShawn Tu 	*val = get_unaligned_be32(data_buf);
538*bf27502bSShawn Tu 
539*bf27502bSShawn Tu 	return 0;
540*bf27502bSShawn Tu }
541*bf27502bSShawn Tu 
542*bf27502bSShawn Tu static int ov5675_write_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 val)
543*bf27502bSShawn Tu {
544*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
545*bf27502bSShawn Tu 	u8 buf[6];
546*bf27502bSShawn Tu 
547*bf27502bSShawn Tu 	if (len > 4)
548*bf27502bSShawn Tu 		return -EINVAL;
549*bf27502bSShawn Tu 
550*bf27502bSShawn Tu 	put_unaligned_be16(reg, buf);
551*bf27502bSShawn Tu 	put_unaligned_be32(val << 8 * (4 - len), buf + 2);
552*bf27502bSShawn Tu 	if (i2c_master_send(client, buf, len + 2) != len + 2)
553*bf27502bSShawn Tu 		return -EIO;
554*bf27502bSShawn Tu 
555*bf27502bSShawn Tu 	return 0;
556*bf27502bSShawn Tu }
557*bf27502bSShawn Tu 
558*bf27502bSShawn Tu static int ov5675_write_reg_list(struct ov5675 *ov5675,
559*bf27502bSShawn Tu 				 const struct ov5675_reg_list *r_list)
560*bf27502bSShawn Tu {
561*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
562*bf27502bSShawn Tu 	unsigned int i;
563*bf27502bSShawn Tu 	int ret;
564*bf27502bSShawn Tu 
565*bf27502bSShawn Tu 	for (i = 0; i < r_list->num_of_regs; i++) {
566*bf27502bSShawn Tu 		ret = ov5675_write_reg(ov5675, r_list->regs[i].address, 1,
567*bf27502bSShawn Tu 				       r_list->regs[i].val);
568*bf27502bSShawn Tu 		if (ret) {
569*bf27502bSShawn Tu 			dev_err_ratelimited(&client->dev,
570*bf27502bSShawn Tu 				    "failed to write reg 0x%4.4x. error = %d",
571*bf27502bSShawn Tu 				    r_list->regs[i].address, ret);
572*bf27502bSShawn Tu 			return ret;
573*bf27502bSShawn Tu 		}
574*bf27502bSShawn Tu 	}
575*bf27502bSShawn Tu 
576*bf27502bSShawn Tu 	return 0;
577*bf27502bSShawn Tu }
578*bf27502bSShawn Tu 
579*bf27502bSShawn Tu static int ov5675_update_digital_gain(struct ov5675 *ov5675, u32 d_gain)
580*bf27502bSShawn Tu {
581*bf27502bSShawn Tu 	int ret;
582*bf27502bSShawn Tu 
583*bf27502bSShawn Tu 	ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_R_GAIN,
584*bf27502bSShawn Tu 			       OV5675_REG_VALUE_16BIT, d_gain);
585*bf27502bSShawn Tu 	if (ret)
586*bf27502bSShawn Tu 		return ret;
587*bf27502bSShawn Tu 
588*bf27502bSShawn Tu 	ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_G_GAIN,
589*bf27502bSShawn Tu 			       OV5675_REG_VALUE_16BIT, d_gain);
590*bf27502bSShawn Tu 	if (ret)
591*bf27502bSShawn Tu 		return ret;
592*bf27502bSShawn Tu 
593*bf27502bSShawn Tu 	return ov5675_write_reg(ov5675, OV5675_REG_MWB_B_GAIN,
594*bf27502bSShawn Tu 				OV5675_REG_VALUE_16BIT, d_gain);
595*bf27502bSShawn Tu }
596*bf27502bSShawn Tu 
597*bf27502bSShawn Tu static int ov5675_test_pattern(struct ov5675 *ov5675, u32 pattern)
598*bf27502bSShawn Tu {
599*bf27502bSShawn Tu 	if (pattern)
600*bf27502bSShawn Tu 		pattern = (pattern - 1) << OV5675_TEST_PATTERN_BAR_SHIFT |
601*bf27502bSShawn Tu 			  OV5675_TEST_PATTERN_ENABLE;
602*bf27502bSShawn Tu 
603*bf27502bSShawn Tu 	return ov5675_write_reg(ov5675, OV5675_REG_TEST_PATTERN,
604*bf27502bSShawn Tu 				OV5675_REG_VALUE_08BIT, pattern);
605*bf27502bSShawn Tu }
606*bf27502bSShawn Tu 
607*bf27502bSShawn Tu static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
608*bf27502bSShawn Tu {
609*bf27502bSShawn Tu 	struct ov5675 *ov5675 = container_of(ctrl->handler,
610*bf27502bSShawn Tu 					     struct ov5675, ctrl_handler);
611*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
612*bf27502bSShawn Tu 	s64 exposure_max;
613*bf27502bSShawn Tu 	int ret = 0;
614*bf27502bSShawn Tu 
615*bf27502bSShawn Tu 	/* Propagate change of current control to all related controls */
616*bf27502bSShawn Tu 	if (ctrl->id == V4L2_CID_VBLANK) {
617*bf27502bSShawn Tu 		/* Update max exposure while meeting expected vblanking */
618*bf27502bSShawn Tu 		exposure_max = (ov5675->cur_mode->height + ctrl->val -
619*bf27502bSShawn Tu 			       OV5675_EXPOSURE_MAX_MARGIN) / 2;
620*bf27502bSShawn Tu 		__v4l2_ctrl_modify_range(ov5675->exposure,
621*bf27502bSShawn Tu 					 ov5675->exposure->minimum,
622*bf27502bSShawn Tu 					 exposure_max, ov5675->exposure->step,
623*bf27502bSShawn Tu 					 exposure_max);
624*bf27502bSShawn Tu 	}
625*bf27502bSShawn Tu 
626*bf27502bSShawn Tu 	/* V4L2 controls values will be applied only when power is already up */
627*bf27502bSShawn Tu 	if (!pm_runtime_get_if_in_use(&client->dev))
628*bf27502bSShawn Tu 		return 0;
629*bf27502bSShawn Tu 
630*bf27502bSShawn Tu 	switch (ctrl->id) {
631*bf27502bSShawn Tu 	case V4L2_CID_ANALOGUE_GAIN:
632*bf27502bSShawn Tu 		ret = ov5675_write_reg(ov5675, OV5675_REG_ANALOG_GAIN,
633*bf27502bSShawn Tu 				       OV5675_REG_VALUE_16BIT, ctrl->val);
634*bf27502bSShawn Tu 		break;
635*bf27502bSShawn Tu 
636*bf27502bSShawn Tu 	case V4L2_CID_DIGITAL_GAIN:
637*bf27502bSShawn Tu 		ret = ov5675_update_digital_gain(ov5675, ctrl->val);
638*bf27502bSShawn Tu 		break;
639*bf27502bSShawn Tu 
640*bf27502bSShawn Tu 	case V4L2_CID_EXPOSURE:
641*bf27502bSShawn Tu 		/* 3 least significant bits of expsoure are fractional part */
642*bf27502bSShawn Tu 		ret = ov5675_write_reg(ov5675, OV5675_REG_EXPOSURE,
643*bf27502bSShawn Tu 				       OV5675_REG_VALUE_24BIT, ctrl->val << 3);
644*bf27502bSShawn Tu 		break;
645*bf27502bSShawn Tu 
646*bf27502bSShawn Tu 	case V4L2_CID_VBLANK:
647*bf27502bSShawn Tu 		ret = ov5675_write_reg(ov5675, OV5675_REG_VTS,
648*bf27502bSShawn Tu 				       OV5675_REG_VALUE_16BIT,
649*bf27502bSShawn Tu 				       ov5675->cur_mode->height + ctrl->val +
650*bf27502bSShawn Tu 				       10);
651*bf27502bSShawn Tu 		break;
652*bf27502bSShawn Tu 
653*bf27502bSShawn Tu 	case V4L2_CID_TEST_PATTERN:
654*bf27502bSShawn Tu 		ret = ov5675_test_pattern(ov5675, ctrl->val);
655*bf27502bSShawn Tu 		break;
656*bf27502bSShawn Tu 
657*bf27502bSShawn Tu 	default:
658*bf27502bSShawn Tu 		ret = -EINVAL;
659*bf27502bSShawn Tu 		break;
660*bf27502bSShawn Tu 	}
661*bf27502bSShawn Tu 
662*bf27502bSShawn Tu 	pm_runtime_put(&client->dev);
663*bf27502bSShawn Tu 
664*bf27502bSShawn Tu 	return ret;
665*bf27502bSShawn Tu }
666*bf27502bSShawn Tu 
667*bf27502bSShawn Tu static const struct v4l2_ctrl_ops ov5675_ctrl_ops = {
668*bf27502bSShawn Tu 	.s_ctrl = ov5675_set_ctrl,
669*bf27502bSShawn Tu };
670*bf27502bSShawn Tu 
671*bf27502bSShawn Tu static int ov5675_init_controls(struct ov5675 *ov5675)
672*bf27502bSShawn Tu {
673*bf27502bSShawn Tu 	struct v4l2_ctrl_handler *ctrl_hdlr;
674*bf27502bSShawn Tu 	s64 exposure_max, h_blank;
675*bf27502bSShawn Tu 	int ret;
676*bf27502bSShawn Tu 
677*bf27502bSShawn Tu 	ctrl_hdlr = &ov5675->ctrl_handler;
678*bf27502bSShawn Tu 	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
679*bf27502bSShawn Tu 	if (ret)
680*bf27502bSShawn Tu 		return ret;
681*bf27502bSShawn Tu 
682*bf27502bSShawn Tu 	ctrl_hdlr->lock = &ov5675->mutex;
683*bf27502bSShawn Tu 	ov5675->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov5675_ctrl_ops,
684*bf27502bSShawn Tu 					   V4L2_CID_LINK_FREQ,
685*bf27502bSShawn Tu 					   ARRAY_SIZE(link_freq_menu_items) - 1,
686*bf27502bSShawn Tu 					   0, link_freq_menu_items);
687*bf27502bSShawn Tu 	if (ov5675->link_freq)
688*bf27502bSShawn Tu 		ov5675->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
689*bf27502bSShawn Tu 
690*bf27502bSShawn Tu 	ov5675->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
691*bf27502bSShawn Tu 				       V4L2_CID_PIXEL_RATE, 0,
692*bf27502bSShawn Tu 				       to_pixel_rate(OV5675_LINK_FREQ_900MBPS),
693*bf27502bSShawn Tu 				       1,
694*bf27502bSShawn Tu 				       to_pixel_rate(OV5675_LINK_FREQ_900MBPS));
695*bf27502bSShawn Tu 	ov5675->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
696*bf27502bSShawn Tu 			  V4L2_CID_VBLANK,
697*bf27502bSShawn Tu 			  ov5675->cur_mode->vts_min - ov5675->cur_mode->height,
698*bf27502bSShawn Tu 			  OV5675_VTS_MAX - ov5675->cur_mode->height, 1,
699*bf27502bSShawn Tu 			  ov5675->cur_mode->vts_def - ov5675->cur_mode->height);
700*bf27502bSShawn Tu 	h_blank = to_pixels_per_line(ov5675->cur_mode->hts,
701*bf27502bSShawn Tu 		  ov5675->cur_mode->link_freq_index) - ov5675->cur_mode->width;
702*bf27502bSShawn Tu 	ov5675->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
703*bf27502bSShawn Tu 					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
704*bf27502bSShawn Tu 					   h_blank);
705*bf27502bSShawn Tu 	if (ov5675->hblank)
706*bf27502bSShawn Tu 		ov5675->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
707*bf27502bSShawn Tu 
708*bf27502bSShawn Tu 	v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
709*bf27502bSShawn Tu 			  OV5675_ANAL_GAIN_MIN, OV5675_ANAL_GAIN_MAX,
710*bf27502bSShawn Tu 			  OV5675_ANAL_GAIN_STEP, OV5675_ANAL_GAIN_MIN);
711*bf27502bSShawn Tu 	v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
712*bf27502bSShawn Tu 			  OV5675_DGTL_GAIN_MIN, OV5675_DGTL_GAIN_MAX,
713*bf27502bSShawn Tu 			  OV5675_DGTL_GAIN_STEP, OV5675_DGTL_GAIN_DEFAULT);
714*bf27502bSShawn Tu 	exposure_max = (ov5675->cur_mode->vts_def -
715*bf27502bSShawn Tu 			OV5675_EXPOSURE_MAX_MARGIN) / 2;
716*bf27502bSShawn Tu 	ov5675->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
717*bf27502bSShawn Tu 					     V4L2_CID_EXPOSURE,
718*bf27502bSShawn Tu 					     OV5675_EXPOSURE_MIN, exposure_max,
719*bf27502bSShawn Tu 					     OV5675_EXPOSURE_STEP,
720*bf27502bSShawn Tu 					     exposure_max);
721*bf27502bSShawn Tu 	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5675_ctrl_ops,
722*bf27502bSShawn Tu 				     V4L2_CID_TEST_PATTERN,
723*bf27502bSShawn Tu 				     ARRAY_SIZE(ov5675_test_pattern_menu) - 1,
724*bf27502bSShawn Tu 				     0, 0, ov5675_test_pattern_menu);
725*bf27502bSShawn Tu 	if (ctrl_hdlr->error)
726*bf27502bSShawn Tu 		return ctrl_hdlr->error;
727*bf27502bSShawn Tu 
728*bf27502bSShawn Tu 	ov5675->sd.ctrl_handler = ctrl_hdlr;
729*bf27502bSShawn Tu 
730*bf27502bSShawn Tu 	return 0;
731*bf27502bSShawn Tu }
732*bf27502bSShawn Tu 
733*bf27502bSShawn Tu static void ov5675_update_pad_format(const struct ov5675_mode *mode,
734*bf27502bSShawn Tu 				     struct v4l2_mbus_framefmt *fmt)
735*bf27502bSShawn Tu {
736*bf27502bSShawn Tu 	fmt->width = mode->width;
737*bf27502bSShawn Tu 	fmt->height = mode->height;
738*bf27502bSShawn Tu 	fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
739*bf27502bSShawn Tu 	fmt->field = V4L2_FIELD_NONE;
740*bf27502bSShawn Tu }
741*bf27502bSShawn Tu 
742*bf27502bSShawn Tu static int ov5675_start_streaming(struct ov5675 *ov5675)
743*bf27502bSShawn Tu {
744*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
745*bf27502bSShawn Tu 	const struct ov5675_reg_list *reg_list;
746*bf27502bSShawn Tu 	int link_freq_index, ret;
747*bf27502bSShawn Tu 
748*bf27502bSShawn Tu 	link_freq_index = ov5675->cur_mode->link_freq_index;
749*bf27502bSShawn Tu 	reg_list = &link_freq_configs[link_freq_index].reg_list;
750*bf27502bSShawn Tu 	ret = ov5675_write_reg_list(ov5675, reg_list);
751*bf27502bSShawn Tu 	if (ret) {
752*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to set plls");
753*bf27502bSShawn Tu 		return ret;
754*bf27502bSShawn Tu 	}
755*bf27502bSShawn Tu 
756*bf27502bSShawn Tu 	reg_list = &ov5675->cur_mode->reg_list;
757*bf27502bSShawn Tu 	ret = ov5675_write_reg_list(ov5675, reg_list);
758*bf27502bSShawn Tu 	if (ret) {
759*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to set mode");
760*bf27502bSShawn Tu 		return ret;
761*bf27502bSShawn Tu 	}
762*bf27502bSShawn Tu 
763*bf27502bSShawn Tu 	ret = __v4l2_ctrl_handler_setup(ov5675->sd.ctrl_handler);
764*bf27502bSShawn Tu 	if (ret)
765*bf27502bSShawn Tu 		return ret;
766*bf27502bSShawn Tu 
767*bf27502bSShawn Tu 	ret = ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
768*bf27502bSShawn Tu 			       OV5675_REG_VALUE_08BIT, OV5675_MODE_STREAMING);
769*bf27502bSShawn Tu 	if (ret) {
770*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to set stream");
771*bf27502bSShawn Tu 		return ret;
772*bf27502bSShawn Tu 	}
773*bf27502bSShawn Tu 
774*bf27502bSShawn Tu 	return 0;
775*bf27502bSShawn Tu }
776*bf27502bSShawn Tu 
777*bf27502bSShawn Tu static void ov5675_stop_streaming(struct ov5675 *ov5675)
778*bf27502bSShawn Tu {
779*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
780*bf27502bSShawn Tu 
781*bf27502bSShawn Tu 	if (ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
782*bf27502bSShawn Tu 			     OV5675_REG_VALUE_08BIT, OV5675_MODE_STANDBY))
783*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to set stream");
784*bf27502bSShawn Tu }
785*bf27502bSShawn Tu 
786*bf27502bSShawn Tu static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
787*bf27502bSShawn Tu {
788*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
789*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(sd);
790*bf27502bSShawn Tu 	int ret = 0;
791*bf27502bSShawn Tu 
792*bf27502bSShawn Tu 	if (ov5675->streaming == enable)
793*bf27502bSShawn Tu 		return 0;
794*bf27502bSShawn Tu 
795*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
796*bf27502bSShawn Tu 	if (enable) {
797*bf27502bSShawn Tu 		ret = pm_runtime_get_sync(&client->dev);
798*bf27502bSShawn Tu 		if (ret < 0) {
799*bf27502bSShawn Tu 			pm_runtime_put_noidle(&client->dev);
800*bf27502bSShawn Tu 			mutex_unlock(&ov5675->mutex);
801*bf27502bSShawn Tu 			return ret;
802*bf27502bSShawn Tu 		}
803*bf27502bSShawn Tu 
804*bf27502bSShawn Tu 		ret = ov5675_start_streaming(ov5675);
805*bf27502bSShawn Tu 		if (ret) {
806*bf27502bSShawn Tu 			enable = 0;
807*bf27502bSShawn Tu 			ov5675_stop_streaming(ov5675);
808*bf27502bSShawn Tu 			pm_runtime_put(&client->dev);
809*bf27502bSShawn Tu 		}
810*bf27502bSShawn Tu 	} else {
811*bf27502bSShawn Tu 		ov5675_stop_streaming(ov5675);
812*bf27502bSShawn Tu 		pm_runtime_put(&client->dev);
813*bf27502bSShawn Tu 	}
814*bf27502bSShawn Tu 
815*bf27502bSShawn Tu 	ov5675->streaming = enable;
816*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
817*bf27502bSShawn Tu 
818*bf27502bSShawn Tu 	return ret;
819*bf27502bSShawn Tu }
820*bf27502bSShawn Tu 
821*bf27502bSShawn Tu static int __maybe_unused ov5675_suspend(struct device *dev)
822*bf27502bSShawn Tu {
823*bf27502bSShawn Tu 	struct i2c_client *client = to_i2c_client(dev);
824*bf27502bSShawn Tu 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
825*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
826*bf27502bSShawn Tu 
827*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
828*bf27502bSShawn Tu 	if (ov5675->streaming)
829*bf27502bSShawn Tu 		ov5675_stop_streaming(ov5675);
830*bf27502bSShawn Tu 
831*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
832*bf27502bSShawn Tu 
833*bf27502bSShawn Tu 	return 0;
834*bf27502bSShawn Tu }
835*bf27502bSShawn Tu 
836*bf27502bSShawn Tu static int __maybe_unused ov5675_resume(struct device *dev)
837*bf27502bSShawn Tu {
838*bf27502bSShawn Tu 	struct i2c_client *client = to_i2c_client(dev);
839*bf27502bSShawn Tu 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
840*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
841*bf27502bSShawn Tu 	int ret;
842*bf27502bSShawn Tu 
843*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
844*bf27502bSShawn Tu 	if (ov5675->streaming) {
845*bf27502bSShawn Tu 		ret = ov5675_start_streaming(ov5675);
846*bf27502bSShawn Tu 		if (ret) {
847*bf27502bSShawn Tu 			ov5675->streaming = false;
848*bf27502bSShawn Tu 			ov5675_stop_streaming(ov5675);
849*bf27502bSShawn Tu 			mutex_unlock(&ov5675->mutex);
850*bf27502bSShawn Tu 			return ret;
851*bf27502bSShawn Tu 		}
852*bf27502bSShawn Tu 	}
853*bf27502bSShawn Tu 
854*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
855*bf27502bSShawn Tu 
856*bf27502bSShawn Tu 	return 0;
857*bf27502bSShawn Tu }
858*bf27502bSShawn Tu 
859*bf27502bSShawn Tu static int ov5675_set_format(struct v4l2_subdev *sd,
860*bf27502bSShawn Tu 			     struct v4l2_subdev_pad_config *cfg,
861*bf27502bSShawn Tu 			     struct v4l2_subdev_format *fmt)
862*bf27502bSShawn Tu {
863*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
864*bf27502bSShawn Tu 	const struct ov5675_mode *mode;
865*bf27502bSShawn Tu 	s32 vblank_def, h_blank;
866*bf27502bSShawn Tu 
867*bf27502bSShawn Tu 	mode = v4l2_find_nearest_size(supported_modes,
868*bf27502bSShawn Tu 				      ARRAY_SIZE(supported_modes), width,
869*bf27502bSShawn Tu 				      height, fmt->format.width,
870*bf27502bSShawn Tu 				      fmt->format.height);
871*bf27502bSShawn Tu 
872*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
873*bf27502bSShawn Tu 	ov5675_update_pad_format(mode, &fmt->format);
874*bf27502bSShawn Tu 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
875*bf27502bSShawn Tu 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
876*bf27502bSShawn Tu 	} else {
877*bf27502bSShawn Tu 		ov5675->cur_mode = mode;
878*bf27502bSShawn Tu 		__v4l2_ctrl_s_ctrl(ov5675->link_freq, mode->link_freq_index);
879*bf27502bSShawn Tu 		__v4l2_ctrl_s_ctrl_int64(ov5675->pixel_rate,
880*bf27502bSShawn Tu 					 to_pixel_rate(mode->link_freq_index));
881*bf27502bSShawn Tu 
882*bf27502bSShawn Tu 		/* Update limits and set FPS to default */
883*bf27502bSShawn Tu 		vblank_def = mode->vts_def - mode->height;
884*bf27502bSShawn Tu 		__v4l2_ctrl_modify_range(ov5675->vblank,
885*bf27502bSShawn Tu 					 mode->vts_min - mode->height,
886*bf27502bSShawn Tu 					 OV5675_VTS_MAX - mode->height, 1,
887*bf27502bSShawn Tu 					 vblank_def);
888*bf27502bSShawn Tu 		__v4l2_ctrl_s_ctrl(ov5675->vblank, vblank_def);
889*bf27502bSShawn Tu 		h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
890*bf27502bSShawn Tu 			  mode->width;
891*bf27502bSShawn Tu 		__v4l2_ctrl_modify_range(ov5675->hblank, h_blank, h_blank, 1,
892*bf27502bSShawn Tu 					 h_blank);
893*bf27502bSShawn Tu 	}
894*bf27502bSShawn Tu 
895*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
896*bf27502bSShawn Tu 
897*bf27502bSShawn Tu 	return 0;
898*bf27502bSShawn Tu }
899*bf27502bSShawn Tu 
900*bf27502bSShawn Tu static int ov5675_get_format(struct v4l2_subdev *sd,
901*bf27502bSShawn Tu 			     struct v4l2_subdev_pad_config *cfg,
902*bf27502bSShawn Tu 			     struct v4l2_subdev_format *fmt)
903*bf27502bSShawn Tu {
904*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
905*bf27502bSShawn Tu 
906*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
907*bf27502bSShawn Tu 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
908*bf27502bSShawn Tu 		fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, cfg,
909*bf27502bSShawn Tu 							  fmt->pad);
910*bf27502bSShawn Tu 	else
911*bf27502bSShawn Tu 		ov5675_update_pad_format(ov5675->cur_mode, &fmt->format);
912*bf27502bSShawn Tu 
913*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
914*bf27502bSShawn Tu 
915*bf27502bSShawn Tu 	return 0;
916*bf27502bSShawn Tu }
917*bf27502bSShawn Tu 
918*bf27502bSShawn Tu static int ov5675_enum_mbus_code(struct v4l2_subdev *sd,
919*bf27502bSShawn Tu 				 struct v4l2_subdev_pad_config *cfg,
920*bf27502bSShawn Tu 				 struct v4l2_subdev_mbus_code_enum *code)
921*bf27502bSShawn Tu {
922*bf27502bSShawn Tu 	if (code->index > 0)
923*bf27502bSShawn Tu 		return -EINVAL;
924*bf27502bSShawn Tu 
925*bf27502bSShawn Tu 	code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
926*bf27502bSShawn Tu 
927*bf27502bSShawn Tu 	return 0;
928*bf27502bSShawn Tu }
929*bf27502bSShawn Tu 
930*bf27502bSShawn Tu static int ov5675_enum_frame_size(struct v4l2_subdev *sd,
931*bf27502bSShawn Tu 				  struct v4l2_subdev_pad_config *cfg,
932*bf27502bSShawn Tu 				  struct v4l2_subdev_frame_size_enum *fse)
933*bf27502bSShawn Tu {
934*bf27502bSShawn Tu 	if (fse->index >= ARRAY_SIZE(supported_modes))
935*bf27502bSShawn Tu 		return -EINVAL;
936*bf27502bSShawn Tu 
937*bf27502bSShawn Tu 	if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
938*bf27502bSShawn Tu 		return -EINVAL;
939*bf27502bSShawn Tu 
940*bf27502bSShawn Tu 	fse->min_width = supported_modes[fse->index].width;
941*bf27502bSShawn Tu 	fse->max_width = fse->min_width;
942*bf27502bSShawn Tu 	fse->min_height = supported_modes[fse->index].height;
943*bf27502bSShawn Tu 	fse->max_height = fse->min_height;
944*bf27502bSShawn Tu 
945*bf27502bSShawn Tu 	return 0;
946*bf27502bSShawn Tu }
947*bf27502bSShawn Tu 
948*bf27502bSShawn Tu static int ov5675_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
949*bf27502bSShawn Tu {
950*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
951*bf27502bSShawn Tu 
952*bf27502bSShawn Tu 	mutex_lock(&ov5675->mutex);
953*bf27502bSShawn Tu 	ov5675_update_pad_format(&supported_modes[0],
954*bf27502bSShawn Tu 				 v4l2_subdev_get_try_format(sd, fh->pad, 0));
955*bf27502bSShawn Tu 	mutex_unlock(&ov5675->mutex);
956*bf27502bSShawn Tu 
957*bf27502bSShawn Tu 	return 0;
958*bf27502bSShawn Tu }
959*bf27502bSShawn Tu 
960*bf27502bSShawn Tu static const struct v4l2_subdev_video_ops ov5675_video_ops = {
961*bf27502bSShawn Tu 	.s_stream = ov5675_set_stream,
962*bf27502bSShawn Tu };
963*bf27502bSShawn Tu 
964*bf27502bSShawn Tu static const struct v4l2_subdev_pad_ops ov5675_pad_ops = {
965*bf27502bSShawn Tu 	.set_fmt = ov5675_set_format,
966*bf27502bSShawn Tu 	.get_fmt = ov5675_get_format,
967*bf27502bSShawn Tu 	.enum_mbus_code = ov5675_enum_mbus_code,
968*bf27502bSShawn Tu 	.enum_frame_size = ov5675_enum_frame_size,
969*bf27502bSShawn Tu };
970*bf27502bSShawn Tu 
971*bf27502bSShawn Tu static const struct v4l2_subdev_ops ov5675_subdev_ops = {
972*bf27502bSShawn Tu 	.video = &ov5675_video_ops,
973*bf27502bSShawn Tu 	.pad = &ov5675_pad_ops,
974*bf27502bSShawn Tu };
975*bf27502bSShawn Tu 
976*bf27502bSShawn Tu static const struct media_entity_operations ov5675_subdev_entity_ops = {
977*bf27502bSShawn Tu 	.link_validate = v4l2_subdev_link_validate,
978*bf27502bSShawn Tu };
979*bf27502bSShawn Tu 
980*bf27502bSShawn Tu static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
981*bf27502bSShawn Tu 	.open = ov5675_open,
982*bf27502bSShawn Tu };
983*bf27502bSShawn Tu 
984*bf27502bSShawn Tu static int ov5675_identify_module(struct ov5675 *ov5675)
985*bf27502bSShawn Tu {
986*bf27502bSShawn Tu 	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
987*bf27502bSShawn Tu 	int ret;
988*bf27502bSShawn Tu 	u32 val;
989*bf27502bSShawn Tu 
990*bf27502bSShawn Tu 	ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID,
991*bf27502bSShawn Tu 			      OV5675_REG_VALUE_24BIT, &val);
992*bf27502bSShawn Tu 	if (ret)
993*bf27502bSShawn Tu 		return ret;
994*bf27502bSShawn Tu 
995*bf27502bSShawn Tu 	if (val != OV5675_CHIP_ID) {
996*bf27502bSShawn Tu 		dev_err(&client->dev, "chip id mismatch: %x!=%x",
997*bf27502bSShawn Tu 			OV5675_CHIP_ID, val);
998*bf27502bSShawn Tu 		return -ENXIO;
999*bf27502bSShawn Tu 	}
1000*bf27502bSShawn Tu 
1001*bf27502bSShawn Tu 	return 0;
1002*bf27502bSShawn Tu }
1003*bf27502bSShawn Tu 
1004*bf27502bSShawn Tu static int ov5675_check_hwcfg(struct device *dev)
1005*bf27502bSShawn Tu {
1006*bf27502bSShawn Tu 	struct fwnode_handle *ep;
1007*bf27502bSShawn Tu 	struct fwnode_handle *fwnode = dev_fwnode(dev);
1008*bf27502bSShawn Tu 	struct v4l2_fwnode_endpoint bus_cfg = {
1009*bf27502bSShawn Tu 		.bus_type = V4L2_MBUS_CSI2_DPHY
1010*bf27502bSShawn Tu 	};
1011*bf27502bSShawn Tu 	u32 mclk;
1012*bf27502bSShawn Tu 	int ret;
1013*bf27502bSShawn Tu 	unsigned int i, j;
1014*bf27502bSShawn Tu 
1015*bf27502bSShawn Tu 	if (!fwnode)
1016*bf27502bSShawn Tu 		return -ENXIO;
1017*bf27502bSShawn Tu 
1018*bf27502bSShawn Tu 	ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
1019*bf27502bSShawn Tu 
1020*bf27502bSShawn Tu 	if (ret) {
1021*bf27502bSShawn Tu 		dev_err(dev, "can't get clock frequency");
1022*bf27502bSShawn Tu 		return ret;
1023*bf27502bSShawn Tu 	}
1024*bf27502bSShawn Tu 
1025*bf27502bSShawn Tu 	if (mclk != OV5675_MCLK) {
1026*bf27502bSShawn Tu 		dev_err(dev, "external clock %d is not supported", mclk);
1027*bf27502bSShawn Tu 		return -EINVAL;
1028*bf27502bSShawn Tu 	}
1029*bf27502bSShawn Tu 
1030*bf27502bSShawn Tu 	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1031*bf27502bSShawn Tu 	if (!ep)
1032*bf27502bSShawn Tu 		return -ENXIO;
1033*bf27502bSShawn Tu 
1034*bf27502bSShawn Tu 	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1035*bf27502bSShawn Tu 	fwnode_handle_put(ep);
1036*bf27502bSShawn Tu 	if (ret)
1037*bf27502bSShawn Tu 		return ret;
1038*bf27502bSShawn Tu 
1039*bf27502bSShawn Tu 	if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV5675_DATA_LANES) {
1040*bf27502bSShawn Tu 		dev_err(dev, "number of CSI2 data lanes %d is not supported",
1041*bf27502bSShawn Tu 			bus_cfg.bus.mipi_csi2.num_data_lanes);
1042*bf27502bSShawn Tu 		ret = -EINVAL;
1043*bf27502bSShawn Tu 		goto check_hwcfg_error;
1044*bf27502bSShawn Tu 	}
1045*bf27502bSShawn Tu 
1046*bf27502bSShawn Tu 	if (!bus_cfg.nr_of_link_frequencies) {
1047*bf27502bSShawn Tu 		dev_err(dev, "no link frequencies defined");
1048*bf27502bSShawn Tu 		ret = -EINVAL;
1049*bf27502bSShawn Tu 		goto check_hwcfg_error;
1050*bf27502bSShawn Tu 	}
1051*bf27502bSShawn Tu 
1052*bf27502bSShawn Tu 	for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
1053*bf27502bSShawn Tu 		for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
1054*bf27502bSShawn Tu 			if (link_freq_menu_items[i] ==
1055*bf27502bSShawn Tu 				bus_cfg.link_frequencies[j])
1056*bf27502bSShawn Tu 				break;
1057*bf27502bSShawn Tu 		}
1058*bf27502bSShawn Tu 
1059*bf27502bSShawn Tu 		if (j == bus_cfg.nr_of_link_frequencies) {
1060*bf27502bSShawn Tu 			dev_err(dev, "no link frequency %lld supported",
1061*bf27502bSShawn Tu 				link_freq_menu_items[i]);
1062*bf27502bSShawn Tu 			ret = -EINVAL;
1063*bf27502bSShawn Tu 			goto check_hwcfg_error;
1064*bf27502bSShawn Tu 		}
1065*bf27502bSShawn Tu 	}
1066*bf27502bSShawn Tu 
1067*bf27502bSShawn Tu check_hwcfg_error:
1068*bf27502bSShawn Tu 	v4l2_fwnode_endpoint_free(&bus_cfg);
1069*bf27502bSShawn Tu 
1070*bf27502bSShawn Tu 	return ret;
1071*bf27502bSShawn Tu }
1072*bf27502bSShawn Tu 
1073*bf27502bSShawn Tu static int ov5675_remove(struct i2c_client *client)
1074*bf27502bSShawn Tu {
1075*bf27502bSShawn Tu 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1076*bf27502bSShawn Tu 	struct ov5675 *ov5675 = to_ov5675(sd);
1077*bf27502bSShawn Tu 
1078*bf27502bSShawn Tu 	v4l2_async_unregister_subdev(sd);
1079*bf27502bSShawn Tu 	media_entity_cleanup(&sd->entity);
1080*bf27502bSShawn Tu 	v4l2_ctrl_handler_free(sd->ctrl_handler);
1081*bf27502bSShawn Tu 	pm_runtime_disable(&client->dev);
1082*bf27502bSShawn Tu 	mutex_destroy(&ov5675->mutex);
1083*bf27502bSShawn Tu 
1084*bf27502bSShawn Tu 	return 0;
1085*bf27502bSShawn Tu }
1086*bf27502bSShawn Tu 
1087*bf27502bSShawn Tu static int ov5675_probe(struct i2c_client *client)
1088*bf27502bSShawn Tu {
1089*bf27502bSShawn Tu 	struct ov5675 *ov5675;
1090*bf27502bSShawn Tu 	int ret;
1091*bf27502bSShawn Tu 
1092*bf27502bSShawn Tu 	ret = ov5675_check_hwcfg(&client->dev);
1093*bf27502bSShawn Tu 	if (ret) {
1094*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to check HW configuration: %d",
1095*bf27502bSShawn Tu 			ret);
1096*bf27502bSShawn Tu 		return ret;
1097*bf27502bSShawn Tu 	}
1098*bf27502bSShawn Tu 
1099*bf27502bSShawn Tu 	ov5675 = devm_kzalloc(&client->dev, sizeof(*ov5675), GFP_KERNEL);
1100*bf27502bSShawn Tu 	if (!ov5675)
1101*bf27502bSShawn Tu 		return -ENOMEM;
1102*bf27502bSShawn Tu 
1103*bf27502bSShawn Tu 	v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
1104*bf27502bSShawn Tu 	ret = ov5675_identify_module(ov5675);
1105*bf27502bSShawn Tu 	if (ret) {
1106*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to find sensor: %d", ret);
1107*bf27502bSShawn Tu 		return ret;
1108*bf27502bSShawn Tu 	}
1109*bf27502bSShawn Tu 
1110*bf27502bSShawn Tu 	mutex_init(&ov5675->mutex);
1111*bf27502bSShawn Tu 	ov5675->cur_mode = &supported_modes[0];
1112*bf27502bSShawn Tu 	ret = ov5675_init_controls(ov5675);
1113*bf27502bSShawn Tu 	if (ret) {
1114*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to init controls: %d", ret);
1115*bf27502bSShawn Tu 		goto probe_error_v4l2_ctrl_handler_free;
1116*bf27502bSShawn Tu 	}
1117*bf27502bSShawn Tu 
1118*bf27502bSShawn Tu 	ov5675->sd.internal_ops = &ov5675_internal_ops;
1119*bf27502bSShawn Tu 	ov5675->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1120*bf27502bSShawn Tu 	ov5675->sd.entity.ops = &ov5675_subdev_entity_ops;
1121*bf27502bSShawn Tu 	ov5675->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1122*bf27502bSShawn Tu 	ov5675->pad.flags = MEDIA_PAD_FL_SOURCE;
1123*bf27502bSShawn Tu 	ret = media_entity_pads_init(&ov5675->sd.entity, 1, &ov5675->pad);
1124*bf27502bSShawn Tu 	if (ret) {
1125*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to init entity pads: %d", ret);
1126*bf27502bSShawn Tu 		goto probe_error_v4l2_ctrl_handler_free;
1127*bf27502bSShawn Tu 	}
1128*bf27502bSShawn Tu 
1129*bf27502bSShawn Tu 	ret = v4l2_async_register_subdev_sensor_common(&ov5675->sd);
1130*bf27502bSShawn Tu 	if (ret < 0) {
1131*bf27502bSShawn Tu 		dev_err(&client->dev, "failed to register V4L2 subdev: %d",
1132*bf27502bSShawn Tu 			ret);
1133*bf27502bSShawn Tu 		goto probe_error_media_entity_cleanup;
1134*bf27502bSShawn Tu 	}
1135*bf27502bSShawn Tu 
1136*bf27502bSShawn Tu 	/*
1137*bf27502bSShawn Tu 	 * Device is already turned on by i2c-core with ACPI domain PM.
1138*bf27502bSShawn Tu 	 * Enable runtime PM and turn off the device.
1139*bf27502bSShawn Tu 	 */
1140*bf27502bSShawn Tu 	pm_runtime_set_active(&client->dev);
1141*bf27502bSShawn Tu 	pm_runtime_enable(&client->dev);
1142*bf27502bSShawn Tu 	pm_runtime_idle(&client->dev);
1143*bf27502bSShawn Tu 
1144*bf27502bSShawn Tu 	return 0;
1145*bf27502bSShawn Tu 
1146*bf27502bSShawn Tu probe_error_media_entity_cleanup:
1147*bf27502bSShawn Tu 	media_entity_cleanup(&ov5675->sd.entity);
1148*bf27502bSShawn Tu 
1149*bf27502bSShawn Tu probe_error_v4l2_ctrl_handler_free:
1150*bf27502bSShawn Tu 	v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler);
1151*bf27502bSShawn Tu 	mutex_destroy(&ov5675->mutex);
1152*bf27502bSShawn Tu 
1153*bf27502bSShawn Tu 	return ret;
1154*bf27502bSShawn Tu }
1155*bf27502bSShawn Tu 
1156*bf27502bSShawn Tu static const struct dev_pm_ops ov5675_pm_ops = {
1157*bf27502bSShawn Tu 	SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume)
1158*bf27502bSShawn Tu };
1159*bf27502bSShawn Tu 
1160*bf27502bSShawn Tu #ifdef CONFIG_ACPI
1161*bf27502bSShawn Tu static const struct acpi_device_id ov5675_acpi_ids[] = {
1162*bf27502bSShawn Tu 	{"OVTI5675"},
1163*bf27502bSShawn Tu 	{}
1164*bf27502bSShawn Tu };
1165*bf27502bSShawn Tu 
1166*bf27502bSShawn Tu MODULE_DEVICE_TABLE(acpi, ov5675_acpi_ids);
1167*bf27502bSShawn Tu #endif
1168*bf27502bSShawn Tu 
1169*bf27502bSShawn Tu static struct i2c_driver ov5675_i2c_driver = {
1170*bf27502bSShawn Tu 	.driver = {
1171*bf27502bSShawn Tu 		.name = "ov5675",
1172*bf27502bSShawn Tu 		.pm = &ov5675_pm_ops,
1173*bf27502bSShawn Tu 		.acpi_match_table = ACPI_PTR(ov5675_acpi_ids),
1174*bf27502bSShawn Tu 	},
1175*bf27502bSShawn Tu 	.probe_new = ov5675_probe,
1176*bf27502bSShawn Tu 	.remove = ov5675_remove,
1177*bf27502bSShawn Tu };
1178*bf27502bSShawn Tu 
1179*bf27502bSShawn Tu module_i2c_driver(ov5675_i2c_driver);
1180*bf27502bSShawn Tu 
1181*bf27502bSShawn Tu MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>");
1182*bf27502bSShawn Tu MODULE_DESCRIPTION("OmniVision OV5675 sensor driver");
1183*bf27502bSShawn Tu MODULE_LICENSE("GPL v2");
1184