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