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