1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Intel Corporation
3
4#include <asm/unaligned.h>
5#include <linux/acpi.h>
6#include <linux/i2c.h>
7#include <linux/module.h>
8#include <linux/pm_runtime.h>
9#include <media/v4l2-ctrls.h>
10#include <media/v4l2-device.h>
11#include <media/v4l2-event.h>
12#include <media/v4l2-fwnode.h>
13
14#define IMX355_REG_MODE_SELECT		0x0100
15#define IMX355_MODE_STANDBY		0x00
16#define IMX355_MODE_STREAMING		0x01
17
18/* Chip ID */
19#define IMX355_REG_CHIP_ID		0x0016
20#define IMX355_CHIP_ID			0x0355
21
22/* V_TIMING internal */
23#define IMX355_REG_FLL			0x0340
24#define IMX355_FLL_MAX			0xffff
25
26/* Exposure control */
27#define IMX355_REG_EXPOSURE		0x0202
28#define IMX355_EXPOSURE_MIN		1
29#define IMX355_EXPOSURE_STEP		1
30#define IMX355_EXPOSURE_DEFAULT		0x0282
31
32/* Analog gain control */
33#define IMX355_REG_ANALOG_GAIN		0x0204
34#define IMX355_ANA_GAIN_MIN		0
35#define IMX355_ANA_GAIN_MAX		960
36#define IMX355_ANA_GAIN_STEP		1
37#define IMX355_ANA_GAIN_DEFAULT		0
38
39/* Digital gain control */
40#define IMX355_REG_DPGA_USE_GLOBAL_GAIN	0x3070
41#define IMX355_REG_DIG_GAIN_GLOBAL	0x020e
42#define IMX355_DGTL_GAIN_MIN		256
43#define IMX355_DGTL_GAIN_MAX		4095
44#define IMX355_DGTL_GAIN_STEP		1
45#define IMX355_DGTL_GAIN_DEFAULT	256
46
47/* Test Pattern Control */
48#define IMX355_REG_TEST_PATTERN		0x0600
49#define IMX355_TEST_PATTERN_DISABLED		0
50#define IMX355_TEST_PATTERN_SOLID_COLOR		1
51#define IMX355_TEST_PATTERN_COLOR_BARS		2
52#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS	3
53#define IMX355_TEST_PATTERN_PN9			4
54
55/* Flip Control */
56#define IMX355_REG_ORIENTATION		0x0101
57
58/* default link frequency and external clock */
59#define IMX355_LINK_FREQ_DEFAULT	360000000LL
60#define IMX355_EXT_CLK			19200000
61#define IMX355_LINK_FREQ_INDEX		0
62
63struct imx355_reg {
64	u16 address;
65	u8 val;
66};
67
68struct imx355_reg_list {
69	u32 num_of_regs;
70	const struct imx355_reg *regs;
71};
72
73/* Mode : resolution and related config&values */
74struct imx355_mode {
75	/* Frame width */
76	u32 width;
77	/* Frame height */
78	u32 height;
79
80	/* V-timing */
81	u32 fll_def;
82	u32 fll_min;
83
84	/* H-timing */
85	u32 llp;
86
87	/* index of link frequency */
88	u32 link_freq_index;
89
90	/* Default register values */
91	struct imx355_reg_list reg_list;
92};
93
94struct imx355_hwcfg {
95	u32 ext_clk;			/* sensor external clk */
96	unsigned long link_freq_bitmap;
97};
98
99struct imx355 {
100	struct v4l2_subdev sd;
101	struct media_pad pad;
102
103	struct v4l2_ctrl_handler ctrl_handler;
104	/* V4L2 Controls */
105	struct v4l2_ctrl *link_freq;
106	struct v4l2_ctrl *pixel_rate;
107	struct v4l2_ctrl *vblank;
108	struct v4l2_ctrl *hblank;
109	struct v4l2_ctrl *exposure;
110	struct v4l2_ctrl *vflip;
111	struct v4l2_ctrl *hflip;
112
113	/* Current mode */
114	const struct imx355_mode *cur_mode;
115
116	struct imx355_hwcfg *hwcfg;
117
118	/*
119	 * Mutex for serialized access:
120	 * Protect sensor set pad format and start/stop streaming safely.
121	 * Protect access to sensor v4l2 controls.
122	 */
123	struct mutex mutex;
124};
125
126static const struct imx355_reg imx355_global_regs[] = {
127	{ 0x0136, 0x13 },
128	{ 0x0137, 0x33 },
129	{ 0x304e, 0x03 },
130	{ 0x4348, 0x16 },
131	{ 0x4350, 0x19 },
132	{ 0x4408, 0x0a },
133	{ 0x440c, 0x0b },
134	{ 0x4411, 0x5f },
135	{ 0x4412, 0x2c },
136	{ 0x4623, 0x00 },
137	{ 0x462c, 0x0f },
138	{ 0x462d, 0x00 },
139	{ 0x462e, 0x00 },
140	{ 0x4684, 0x54 },
141	{ 0x480a, 0x07 },
142	{ 0x4908, 0x07 },
143	{ 0x4909, 0x07 },
144	{ 0x490d, 0x0a },
145	{ 0x491e, 0x0f },
146	{ 0x4921, 0x06 },
147	{ 0x4923, 0x28 },
148	{ 0x4924, 0x28 },
149	{ 0x4925, 0x29 },
150	{ 0x4926, 0x29 },
151	{ 0x4927, 0x1f },
152	{ 0x4928, 0x20 },
153	{ 0x4929, 0x20 },
154	{ 0x492a, 0x20 },
155	{ 0x492c, 0x05 },
156	{ 0x492d, 0x06 },
157	{ 0x492e, 0x06 },
158	{ 0x492f, 0x06 },
159	{ 0x4930, 0x03 },
160	{ 0x4931, 0x04 },
161	{ 0x4932, 0x04 },
162	{ 0x4933, 0x05 },
163	{ 0x595e, 0x01 },
164	{ 0x5963, 0x01 },
165	{ 0x3030, 0x01 },
166	{ 0x3031, 0x01 },
167	{ 0x3045, 0x01 },
168	{ 0x4010, 0x00 },
169	{ 0x4011, 0x00 },
170	{ 0x4012, 0x00 },
171	{ 0x4013, 0x01 },
172	{ 0x68a8, 0xfe },
173	{ 0x68a9, 0xff },
174	{ 0x6888, 0x00 },
175	{ 0x6889, 0x00 },
176	{ 0x68b0, 0x00 },
177	{ 0x3058, 0x00 },
178	{ 0x305a, 0x00 },
179};
180
181static const struct imx355_reg_list imx355_global_setting = {
182	.num_of_regs = ARRAY_SIZE(imx355_global_regs),
183	.regs = imx355_global_regs,
184};
185
186static const struct imx355_reg mode_3268x2448_regs[] = {
187	{ 0x0112, 0x0a },
188	{ 0x0113, 0x0a },
189	{ 0x0114, 0x03 },
190	{ 0x0342, 0x0e },
191	{ 0x0343, 0x58 },
192	{ 0x0340, 0x0a },
193	{ 0x0341, 0x37 },
194	{ 0x0344, 0x00 },
195	{ 0x0345, 0x08 },
196	{ 0x0346, 0x00 },
197	{ 0x0347, 0x08 },
198	{ 0x0348, 0x0c },
199	{ 0x0349, 0xcb },
200	{ 0x034a, 0x09 },
201	{ 0x034b, 0x97 },
202	{ 0x0220, 0x00 },
203	{ 0x0222, 0x01 },
204	{ 0x0900, 0x00 },
205	{ 0x0901, 0x11 },
206	{ 0x0902, 0x00 },
207	{ 0x034c, 0x0c },
208	{ 0x034d, 0xc4 },
209	{ 0x034e, 0x09 },
210	{ 0x034f, 0x90 },
211	{ 0x0301, 0x05 },
212	{ 0x0303, 0x01 },
213	{ 0x0305, 0x02 },
214	{ 0x0306, 0x00 },
215	{ 0x0307, 0x78 },
216	{ 0x030b, 0x01 },
217	{ 0x030d, 0x02 },
218	{ 0x030e, 0x00 },
219	{ 0x030f, 0x4b },
220	{ 0x0310, 0x00 },
221	{ 0x0700, 0x00 },
222	{ 0x0701, 0x10 },
223	{ 0x0820, 0x0b },
224	{ 0x0821, 0x40 },
225	{ 0x3088, 0x04 },
226	{ 0x6813, 0x02 },
227	{ 0x6835, 0x07 },
228	{ 0x6836, 0x01 },
229	{ 0x6837, 0x04 },
230	{ 0x684d, 0x07 },
231	{ 0x684e, 0x01 },
232	{ 0x684f, 0x04 },
233};
234
235static const struct imx355_reg mode_3264x2448_regs[] = {
236	{ 0x0112, 0x0a },
237	{ 0x0113, 0x0a },
238	{ 0x0114, 0x03 },
239	{ 0x0342, 0x0e },
240	{ 0x0343, 0x58 },
241	{ 0x0340, 0x0a },
242	{ 0x0341, 0x37 },
243	{ 0x0344, 0x00 },
244	{ 0x0345, 0x08 },
245	{ 0x0346, 0x00 },
246	{ 0x0347, 0x08 },
247	{ 0x0348, 0x0c },
248	{ 0x0349, 0xc7 },
249	{ 0x034a, 0x09 },
250	{ 0x034b, 0x97 },
251	{ 0x0220, 0x00 },
252	{ 0x0222, 0x01 },
253	{ 0x0900, 0x00 },
254	{ 0x0901, 0x11 },
255	{ 0x0902, 0x00 },
256	{ 0x034c, 0x0c },
257	{ 0x034d, 0xc0 },
258	{ 0x034e, 0x09 },
259	{ 0x034f, 0x90 },
260	{ 0x0301, 0x05 },
261	{ 0x0303, 0x01 },
262	{ 0x0305, 0x02 },
263	{ 0x0306, 0x00 },
264	{ 0x0307, 0x78 },
265	{ 0x030b, 0x01 },
266	{ 0x030d, 0x02 },
267	{ 0x030e, 0x00 },
268	{ 0x030f, 0x4b },
269	{ 0x0310, 0x00 },
270	{ 0x0700, 0x00 },
271	{ 0x0701, 0x10 },
272	{ 0x0820, 0x0b },
273	{ 0x0821, 0x40 },
274	{ 0x3088, 0x04 },
275	{ 0x6813, 0x02 },
276	{ 0x6835, 0x07 },
277	{ 0x6836, 0x01 },
278	{ 0x6837, 0x04 },
279	{ 0x684d, 0x07 },
280	{ 0x684e, 0x01 },
281	{ 0x684f, 0x04 },
282};
283
284static const struct imx355_reg mode_3280x2464_regs[] = {
285	{ 0x0112, 0x0a },
286	{ 0x0113, 0x0a },
287	{ 0x0114, 0x03 },
288	{ 0x0342, 0x0e },
289	{ 0x0343, 0x58 },
290	{ 0x0340, 0x0a },
291	{ 0x0341, 0x37 },
292	{ 0x0344, 0x00 },
293	{ 0x0345, 0x00 },
294	{ 0x0346, 0x00 },
295	{ 0x0347, 0x00 },
296	{ 0x0348, 0x0c },
297	{ 0x0349, 0xcf },
298	{ 0x034a, 0x09 },
299	{ 0x034b, 0x9f },
300	{ 0x0220, 0x00 },
301	{ 0x0222, 0x01 },
302	{ 0x0900, 0x00 },
303	{ 0x0901, 0x11 },
304	{ 0x0902, 0x00 },
305	{ 0x034c, 0x0c },
306	{ 0x034d, 0xd0 },
307	{ 0x034e, 0x09 },
308	{ 0x034f, 0xa0 },
309	{ 0x0301, 0x05 },
310	{ 0x0303, 0x01 },
311	{ 0x0305, 0x02 },
312	{ 0x0306, 0x00 },
313	{ 0x0307, 0x78 },
314	{ 0x030b, 0x01 },
315	{ 0x030d, 0x02 },
316	{ 0x030e, 0x00 },
317	{ 0x030f, 0x4b },
318	{ 0x0310, 0x00 },
319	{ 0x0700, 0x00 },
320	{ 0x0701, 0x10 },
321	{ 0x0820, 0x0b },
322	{ 0x0821, 0x40 },
323	{ 0x3088, 0x04 },
324	{ 0x6813, 0x02 },
325	{ 0x6835, 0x07 },
326	{ 0x6836, 0x01 },
327	{ 0x6837, 0x04 },
328	{ 0x684d, 0x07 },
329	{ 0x684e, 0x01 },
330	{ 0x684f, 0x04 },
331};
332
333static const struct imx355_reg mode_1940x1096_regs[] = {
334	{ 0x0112, 0x0a },
335	{ 0x0113, 0x0a },
336	{ 0x0114, 0x03 },
337	{ 0x0342, 0x0e },
338	{ 0x0343, 0x58 },
339	{ 0x0340, 0x05 },
340	{ 0x0341, 0x1a },
341	{ 0x0344, 0x02 },
342	{ 0x0345, 0xa0 },
343	{ 0x0346, 0x02 },
344	{ 0x0347, 0xac },
345	{ 0x0348, 0x0a },
346	{ 0x0349, 0x33 },
347	{ 0x034a, 0x06 },
348	{ 0x034b, 0xf3 },
349	{ 0x0220, 0x00 },
350	{ 0x0222, 0x01 },
351	{ 0x0900, 0x00 },
352	{ 0x0901, 0x11 },
353	{ 0x0902, 0x00 },
354	{ 0x034c, 0x07 },
355	{ 0x034d, 0x94 },
356	{ 0x034e, 0x04 },
357	{ 0x034f, 0x48 },
358	{ 0x0301, 0x05 },
359	{ 0x0303, 0x01 },
360	{ 0x0305, 0x02 },
361	{ 0x0306, 0x00 },
362	{ 0x0307, 0x78 },
363	{ 0x030b, 0x01 },
364	{ 0x030d, 0x02 },
365	{ 0x030e, 0x00 },
366	{ 0x030f, 0x4b },
367	{ 0x0310, 0x00 },
368	{ 0x0700, 0x00 },
369	{ 0x0701, 0x10 },
370	{ 0x0820, 0x0b },
371	{ 0x0821, 0x40 },
372	{ 0x3088, 0x04 },
373	{ 0x6813, 0x02 },
374	{ 0x6835, 0x07 },
375	{ 0x6836, 0x01 },
376	{ 0x6837, 0x04 },
377	{ 0x684d, 0x07 },
378	{ 0x684e, 0x01 },
379	{ 0x684f, 0x04 },
380};
381
382static const struct imx355_reg mode_1936x1096_regs[] = {
383	{ 0x0112, 0x0a },
384	{ 0x0113, 0x0a },
385	{ 0x0114, 0x03 },
386	{ 0x0342, 0x0e },
387	{ 0x0343, 0x58 },
388	{ 0x0340, 0x05 },
389	{ 0x0341, 0x1a },
390	{ 0x0344, 0x02 },
391	{ 0x0345, 0xa0 },
392	{ 0x0346, 0x02 },
393	{ 0x0347, 0xac },
394	{ 0x0348, 0x0a },
395	{ 0x0349, 0x2f },
396	{ 0x034a, 0x06 },
397	{ 0x034b, 0xf3 },
398	{ 0x0220, 0x00 },
399	{ 0x0222, 0x01 },
400	{ 0x0900, 0x00 },
401	{ 0x0901, 0x11 },
402	{ 0x0902, 0x00 },
403	{ 0x034c, 0x07 },
404	{ 0x034d, 0x90 },
405	{ 0x034e, 0x04 },
406	{ 0x034f, 0x48 },
407	{ 0x0301, 0x05 },
408	{ 0x0303, 0x01 },
409	{ 0x0305, 0x02 },
410	{ 0x0306, 0x00 },
411	{ 0x0307, 0x78 },
412	{ 0x030b, 0x01 },
413	{ 0x030d, 0x02 },
414	{ 0x030e, 0x00 },
415	{ 0x030f, 0x4b },
416	{ 0x0310, 0x00 },
417	{ 0x0700, 0x00 },
418	{ 0x0701, 0x10 },
419	{ 0x0820, 0x0b },
420	{ 0x0821, 0x40 },
421	{ 0x3088, 0x04 },
422	{ 0x6813, 0x02 },
423	{ 0x6835, 0x07 },
424	{ 0x6836, 0x01 },
425	{ 0x6837, 0x04 },
426	{ 0x684d, 0x07 },
427	{ 0x684e, 0x01 },
428	{ 0x684f, 0x04 },
429};
430
431static const struct imx355_reg mode_1924x1080_regs[] = {
432	{ 0x0112, 0x0a },
433	{ 0x0113, 0x0a },
434	{ 0x0114, 0x03 },
435	{ 0x0342, 0x0e },
436	{ 0x0343, 0x58 },
437	{ 0x0340, 0x05 },
438	{ 0x0341, 0x1a },
439	{ 0x0344, 0x02 },
440	{ 0x0345, 0xa8 },
441	{ 0x0346, 0x02 },
442	{ 0x0347, 0xb4 },
443	{ 0x0348, 0x0a },
444	{ 0x0349, 0x2b },
445	{ 0x034a, 0x06 },
446	{ 0x034b, 0xeb },
447	{ 0x0220, 0x00 },
448	{ 0x0222, 0x01 },
449	{ 0x0900, 0x00 },
450	{ 0x0901, 0x11 },
451	{ 0x0902, 0x00 },
452	{ 0x034c, 0x07 },
453	{ 0x034d, 0x84 },
454	{ 0x034e, 0x04 },
455	{ 0x034f, 0x38 },
456	{ 0x0301, 0x05 },
457	{ 0x0303, 0x01 },
458	{ 0x0305, 0x02 },
459	{ 0x0306, 0x00 },
460	{ 0x0307, 0x78 },
461	{ 0x030b, 0x01 },
462	{ 0x030d, 0x02 },
463	{ 0x030e, 0x00 },
464	{ 0x030f, 0x4b },
465	{ 0x0310, 0x00 },
466	{ 0x0700, 0x00 },
467	{ 0x0701, 0x10 },
468	{ 0x0820, 0x0b },
469	{ 0x0821, 0x40 },
470	{ 0x3088, 0x04 },
471	{ 0x6813, 0x02 },
472	{ 0x6835, 0x07 },
473	{ 0x6836, 0x01 },
474	{ 0x6837, 0x04 },
475	{ 0x684d, 0x07 },
476	{ 0x684e, 0x01 },
477	{ 0x684f, 0x04 },
478};
479
480static const struct imx355_reg mode_1920x1080_regs[] = {
481	{ 0x0112, 0x0a },
482	{ 0x0113, 0x0a },
483	{ 0x0114, 0x03 },
484	{ 0x0342, 0x0e },
485	{ 0x0343, 0x58 },
486	{ 0x0340, 0x05 },
487	{ 0x0341, 0x1a },
488	{ 0x0344, 0x02 },
489	{ 0x0345, 0xa8 },
490	{ 0x0346, 0x02 },
491	{ 0x0347, 0xb4 },
492	{ 0x0348, 0x0a },
493	{ 0x0349, 0x27 },
494	{ 0x034a, 0x06 },
495	{ 0x034b, 0xeb },
496	{ 0x0220, 0x00 },
497	{ 0x0222, 0x01 },
498	{ 0x0900, 0x00 },
499	{ 0x0901, 0x11 },
500	{ 0x0902, 0x00 },
501	{ 0x034c, 0x07 },
502	{ 0x034d, 0x80 },
503	{ 0x034e, 0x04 },
504	{ 0x034f, 0x38 },
505	{ 0x0301, 0x05 },
506	{ 0x0303, 0x01 },
507	{ 0x0305, 0x02 },
508	{ 0x0306, 0x00 },
509	{ 0x0307, 0x78 },
510	{ 0x030b, 0x01 },
511	{ 0x030d, 0x02 },
512	{ 0x030e, 0x00 },
513	{ 0x030f, 0x4b },
514	{ 0x0310, 0x00 },
515	{ 0x0700, 0x00 },
516	{ 0x0701, 0x10 },
517	{ 0x0820, 0x0b },
518	{ 0x0821, 0x40 },
519	{ 0x3088, 0x04 },
520	{ 0x6813, 0x02 },
521	{ 0x6835, 0x07 },
522	{ 0x6836, 0x01 },
523	{ 0x6837, 0x04 },
524	{ 0x684d, 0x07 },
525	{ 0x684e, 0x01 },
526	{ 0x684f, 0x04 },
527};
528
529static const struct imx355_reg mode_1640x1232_regs[] = {
530	{ 0x0112, 0x0a },
531	{ 0x0113, 0x0a },
532	{ 0x0114, 0x03 },
533	{ 0x0342, 0x07 },
534	{ 0x0343, 0x2c },
535	{ 0x0340, 0x05 },
536	{ 0x0341, 0x1a },
537	{ 0x0344, 0x00 },
538	{ 0x0345, 0x00 },
539	{ 0x0346, 0x00 },
540	{ 0x0347, 0x00 },
541	{ 0x0348, 0x0c },
542	{ 0x0349, 0xcf },
543	{ 0x034a, 0x09 },
544	{ 0x034b, 0x9f },
545	{ 0x0220, 0x00 },
546	{ 0x0222, 0x01 },
547	{ 0x0900, 0x01 },
548	{ 0x0901, 0x22 },
549	{ 0x0902, 0x00 },
550	{ 0x034c, 0x06 },
551	{ 0x034d, 0x68 },
552	{ 0x034e, 0x04 },
553	{ 0x034f, 0xd0 },
554	{ 0x0301, 0x05 },
555	{ 0x0303, 0x01 },
556	{ 0x0305, 0x02 },
557	{ 0x0306, 0x00 },
558	{ 0x0307, 0x78 },
559	{ 0x030b, 0x01 },
560	{ 0x030d, 0x02 },
561	{ 0x030e, 0x00 },
562	{ 0x030f, 0x4b },
563	{ 0x0310, 0x00 },
564	{ 0x0700, 0x00 },
565	{ 0x0701, 0x10 },
566	{ 0x0820, 0x0b },
567	{ 0x0821, 0x40 },
568	{ 0x3088, 0x04 },
569	{ 0x6813, 0x02 },
570	{ 0x6835, 0x07 },
571	{ 0x6836, 0x01 },
572	{ 0x6837, 0x04 },
573	{ 0x684d, 0x07 },
574	{ 0x684e, 0x01 },
575	{ 0x684f, 0x04 },
576};
577
578static const struct imx355_reg mode_1640x922_regs[] = {
579	{ 0x0112, 0x0a },
580	{ 0x0113, 0x0a },
581	{ 0x0114, 0x03 },
582	{ 0x0342, 0x07 },
583	{ 0x0343, 0x2c },
584	{ 0x0340, 0x05 },
585	{ 0x0341, 0x1a },
586	{ 0x0344, 0x00 },
587	{ 0x0345, 0x00 },
588	{ 0x0346, 0x01 },
589	{ 0x0347, 0x30 },
590	{ 0x0348, 0x0c },
591	{ 0x0349, 0xcf },
592	{ 0x034a, 0x08 },
593	{ 0x034b, 0x63 },
594	{ 0x0220, 0x00 },
595	{ 0x0222, 0x01 },
596	{ 0x0900, 0x01 },
597	{ 0x0901, 0x22 },
598	{ 0x0902, 0x00 },
599	{ 0x034c, 0x06 },
600	{ 0x034d, 0x68 },
601	{ 0x034e, 0x03 },
602	{ 0x034f, 0x9a },
603	{ 0x0301, 0x05 },
604	{ 0x0303, 0x01 },
605	{ 0x0305, 0x02 },
606	{ 0x0306, 0x00 },
607	{ 0x0307, 0x78 },
608	{ 0x030b, 0x01 },
609	{ 0x030d, 0x02 },
610	{ 0x030e, 0x00 },
611	{ 0x030f, 0x4b },
612	{ 0x0310, 0x00 },
613	{ 0x0700, 0x00 },
614	{ 0x0701, 0x10 },
615	{ 0x0820, 0x0b },
616	{ 0x0821, 0x40 },
617	{ 0x3088, 0x04 },
618	{ 0x6813, 0x02 },
619	{ 0x6835, 0x07 },
620	{ 0x6836, 0x01 },
621	{ 0x6837, 0x04 },
622	{ 0x684d, 0x07 },
623	{ 0x684e, 0x01 },
624	{ 0x684f, 0x04 },
625};
626
627static const struct imx355_reg mode_1300x736_regs[] = {
628	{ 0x0112, 0x0a },
629	{ 0x0113, 0x0a },
630	{ 0x0114, 0x03 },
631	{ 0x0342, 0x07 },
632	{ 0x0343, 0x2c },
633	{ 0x0340, 0x05 },
634	{ 0x0341, 0x1a },
635	{ 0x0344, 0x01 },
636	{ 0x0345, 0x58 },
637	{ 0x0346, 0x01 },
638	{ 0x0347, 0xf0 },
639	{ 0x0348, 0x0b },
640	{ 0x0349, 0x7f },
641	{ 0x034a, 0x07 },
642	{ 0x034b, 0xaf },
643	{ 0x0220, 0x00 },
644	{ 0x0222, 0x01 },
645	{ 0x0900, 0x01 },
646	{ 0x0901, 0x22 },
647	{ 0x0902, 0x00 },
648	{ 0x034c, 0x05 },
649	{ 0x034d, 0x14 },
650	{ 0x034e, 0x02 },
651	{ 0x034f, 0xe0 },
652	{ 0x0301, 0x05 },
653	{ 0x0303, 0x01 },
654	{ 0x0305, 0x02 },
655	{ 0x0306, 0x00 },
656	{ 0x0307, 0x78 },
657	{ 0x030b, 0x01 },
658	{ 0x030d, 0x02 },
659	{ 0x030e, 0x00 },
660	{ 0x030f, 0x4b },
661	{ 0x0310, 0x00 },
662	{ 0x0700, 0x00 },
663	{ 0x0701, 0x10 },
664	{ 0x0820, 0x0b },
665	{ 0x0821, 0x40 },
666	{ 0x3088, 0x04 },
667	{ 0x6813, 0x02 },
668	{ 0x6835, 0x07 },
669	{ 0x6836, 0x01 },
670	{ 0x6837, 0x04 },
671	{ 0x684d, 0x07 },
672	{ 0x684e, 0x01 },
673	{ 0x684f, 0x04 },
674};
675
676static const struct imx355_reg mode_1296x736_regs[] = {
677	{ 0x0112, 0x0a },
678	{ 0x0113, 0x0a },
679	{ 0x0114, 0x03 },
680	{ 0x0342, 0x07 },
681	{ 0x0343, 0x2c },
682	{ 0x0340, 0x05 },
683	{ 0x0341, 0x1a },
684	{ 0x0344, 0x01 },
685	{ 0x0345, 0x58 },
686	{ 0x0346, 0x01 },
687	{ 0x0347, 0xf0 },
688	{ 0x0348, 0x0b },
689	{ 0x0349, 0x77 },
690	{ 0x034a, 0x07 },
691	{ 0x034b, 0xaf },
692	{ 0x0220, 0x00 },
693	{ 0x0222, 0x01 },
694	{ 0x0900, 0x01 },
695	{ 0x0901, 0x22 },
696	{ 0x0902, 0x00 },
697	{ 0x034c, 0x05 },
698	{ 0x034d, 0x10 },
699	{ 0x034e, 0x02 },
700	{ 0x034f, 0xe0 },
701	{ 0x0301, 0x05 },
702	{ 0x0303, 0x01 },
703	{ 0x0305, 0x02 },
704	{ 0x0306, 0x00 },
705	{ 0x0307, 0x78 },
706	{ 0x030b, 0x01 },
707	{ 0x030d, 0x02 },
708	{ 0x030e, 0x00 },
709	{ 0x030f, 0x4b },
710	{ 0x0310, 0x00 },
711	{ 0x0700, 0x00 },
712	{ 0x0701, 0x10 },
713	{ 0x0820, 0x0b },
714	{ 0x0821, 0x40 },
715	{ 0x3088, 0x04 },
716	{ 0x6813, 0x02 },
717	{ 0x6835, 0x07 },
718	{ 0x6836, 0x01 },
719	{ 0x6837, 0x04 },
720	{ 0x684d, 0x07 },
721	{ 0x684e, 0x01 },
722	{ 0x684f, 0x04 },
723};
724
725static const struct imx355_reg mode_1284x720_regs[] = {
726	{ 0x0112, 0x0a },
727	{ 0x0113, 0x0a },
728	{ 0x0114, 0x03 },
729	{ 0x0342, 0x07 },
730	{ 0x0343, 0x2c },
731	{ 0x0340, 0x05 },
732	{ 0x0341, 0x1a },
733	{ 0x0344, 0x01 },
734	{ 0x0345, 0x68 },
735	{ 0x0346, 0x02 },
736	{ 0x0347, 0x00 },
737	{ 0x0348, 0x0b },
738	{ 0x0349, 0x6f },
739	{ 0x034a, 0x07 },
740	{ 0x034b, 0x9f },
741	{ 0x0220, 0x00 },
742	{ 0x0222, 0x01 },
743	{ 0x0900, 0x01 },
744	{ 0x0901, 0x22 },
745	{ 0x0902, 0x00 },
746	{ 0x034c, 0x05 },
747	{ 0x034d, 0x04 },
748	{ 0x034e, 0x02 },
749	{ 0x034f, 0xd0 },
750	{ 0x0301, 0x05 },
751	{ 0x0303, 0x01 },
752	{ 0x0305, 0x02 },
753	{ 0x0306, 0x00 },
754	{ 0x0307, 0x78 },
755	{ 0x030b, 0x01 },
756	{ 0x030d, 0x02 },
757	{ 0x030e, 0x00 },
758	{ 0x030f, 0x4b },
759	{ 0x0310, 0x00 },
760	{ 0x0700, 0x00 },
761	{ 0x0701, 0x10 },
762	{ 0x0820, 0x0b },
763	{ 0x0821, 0x40 },
764	{ 0x3088, 0x04 },
765	{ 0x6813, 0x02 },
766	{ 0x6835, 0x07 },
767	{ 0x6836, 0x01 },
768	{ 0x6837, 0x04 },
769	{ 0x684d, 0x07 },
770	{ 0x684e, 0x01 },
771	{ 0x684f, 0x04 },
772};
773
774static const struct imx355_reg mode_1280x720_regs[] = {
775	{ 0x0112, 0x0a },
776	{ 0x0113, 0x0a },
777	{ 0x0114, 0x03 },
778	{ 0x0342, 0x07 },
779	{ 0x0343, 0x2c },
780	{ 0x0340, 0x05 },
781	{ 0x0341, 0x1a },
782	{ 0x0344, 0x01 },
783	{ 0x0345, 0x68 },
784	{ 0x0346, 0x02 },
785	{ 0x0347, 0x00 },
786	{ 0x0348, 0x0b },
787	{ 0x0349, 0x67 },
788	{ 0x034a, 0x07 },
789	{ 0x034b, 0x9f },
790	{ 0x0220, 0x00 },
791	{ 0x0222, 0x01 },
792	{ 0x0900, 0x01 },
793	{ 0x0901, 0x22 },
794	{ 0x0902, 0x00 },
795	{ 0x034c, 0x05 },
796	{ 0x034d, 0x00 },
797	{ 0x034e, 0x02 },
798	{ 0x034f, 0xd0 },
799	{ 0x0301, 0x05 },
800	{ 0x0303, 0x01 },
801	{ 0x0305, 0x02 },
802	{ 0x0306, 0x00 },
803	{ 0x0307, 0x78 },
804	{ 0x030b, 0x01 },
805	{ 0x030d, 0x02 },
806	{ 0x030e, 0x00 },
807	{ 0x030f, 0x4b },
808	{ 0x0310, 0x00 },
809	{ 0x0700, 0x00 },
810	{ 0x0701, 0x10 },
811	{ 0x0820, 0x0b },
812	{ 0x0821, 0x40 },
813	{ 0x3088, 0x04 },
814	{ 0x6813, 0x02 },
815	{ 0x6835, 0x07 },
816	{ 0x6836, 0x01 },
817	{ 0x6837, 0x04 },
818	{ 0x684d, 0x07 },
819	{ 0x684e, 0x01 },
820	{ 0x684f, 0x04 },
821};
822
823static const struct imx355_reg mode_820x616_regs[] = {
824	{ 0x0112, 0x0a },
825	{ 0x0113, 0x0a },
826	{ 0x0114, 0x03 },
827	{ 0x0342, 0x0e },
828	{ 0x0343, 0x58 },
829	{ 0x0340, 0x02 },
830	{ 0x0341, 0x8c },
831	{ 0x0344, 0x00 },
832	{ 0x0345, 0x00 },
833	{ 0x0346, 0x00 },
834	{ 0x0347, 0x00 },
835	{ 0x0348, 0x0c },
836	{ 0x0349, 0xcf },
837	{ 0x034a, 0x09 },
838	{ 0x034b, 0x9f },
839	{ 0x0220, 0x00 },
840	{ 0x0222, 0x01 },
841	{ 0x0900, 0x01 },
842	{ 0x0901, 0x44 },
843	{ 0x0902, 0x00 },
844	{ 0x034c, 0x03 },
845	{ 0x034d, 0x34 },
846	{ 0x034e, 0x02 },
847	{ 0x034f, 0x68 },
848	{ 0x0301, 0x05 },
849	{ 0x0303, 0x01 },
850	{ 0x0305, 0x02 },
851	{ 0x0306, 0x00 },
852	{ 0x0307, 0x78 },
853	{ 0x030b, 0x01 },
854	{ 0x030d, 0x02 },
855	{ 0x030e, 0x00 },
856	{ 0x030f, 0x4b },
857	{ 0x0310, 0x00 },
858	{ 0x0700, 0x02 },
859	{ 0x0701, 0x78 },
860	{ 0x0820, 0x0b },
861	{ 0x0821, 0x40 },
862	{ 0x3088, 0x04 },
863	{ 0x6813, 0x02 },
864	{ 0x6835, 0x07 },
865	{ 0x6836, 0x01 },
866	{ 0x6837, 0x04 },
867	{ 0x684d, 0x07 },
868	{ 0x684e, 0x01 },
869	{ 0x684f, 0x04 },
870};
871
872static const char * const imx355_test_pattern_menu[] = {
873	"Disabled",
874	"Solid Colour",
875	"Eight Vertical Colour Bars",
876	"Colour Bars With Fade to Grey",
877	"Pseudorandom Sequence (PN9)",
878};
879
880/*
881 * When adding more than the one below, make sure the disallowed ones will
882 * actually be disabled in the LINK_FREQ control.
883 */
884static const s64 link_freq_menu_items[] = {
885	IMX355_LINK_FREQ_DEFAULT,
886};
887
888/* Mode configs */
889static const struct imx355_mode supported_modes[] = {
890	{
891		.width = 3280,
892		.height = 2464,
893		.fll_def = 2615,
894		.fll_min = 2615,
895		.llp = 3672,
896		.link_freq_index = IMX355_LINK_FREQ_INDEX,
897		.reg_list = {
898			.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
899			.regs = mode_3280x2464_regs,
900		},
901	},
902	{
903		.width = 3268,
904		.height = 2448,
905		.fll_def = 2615,
906		.fll_min = 2615,
907		.llp = 3672,
908		.link_freq_index = IMX355_LINK_FREQ_INDEX,
909		.reg_list = {
910			.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
911			.regs = mode_3268x2448_regs,
912		},
913	},
914	{
915		.width = 3264,
916		.height = 2448,
917		.fll_def = 2615,
918		.fll_min = 2615,
919		.llp = 3672,
920		.link_freq_index = IMX355_LINK_FREQ_INDEX,
921		.reg_list = {
922			.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
923			.regs = mode_3264x2448_regs,
924		},
925	},
926	{
927		.width = 1940,
928		.height = 1096,
929		.fll_def = 1306,
930		.fll_min = 1306,
931		.llp = 3672,
932		.link_freq_index = IMX355_LINK_FREQ_INDEX,
933		.reg_list = {
934			.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
935			.regs = mode_1940x1096_regs,
936		},
937	},
938	{
939		.width = 1936,
940		.height = 1096,
941		.fll_def = 1306,
942		.fll_min = 1306,
943		.llp = 3672,
944		.link_freq_index = IMX355_LINK_FREQ_INDEX,
945		.reg_list = {
946			.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
947			.regs = mode_1936x1096_regs,
948		},
949	},
950	{
951		.width = 1924,
952		.height = 1080,
953		.fll_def = 1306,
954		.fll_min = 1306,
955		.llp = 3672,
956		.link_freq_index = IMX355_LINK_FREQ_INDEX,
957		.reg_list = {
958			.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
959			.regs = mode_1924x1080_regs,
960		},
961	},
962	{
963		.width = 1920,
964		.height = 1080,
965		.fll_def = 1306,
966		.fll_min = 1306,
967		.llp = 3672,
968		.link_freq_index = IMX355_LINK_FREQ_INDEX,
969		.reg_list = {
970			.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
971			.regs = mode_1920x1080_regs,
972		},
973	},
974	{
975		.width = 1640,
976		.height = 1232,
977		.fll_def = 1306,
978		.fll_min = 1306,
979		.llp = 1836,
980		.link_freq_index = IMX355_LINK_FREQ_INDEX,
981		.reg_list = {
982			.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
983			.regs = mode_1640x1232_regs,
984		},
985	},
986	{
987		.width = 1640,
988		.height = 922,
989		.fll_def = 1306,
990		.fll_min = 1306,
991		.llp = 1836,
992		.link_freq_index = IMX355_LINK_FREQ_INDEX,
993		.reg_list = {
994			.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
995			.regs = mode_1640x922_regs,
996		},
997	},
998	{
999		.width = 1300,
1000		.height = 736,
1001		.fll_def = 1306,
1002		.fll_min = 1306,
1003		.llp = 1836,
1004		.link_freq_index = IMX355_LINK_FREQ_INDEX,
1005		.reg_list = {
1006			.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
1007			.regs = mode_1300x736_regs,
1008		},
1009	},
1010	{
1011		.width = 1296,
1012		.height = 736,
1013		.fll_def = 1306,
1014		.fll_min = 1306,
1015		.llp = 1836,
1016		.link_freq_index = IMX355_LINK_FREQ_INDEX,
1017		.reg_list = {
1018			.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
1019			.regs = mode_1296x736_regs,
1020		},
1021	},
1022	{
1023		.width = 1284,
1024		.height = 720,
1025		.fll_def = 1306,
1026		.fll_min = 1306,
1027		.llp = 1836,
1028		.link_freq_index = IMX355_LINK_FREQ_INDEX,
1029		.reg_list = {
1030			.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
1031			.regs = mode_1284x720_regs,
1032		},
1033	},
1034	{
1035		.width = 1280,
1036		.height = 720,
1037		.fll_def = 1306,
1038		.fll_min = 1306,
1039		.llp = 1836,
1040		.link_freq_index = IMX355_LINK_FREQ_INDEX,
1041		.reg_list = {
1042			.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
1043			.regs = mode_1280x720_regs,
1044		},
1045	},
1046	{
1047		.width = 820,
1048		.height = 616,
1049		.fll_def = 652,
1050		.fll_min = 652,
1051		.llp = 3672,
1052		.link_freq_index = IMX355_LINK_FREQ_INDEX,
1053		.reg_list = {
1054			.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
1055			.regs = mode_820x616_regs,
1056		},
1057	},
1058};
1059
1060static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd)
1061{
1062	return container_of(_sd, struct imx355, sd);
1063}
1064
1065/* Get bayer order based on flip setting. */
1066static u32 imx355_get_format_code(struct imx355 *imx355)
1067{
1068	/*
1069	 * Only one bayer order is supported.
1070	 * It depends on the flip settings.
1071	 */
1072	u32 code;
1073	static const u32 codes[2][2] = {
1074		{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
1075		{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
1076	};
1077
1078	lockdep_assert_held(&imx355->mutex);
1079	code = codes[imx355->vflip->val][imx355->hflip->val];
1080
1081	return code;
1082}
1083
1084/* Read registers up to 4 at a time */
1085static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
1086{
1087	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1088	struct i2c_msg msgs[2];
1089	u8 addr_buf[2];
1090	u8 data_buf[4] = { 0 };
1091	int ret;
1092
1093	if (len > 4)
1094		return -EINVAL;
1095
1096	put_unaligned_be16(reg, addr_buf);
1097	/* Write register address */
1098	msgs[0].addr = client->addr;
1099	msgs[0].flags = 0;
1100	msgs[0].len = ARRAY_SIZE(addr_buf);
1101	msgs[0].buf = addr_buf;
1102
1103	/* Read data from register */
1104	msgs[1].addr = client->addr;
1105	msgs[1].flags = I2C_M_RD;
1106	msgs[1].len = len;
1107	msgs[1].buf = &data_buf[4 - len];
1108
1109	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1110	if (ret != ARRAY_SIZE(msgs))
1111		return -EIO;
1112
1113	*val = get_unaligned_be32(data_buf);
1114
1115	return 0;
1116}
1117
1118/* Write registers up to 4 at a time */
1119static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
1120{
1121	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1122	u8 buf[6];
1123
1124	if (len > 4)
1125		return -EINVAL;
1126
1127	put_unaligned_be16(reg, buf);
1128	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1129	if (i2c_master_send(client, buf, len + 2) != len + 2)
1130		return -EIO;
1131
1132	return 0;
1133}
1134
1135/* Write a list of registers */
1136static int imx355_write_regs(struct imx355 *imx355,
1137			     const struct imx355_reg *regs, u32 len)
1138{
1139	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1140	int ret;
1141	u32 i;
1142
1143	for (i = 0; i < len; i++) {
1144		ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
1145		if (ret) {
1146			dev_err_ratelimited(&client->dev,
1147					    "write reg 0x%4.4x return err %d",
1148					    regs[i].address, ret);
1149
1150			return ret;
1151		}
1152	}
1153
1154	return 0;
1155}
1156
1157/* Open sub-device */
1158static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1159{
1160	struct imx355 *imx355 = to_imx355(sd);
1161	struct v4l2_mbus_framefmt *try_fmt =
1162		v4l2_subdev_state_get_format(fh->state, 0);
1163
1164	mutex_lock(&imx355->mutex);
1165
1166	/* Initialize try_fmt */
1167	try_fmt->width = imx355->cur_mode->width;
1168	try_fmt->height = imx355->cur_mode->height;
1169	try_fmt->code = imx355_get_format_code(imx355);
1170	try_fmt->field = V4L2_FIELD_NONE;
1171
1172	mutex_unlock(&imx355->mutex);
1173
1174	return 0;
1175}
1176
1177static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
1178{
1179	struct imx355 *imx355 = container_of(ctrl->handler,
1180					     struct imx355, ctrl_handler);
1181	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1182	s64 max;
1183	int ret;
1184
1185	/* Propagate change of current control to all related controls */
1186	switch (ctrl->id) {
1187	case V4L2_CID_VBLANK:
1188		/* Update max exposure while meeting expected vblanking */
1189		max = imx355->cur_mode->height + ctrl->val - 10;
1190		__v4l2_ctrl_modify_range(imx355->exposure,
1191					 imx355->exposure->minimum,
1192					 max, imx355->exposure->step, max);
1193		break;
1194	}
1195
1196	/*
1197	 * Applying V4L2 control value only happens
1198	 * when power is up for streaming
1199	 */
1200	if (!pm_runtime_get_if_in_use(&client->dev))
1201		return 0;
1202
1203	switch (ctrl->id) {
1204	case V4L2_CID_ANALOGUE_GAIN:
1205		/* Analog gain = 1024/(1024 - ctrl->val) times */
1206		ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
1207				       ctrl->val);
1208		break;
1209	case V4L2_CID_DIGITAL_GAIN:
1210		ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
1211				       ctrl->val);
1212		break;
1213	case V4L2_CID_EXPOSURE:
1214		ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
1215				       ctrl->val);
1216		break;
1217	case V4L2_CID_VBLANK:
1218		/* Update FLL that meets expected vertical blanking */
1219		ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
1220				       imx355->cur_mode->height + ctrl->val);
1221		break;
1222	case V4L2_CID_TEST_PATTERN:
1223		ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
1224				       2, ctrl->val);
1225		break;
1226	case V4L2_CID_HFLIP:
1227	case V4L2_CID_VFLIP:
1228		ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
1229				       imx355->hflip->val |
1230				       imx355->vflip->val << 1);
1231		break;
1232	default:
1233		ret = -EINVAL;
1234		dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
1235			 ctrl->id, ctrl->val);
1236		break;
1237	}
1238
1239	pm_runtime_put(&client->dev);
1240
1241	return ret;
1242}
1243
1244static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
1245	.s_ctrl = imx355_set_ctrl,
1246};
1247
1248static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
1249				 struct v4l2_subdev_state *sd_state,
1250				 struct v4l2_subdev_mbus_code_enum *code)
1251{
1252	struct imx355 *imx355 = to_imx355(sd);
1253
1254	if (code->index > 0)
1255		return -EINVAL;
1256
1257	mutex_lock(&imx355->mutex);
1258	code->code = imx355_get_format_code(imx355);
1259	mutex_unlock(&imx355->mutex);
1260
1261	return 0;
1262}
1263
1264static int imx355_enum_frame_size(struct v4l2_subdev *sd,
1265				  struct v4l2_subdev_state *sd_state,
1266				  struct v4l2_subdev_frame_size_enum *fse)
1267{
1268	struct imx355 *imx355 = to_imx355(sd);
1269
1270	if (fse->index >= ARRAY_SIZE(supported_modes))
1271		return -EINVAL;
1272
1273	mutex_lock(&imx355->mutex);
1274	if (fse->code != imx355_get_format_code(imx355)) {
1275		mutex_unlock(&imx355->mutex);
1276		return -EINVAL;
1277	}
1278	mutex_unlock(&imx355->mutex);
1279
1280	fse->min_width = supported_modes[fse->index].width;
1281	fse->max_width = fse->min_width;
1282	fse->min_height = supported_modes[fse->index].height;
1283	fse->max_height = fse->min_height;
1284
1285	return 0;
1286}
1287
1288static void imx355_update_pad_format(struct imx355 *imx355,
1289				     const struct imx355_mode *mode,
1290				     struct v4l2_subdev_format *fmt)
1291{
1292	fmt->format.width = mode->width;
1293	fmt->format.height = mode->height;
1294	fmt->format.code = imx355_get_format_code(imx355);
1295	fmt->format.field = V4L2_FIELD_NONE;
1296}
1297
1298static int imx355_do_get_pad_format(struct imx355 *imx355,
1299				    struct v4l2_subdev_state *sd_state,
1300				    struct v4l2_subdev_format *fmt)
1301{
1302	struct v4l2_mbus_framefmt *framefmt;
1303
1304	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1305		framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
1306		fmt->format = *framefmt;
1307	} else {
1308		imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
1309	}
1310
1311	return 0;
1312}
1313
1314static int imx355_get_pad_format(struct v4l2_subdev *sd,
1315				 struct v4l2_subdev_state *sd_state,
1316				 struct v4l2_subdev_format *fmt)
1317{
1318	struct imx355 *imx355 = to_imx355(sd);
1319	int ret;
1320
1321	mutex_lock(&imx355->mutex);
1322	ret = imx355_do_get_pad_format(imx355, sd_state, fmt);
1323	mutex_unlock(&imx355->mutex);
1324
1325	return ret;
1326}
1327
1328static int
1329imx355_set_pad_format(struct v4l2_subdev *sd,
1330		      struct v4l2_subdev_state *sd_state,
1331		      struct v4l2_subdev_format *fmt)
1332{
1333	struct imx355 *imx355 = to_imx355(sd);
1334	const struct imx355_mode *mode;
1335	struct v4l2_mbus_framefmt *framefmt;
1336	s32 vblank_def;
1337	s32 vblank_min;
1338	s64 h_blank;
1339	u64 pixel_rate;
1340	u32 height;
1341
1342	mutex_lock(&imx355->mutex);
1343
1344	/*
1345	 * Only one bayer order is supported.
1346	 * It depends on the flip settings.
1347	 */
1348	fmt->format.code = imx355_get_format_code(imx355);
1349
1350	mode = v4l2_find_nearest_size(supported_modes,
1351				      ARRAY_SIZE(supported_modes),
1352				      width, height,
1353				      fmt->format.width, fmt->format.height);
1354	imx355_update_pad_format(imx355, mode, fmt);
1355	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1356		framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
1357		*framefmt = fmt->format;
1358	} else {
1359		imx355->cur_mode = mode;
1360		pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
1361		do_div(pixel_rate, 10);
1362		__v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
1363		/* Update limits and set FPS to default */
1364		height = imx355->cur_mode->height;
1365		vblank_def = imx355->cur_mode->fll_def - height;
1366		vblank_min = imx355->cur_mode->fll_min - height;
1367		height = IMX355_FLL_MAX - height;
1368		__v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
1369					 vblank_def);
1370		__v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
1371		h_blank = mode->llp - imx355->cur_mode->width;
1372		/*
1373		 * Currently hblank is not changeable.
1374		 * So FPS control is done only by vblank.
1375		 */
1376		__v4l2_ctrl_modify_range(imx355->hblank, h_blank,
1377					 h_blank, 1, h_blank);
1378	}
1379
1380	mutex_unlock(&imx355->mutex);
1381
1382	return 0;
1383}
1384
1385/* Start streaming */
1386static int imx355_start_streaming(struct imx355 *imx355)
1387{
1388	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1389	const struct imx355_reg_list *reg_list;
1390	int ret;
1391
1392	/* Global Setting */
1393	reg_list = &imx355_global_setting;
1394	ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1395	if (ret) {
1396		dev_err(&client->dev, "failed to set global settings");
1397		return ret;
1398	}
1399
1400	/* Apply default values of current mode */
1401	reg_list = &imx355->cur_mode->reg_list;
1402	ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1403	if (ret) {
1404		dev_err(&client->dev, "failed to set mode");
1405		return ret;
1406	}
1407
1408	/* set digital gain control to all color mode */
1409	ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
1410	if (ret)
1411		return ret;
1412
1413	/* Apply customized values from user */
1414	ret =  __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
1415	if (ret)
1416		return ret;
1417
1418	return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1419				1, IMX355_MODE_STREAMING);
1420}
1421
1422/* Stop streaming */
1423static int imx355_stop_streaming(struct imx355 *imx355)
1424{
1425	return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1426				1, IMX355_MODE_STANDBY);
1427}
1428
1429static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
1430{
1431	struct imx355 *imx355 = to_imx355(sd);
1432	struct i2c_client *client = v4l2_get_subdevdata(sd);
1433	int ret = 0;
1434
1435	mutex_lock(&imx355->mutex);
1436
1437	if (enable) {
1438		ret = pm_runtime_resume_and_get(&client->dev);
1439		if (ret < 0)
1440			goto err_unlock;
1441
1442		/*
1443		 * Apply default & customized values
1444		 * and then start streaming.
1445		 */
1446		ret = imx355_start_streaming(imx355);
1447		if (ret)
1448			goto err_rpm_put;
1449	} else {
1450		imx355_stop_streaming(imx355);
1451		pm_runtime_put(&client->dev);
1452	}
1453
1454	/* vflip and hflip cannot change during streaming */
1455	__v4l2_ctrl_grab(imx355->vflip, enable);
1456	__v4l2_ctrl_grab(imx355->hflip, enable);
1457
1458	mutex_unlock(&imx355->mutex);
1459
1460	return ret;
1461
1462err_rpm_put:
1463	pm_runtime_put(&client->dev);
1464err_unlock:
1465	mutex_unlock(&imx355->mutex);
1466
1467	return ret;
1468}
1469
1470/* Verify chip ID */
1471static int imx355_identify_module(struct imx355 *imx355)
1472{
1473	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1474	int ret;
1475	u32 val;
1476
1477	ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
1478	if (ret)
1479		return ret;
1480
1481	if (val != IMX355_CHIP_ID) {
1482		dev_err(&client->dev, "chip id mismatch: %x!=%x",
1483			IMX355_CHIP_ID, val);
1484		return -EIO;
1485	}
1486	return 0;
1487}
1488
1489static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
1490	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1491	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
1492};
1493
1494static const struct v4l2_subdev_video_ops imx355_video_ops = {
1495	.s_stream = imx355_set_stream,
1496};
1497
1498static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
1499	.enum_mbus_code = imx355_enum_mbus_code,
1500	.get_fmt = imx355_get_pad_format,
1501	.set_fmt = imx355_set_pad_format,
1502	.enum_frame_size = imx355_enum_frame_size,
1503};
1504
1505static const struct v4l2_subdev_ops imx355_subdev_ops = {
1506	.core = &imx355_subdev_core_ops,
1507	.video = &imx355_video_ops,
1508	.pad = &imx355_pad_ops,
1509};
1510
1511static const struct media_entity_operations imx355_subdev_entity_ops = {
1512	.link_validate = v4l2_subdev_link_validate,
1513};
1514
1515static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
1516	.open = imx355_open,
1517};
1518
1519/* Initialize control handlers */
1520static int imx355_init_controls(struct imx355 *imx355)
1521{
1522	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1523	struct v4l2_ctrl_handler *ctrl_hdlr;
1524	s64 exposure_max;
1525	s64 vblank_def;
1526	s64 vblank_min;
1527	s64 hblank;
1528	u64 pixel_rate;
1529	const struct imx355_mode *mode;
1530	u32 max;
1531	int ret;
1532
1533	ctrl_hdlr = &imx355->ctrl_handler;
1534	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
1535	if (ret)
1536		return ret;
1537
1538	ctrl_hdlr->lock = &imx355->mutex;
1539	max = ARRAY_SIZE(link_freq_menu_items) - 1;
1540	imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
1541						   V4L2_CID_LINK_FREQ, max, 0,
1542						   link_freq_menu_items);
1543	if (imx355->link_freq)
1544		imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1545
1546	/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
1547	pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
1548	do_div(pixel_rate, 10);
1549	/* By default, PIXEL_RATE is read only */
1550	imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1551					       V4L2_CID_PIXEL_RATE, pixel_rate,
1552					       pixel_rate, 1, pixel_rate);
1553
1554	/* Initialize vblank/hblank/exposure parameters based on current mode */
1555	mode = imx355->cur_mode;
1556	vblank_def = mode->fll_def - mode->height;
1557	vblank_min = mode->fll_min - mode->height;
1558	imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1559					   V4L2_CID_VBLANK, vblank_min,
1560					   IMX355_FLL_MAX - mode->height,
1561					   1, vblank_def);
1562
1563	hblank = mode->llp - mode->width;
1564	imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1565					   V4L2_CID_HBLANK, hblank, hblank,
1566					   1, hblank);
1567	if (imx355->hblank)
1568		imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1569
1570	/* fll >= exposure time + adjust parameter (default value is 10) */
1571	exposure_max = mode->fll_def - 10;
1572	imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1573					     V4L2_CID_EXPOSURE,
1574					     IMX355_EXPOSURE_MIN, exposure_max,
1575					     IMX355_EXPOSURE_STEP,
1576					     IMX355_EXPOSURE_DEFAULT);
1577
1578	imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1579					  V4L2_CID_HFLIP, 0, 1, 1, 0);
1580	if (imx355->hflip)
1581		imx355->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1582	imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1583					  V4L2_CID_VFLIP, 0, 1, 1, 0);
1584	if (imx355->vflip)
1585		imx355->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1586
1587	v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1588			  IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
1589			  IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
1590
1591	/* Digital gain */
1592	v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1593			  IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
1594			  IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
1595
1596	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
1597				     V4L2_CID_TEST_PATTERN,
1598				     ARRAY_SIZE(imx355_test_pattern_menu) - 1,
1599				     0, 0, imx355_test_pattern_menu);
1600	if (ctrl_hdlr->error) {
1601		ret = ctrl_hdlr->error;
1602		dev_err(&client->dev, "control init failed: %d", ret);
1603		goto error;
1604	}
1605
1606	imx355->sd.ctrl_handler = ctrl_hdlr;
1607
1608	return 0;
1609
1610error:
1611	v4l2_ctrl_handler_free(ctrl_hdlr);
1612
1613	return ret;
1614}
1615
1616static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
1617{
1618	struct imx355_hwcfg *cfg;
1619	struct v4l2_fwnode_endpoint bus_cfg = {
1620		.bus_type = V4L2_MBUS_CSI2_DPHY
1621	};
1622	struct fwnode_handle *ep;
1623	struct fwnode_handle *fwnode = dev_fwnode(dev);
1624	int ret;
1625
1626	if (!fwnode)
1627		return NULL;
1628
1629	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1630	if (!ep)
1631		return NULL;
1632
1633	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1634	if (ret)
1635		goto out_err;
1636
1637	cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
1638	if (!cfg)
1639		goto out_err;
1640
1641	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
1642				       &cfg->ext_clk);
1643	if (ret) {
1644		dev_err(dev, "can't get clock frequency");
1645		goto out_err;
1646	}
1647
1648	dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
1649	if (cfg->ext_clk != IMX355_EXT_CLK) {
1650		dev_err(dev, "external clock %d is not supported",
1651			cfg->ext_clk);
1652		goto out_err;
1653	}
1654
1655	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
1656				       bus_cfg.nr_of_link_frequencies,
1657				       link_freq_menu_items,
1658				       ARRAY_SIZE(link_freq_menu_items),
1659				       &cfg->link_freq_bitmap);
1660	if (ret)
1661		goto out_err;
1662
1663	v4l2_fwnode_endpoint_free(&bus_cfg);
1664	fwnode_handle_put(ep);
1665	return cfg;
1666
1667out_err:
1668	v4l2_fwnode_endpoint_free(&bus_cfg);
1669	fwnode_handle_put(ep);
1670	return NULL;
1671}
1672
1673static int imx355_probe(struct i2c_client *client)
1674{
1675	struct imx355 *imx355;
1676	int ret;
1677
1678	imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
1679	if (!imx355)
1680		return -ENOMEM;
1681
1682	mutex_init(&imx355->mutex);
1683
1684	/* Initialize subdev */
1685	v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
1686
1687	/* Check module identity */
1688	ret = imx355_identify_module(imx355);
1689	if (ret) {
1690		dev_err(&client->dev, "failed to find sensor: %d", ret);
1691		goto error_probe;
1692	}
1693
1694	imx355->hwcfg = imx355_get_hwcfg(&client->dev);
1695	if (!imx355->hwcfg) {
1696		dev_err(&client->dev, "failed to get hwcfg");
1697		ret = -ENODEV;
1698		goto error_probe;
1699	}
1700
1701	/* Set default mode to max resolution */
1702	imx355->cur_mode = &supported_modes[0];
1703
1704	ret = imx355_init_controls(imx355);
1705	if (ret) {
1706		dev_err(&client->dev, "failed to init controls: %d", ret);
1707		goto error_probe;
1708	}
1709
1710	/* Initialize subdev */
1711	imx355->sd.internal_ops = &imx355_internal_ops;
1712	imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1713		V4L2_SUBDEV_FL_HAS_EVENTS;
1714	imx355->sd.entity.ops = &imx355_subdev_entity_ops;
1715	imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1716
1717	/* Initialize source pad */
1718	imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
1719	ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
1720	if (ret) {
1721		dev_err(&client->dev, "failed to init entity pads: %d", ret);
1722		goto error_handler_free;
1723	}
1724
1725	/*
1726	 * Device is already turned on by i2c-core with ACPI domain PM.
1727	 * Enable runtime PM and turn off the device.
1728	 */
1729	pm_runtime_set_active(&client->dev);
1730	pm_runtime_enable(&client->dev);
1731	pm_runtime_idle(&client->dev);
1732
1733	ret = v4l2_async_register_subdev_sensor(&imx355->sd);
1734	if (ret < 0)
1735		goto error_media_entity_runtime_pm;
1736
1737	return 0;
1738
1739error_media_entity_runtime_pm:
1740	pm_runtime_disable(&client->dev);
1741	pm_runtime_set_suspended(&client->dev);
1742	media_entity_cleanup(&imx355->sd.entity);
1743
1744error_handler_free:
1745	v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
1746
1747error_probe:
1748	mutex_destroy(&imx355->mutex);
1749
1750	return ret;
1751}
1752
1753static void imx355_remove(struct i2c_client *client)
1754{
1755	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1756	struct imx355 *imx355 = to_imx355(sd);
1757
1758	v4l2_async_unregister_subdev(sd);
1759	media_entity_cleanup(&sd->entity);
1760	v4l2_ctrl_handler_free(sd->ctrl_handler);
1761
1762	pm_runtime_disable(&client->dev);
1763	pm_runtime_set_suspended(&client->dev);
1764
1765	mutex_destroy(&imx355->mutex);
1766}
1767
1768static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
1769	{ "SONY355A" },
1770	{ /* sentinel */ }
1771};
1772MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
1773
1774static struct i2c_driver imx355_i2c_driver = {
1775	.driver = {
1776		.name = "imx355",
1777		.acpi_match_table = ACPI_PTR(imx355_acpi_ids),
1778	},
1779	.probe = imx355_probe,
1780	.remove = imx355_remove,
1781};
1782module_i2c_driver(imx355_i2c_driver);
1783
1784MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
1785MODULE_AUTHOR("Rapolu, Chiranjeevi");
1786MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1787MODULE_AUTHOR("Yang, Hyungwoo");
1788MODULE_DESCRIPTION("Sony imx355 sensor driver");
1789MODULE_LICENSE("GPL v2");
1790