]> git.ipfire.org Git - thirdparty/linux.git/blob
e1b1d2fc79dd
[thirdparty/linux.git] /
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 ret = v4l2_async_register_subdev_sensor(&imx355->sd);
1751 if (ret < 0)
1752 goto error_media_entity;
1753
1754 /*
1755 * Device is already turned on by i2c-core with ACPI domain PM.
1756 * Enable runtime PM and turn off the device.
1757 */
1758 pm_runtime_set_active(&client->dev);
1759 pm_runtime_enable(&client->dev);
1760 pm_runtime_idle(&client->dev);
1761
1762 return 0;
1763
1764 error_media_entity:
1765 media_entity_cleanup(&imx355->sd.entity);
1766
1767 error_handler_free:
1768 v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
1769
1770 error_probe:
1771 mutex_destroy(&imx355->mutex);
1772
1773 return ret;
1774 }
1775
1776 static void imx355_remove(struct i2c_client *client)
1777 {
1778 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1779 struct imx355 *imx355 = to_imx355(sd);
1780
1781 v4l2_async_unregister_subdev(sd);
1782 media_entity_cleanup(&sd->entity);
1783 v4l2_ctrl_handler_free(sd->ctrl_handler);
1784
1785 pm_runtime_disable(&client->dev);
1786 pm_runtime_set_suspended(&client->dev);
1787
1788 mutex_destroy(&imx355->mutex);
1789 }
1790
1791 static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
1792 { "SONY355A" },
1793 { /* sentinel */ }
1794 };
1795 MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
1796
1797 static struct i2c_driver imx355_i2c_driver = {
1798 .driver = {
1799 .name = "imx355",
1800 .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
1801 },
1802 .probe = imx355_probe,
1803 .remove = imx355_remove,
1804 };
1805 module_i2c_driver(imx355_i2c_driver);
1806
1807 MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
1808 MODULE_AUTHOR("Rapolu, Chiranjeevi");
1809 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1810 MODULE_AUTHOR("Yang, Hyungwoo");
1811 MODULE_DESCRIPTION("Sony imx355 sensor driver");
1812 MODULE_LICENSE("GPL v2");