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

source code of linux/drivers/media/i2c/imx355.c