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