1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * imx378 driver
4 *
5 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
6 * V0.0X01.0X01 add imx378 driver.
7 * V0.0X01.0X02 add imx378 support mirror and flip.
8 * V0.0X01.0X03 add quick stream on/off
9 */
10
11 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/delay.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/i2c.h>
16 #include <linux/module.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/sysfs.h>
20 #include <linux/slab.h>
21 #include <linux/version.h>
22 #include <linux/rk-camera-module.h>
23 #include <media/media-entity.h>
24 #include <media/v4l2-async.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-subdev.h>
27 #include <media/v4l2-fwnode.h>
28 #include <linux/pinctrl/consumer.h>
29 #include <linux/of.h>
30 #include <linux/of_device.h>
31 #include <linux/of_graph.h>
32 #include <linux/of_platform.h>
33 #include <linux/of_gpio.h>
34 #include <linux/mfd/syscon.h>
35 #include <linux/rk-preisp.h>
36
37 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
38
39 #ifndef V4L2_CID_DIGITAL_GAIN
40 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
41 #endif
42
43 #define IMX378_LINK_FREQ_848 848000000// 1696Mbps
44
45 #define IMX378_LANES 4
46
47 #define PIXEL_RATE_WITH_848M_10BIT (IMX378_LINK_FREQ_848 * 2 / 10 * 4)
48 #define PIXEL_RATE_WITH_848M_12BIT (IMX378_LINK_FREQ_848 * 2 / 12 * 4)
49
50 #define IMX378_XVCLK_FREQ 24000000
51
52 #define CHIP_ID 0x0378
53 #define IMX378_REG_CHIP_ID_H 0x0016
54 #define IMX378_REG_CHIP_ID_L 0x0017
55
56 #define IMX378_REG_CTRL_MODE 0x0100
57 #define IMX378_MODE_SW_STANDBY 0x0
58 #define IMX378_MODE_STREAMING 0x1
59
60 #define IMX378_REG_EXPOSURE_H 0x0202
61 #define IMX378_REG_EXPOSURE_L 0x0203
62 #define IMX378_EXPOSURE_MIN 2
63 #define IMX378_EXPOSURE_STEP 1
64 #define IMX378_VTS_MAX 0x7fff
65
66 #define IMX378_REG_GAIN_H 0x0204
67 #define IMX378_REG_GAIN_L 0x0205
68 #define IMX378_GAIN_MIN 0x00
69 #define IMX378_GAIN_MAX 0x13AB
70 #define IMX378_GAIN_STEP 1
71 #define IMX378_GAIN_DEFAULT 0x0080
72
73 #define IMX378_REG_DGAIN 0x3ff9
74 #define IMX378_DGAIN_MODE 1
75 #define IMX378_REG_DGAINGR_H 0x020e
76 #define IMX378_REG_DGAINGR_L 0x020f
77 #define IMX378_REG_DGAINR_H 0x0210
78 #define IMX378_REG_DGAINR_L 0x0211
79 #define IMX378_REG_DGAINB_H 0x0212
80 #define IMX378_REG_DGAINB_L 0x0213
81 #define IMX378_REG_DGAINGB_H 0x0214
82 #define IMX378_REG_DGAINGB_L 0x0215
83 #define IMX378_REG_GAIN_GLOBAL_H 0x3ffc
84 #define IMX378_REG_GAIN_GLOBAL_L 0x3ffd
85
86 //#define IMX378_REG_TEST_PATTERN_H 0x0600
87 #define IMX378_REG_TEST_PATTERN 0x0601
88 #define IMX378_TEST_PATTERN_ENABLE 0x1
89 #define IMX378_TEST_PATTERN_DISABLE 0x0
90
91 #define IMX378_REG_VTS_H 0x0340
92 #define IMX378_REG_VTS_L 0x0341
93
94 #define IMX378_FLIP_MIRROR_REG 0x0101
95 #define IMX378_MIRROR_BIT_MASK BIT(0)
96 #define IMX378_FLIP_BIT_MASK BIT(1)
97
98 #define IMX378_FETCH_EXP_H(VAL) (((VAL) >> 8) & 0xFF)
99 #define IMX378_FETCH_EXP_L(VAL) ((VAL) & 0xFF)
100
101 #define IMX378_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0x03)
102 #define IMX378_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF)
103
104 #define IMX378_FETCH_DGAIN_H(VAL) (((VAL) >> 8) & 0x0F)
105 #define IMX378_FETCH_DGAIN_L(VAL) ((VAL) & 0xFF)
106
107 #define IMX378_FETCH_RHS1_H(VAL) (((VAL) >> 16) & 0x0F)
108 #define IMX378_FETCH_RHS1_M(VAL) (((VAL) >> 8) & 0xFF)
109 #define IMX378_FETCH_RHS1_L(VAL) ((VAL) & 0xFF)
110
111 #define REG_DELAY 0xFFFE
112 #define REG_NULL 0xFFFF
113
114 #define IMX378_REG_VALUE_08BIT 1
115 #define IMX378_REG_VALUE_16BIT 2
116 #define IMX378_REG_VALUE_24BIT 3
117
118 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
119
120 #define IMX378_NAME "imx378"
121
122 static const char * const imx378_supply_names[] = {
123 "avdd", /* Analog power */
124 "dovdd", /* Digital I/O power */
125 "dvdd", /* Digital core power */
126 };
127
128 #define IMX378_NUM_SUPPLIES ARRAY_SIZE(imx378_supply_names)
129
130 struct regval {
131 u16 addr;
132 u8 val;
133 };
134
135 struct imx378_mode {
136 u32 bus_fmt;
137 u32 width;
138 u32 height;
139 struct v4l2_fract max_fps;
140 u32 hts_def;
141 u32 vts_def;
142 u32 exp_def;
143 const struct regval *reg_list;
144 u32 hdr_mode;
145 u32 vc[PAD_MAX];
146 };
147
148 struct imx378 {
149 struct i2c_client *client;
150 struct clk *xvclk;
151 struct gpio_desc *reset_gpio;
152 struct gpio_desc *pwdn_gpio;
153 struct regulator_bulk_data supplies[IMX378_NUM_SUPPLIES];
154
155 struct pinctrl *pinctrl;
156 struct pinctrl_state *pins_default;
157 struct pinctrl_state *pins_sleep;
158
159 struct v4l2_subdev subdev;
160 struct media_pad pad;
161 struct v4l2_ctrl_handler ctrl_handler;
162 struct v4l2_ctrl *exposure;
163 struct v4l2_ctrl *anal_gain;
164 struct v4l2_ctrl *digi_gain;
165 struct v4l2_ctrl *hblank;
166 struct v4l2_ctrl *vblank;
167 struct v4l2_ctrl *h_flip;
168 struct v4l2_ctrl *v_flip;
169 struct v4l2_ctrl *test_pattern;
170 struct v4l2_ctrl *pixel_rate;
171 struct v4l2_ctrl *link_freq;
172 struct mutex mutex;
173 bool streaming;
174 bool power_on;
175 const struct imx378_mode *cur_mode;
176 u32 cfg_num;
177 u32 cur_pixel_rate;
178 u32 cur_link_freq;
179 u32 module_index;
180 const char *module_facing;
181 const char *module_name;
182 const char *len_name;
183 u32 cur_vts;
184 bool has_init_exp;
185 struct preisp_hdrae_exp_s init_hdrae_exp;
186 u8 flip;
187 };
188
189 #define to_imx378(sd) container_of(sd, struct imx378, subdev)
190
191 /*
192 *IMX378LQR All-pixel scan CSI-2_4lane 24Mhz
193 *AD:10bit Output:10bit 1696Mbps Master Mode 30fps
194 *Tool ver : Ver4.0
195 */
196 static const struct regval imx378_linear_10_4056x3040_regs[] = {
197 {0x0101, 0x00},
198 {0x0136, 0x18},
199 {0x0137, 0x00},
200 {0xE000, 0x00},
201 {0x4AE9, 0x18},
202 {0x4AEA, 0x08},
203 {0xF61C, 0x04},
204 {0xF61E, 0x04},
205 {0x4AE9, 0x21},
206 {0x4AEA, 0x80},
207 {0x38A8, 0x1F},
208 {0x38A9, 0xFF},
209 {0x38AA, 0x1F},
210 {0x38AB, 0xFF},
211 {0x55D4, 0x00},
212 {0x55D5, 0x00},
213 {0x55D6, 0x07},
214 {0x55D7, 0xFF},
215 {0x55E8, 0x07},
216 {0x55E9, 0xFF},
217 {0x55EA, 0x00},
218 {0x55EB, 0x00},
219 {0x574C, 0x07},
220 {0x574D, 0xFF},
221 {0x574E, 0x00},
222 {0x574F, 0x00},
223 {0x5754, 0x00},
224 {0x5755, 0x00},
225 {0x5756, 0x07},
226 {0x5757, 0xFF},
227 {0x5973, 0x04},
228 {0x5974, 0x01},
229 {0x5D13, 0xC3},
230 {0x5D14, 0x58},
231 {0x5D15, 0xA3},
232 {0x5D16, 0x1D},
233 {0x5D17, 0x65},
234 {0x5D18, 0x8C},
235 {0x5D1A, 0x06},
236 {0x5D1B, 0xA9},
237 {0x5D1C, 0x45},
238 {0x5D1D, 0x3A},
239 {0x5D1E, 0xAB},
240 {0x5D1F, 0x15},
241 {0x5D21, 0x0E},
242 {0x5D22, 0x52},
243 {0x5D23, 0xAA},
244 {0x5D24, 0x7D},
245 {0x5D25, 0x57},
246 {0x5D26, 0xA8},
247 {0x5D37, 0x5A},
248 {0x5D38, 0x5A},
249 {0x5D77, 0x7F},
250 {0x7B75, 0x0E},
251 {0x7B76, 0x0B},
252 {0x7B77, 0x08},
253 {0x7B78, 0x0A},
254 {0x7B79, 0x47},
255 {0x7B7C, 0x00},
256 {0x7B7D, 0x00},
257 {0x8D1F, 0x00},
258 {0x8D27, 0x00},
259 {0x9004, 0x03},
260 {0x9200, 0x50},
261 {0x9201, 0x6C},
262 {0x9202, 0x71},
263 {0x9203, 0x00},
264 {0x9204, 0x71},
265 {0x9205, 0x01},
266 {0x9371, 0x6A},
267 {0x9373, 0x6A},
268 {0x9375, 0x64},
269 {0x991A, 0x00},
270 {0x996B, 0x8C},
271 {0x996C, 0x64},
272 {0x996D, 0x50},
273 {0x9A4C, 0x0D},
274 {0x9A4D, 0x0D},
275 {0xA001, 0x0A},
276 {0xA003, 0x0A},
277 {0xA005, 0x0A},
278 {0xA006, 0x01},
279 {0xA007, 0xC0},
280 {0xA009, 0xC0},
281
282 {0x3D8A, 0x01},
283 {0x4421, 0x08},
284 {0x7B3B, 0x01},
285 {0x7B4C, 0x00},
286 {0x9905, 0x00},
287 {0x9907, 0x00},
288 {0x9909, 0x00},
289 {0x990B, 0x00},
290 {0x9944, 0x3C},
291 {0x9947, 0x3C},
292 {0x994A, 0x8C},
293 {0x994B, 0x50},
294 {0x994C, 0x1B},
295 {0x994D, 0x8C},
296 {0x994E, 0x50},
297 {0x994F, 0x1B},
298 {0x9950, 0x8C},
299 {0x9951, 0x1B},
300 {0x9952, 0x0A},
301 {0x9953, 0x8C},
302 {0x9954, 0x1B},
303 {0x9955, 0x0A},
304 {0x9A13, 0x04},
305 {0x9A14, 0x04},
306 {0x9A19, 0x00},
307 {0x9A1C, 0x04},
308 {0x9A1D, 0x04},
309 {0x9A26, 0x05},
310 {0x9A27, 0x05},
311 {0x9A2C, 0x01},
312 {0x9A2D, 0x03},
313 {0x9A2F, 0x05},
314 {0x9A30, 0x05},
315 {0x9A41, 0x00},
316 {0x9A46, 0x00},
317 {0x9A47, 0x00},
318 {0x9C17, 0x35},
319 {0x9C1D, 0x31},
320 {0x9C29, 0x50},
321 {0x9C3B, 0x2F},
322 {0x9C41, 0x6B},
323 {0x9C47, 0x2D},
324 {0x9C4D, 0x40},
325 {0x9C6B, 0x00},
326 {0x9C71, 0xC8},
327 {0x9C73, 0x32},
328 {0x9C75, 0x04},
329 {0x9C7D, 0x2D},
330 {0x9C83, 0x40},
331 {0x9C94, 0x3F},
332 {0x9C95, 0x3F},
333 {0x9C96, 0x3F},
334 {0x9C97, 0x00},
335 {0x9C98, 0x00},
336 {0x9C99, 0x00},
337 {0x9C9A, 0x3F},
338 {0x9C9B, 0x3F},
339 {0x9C9C, 0x3F},
340 {0x9CA0, 0x0F},
341 {0x9CA1, 0x0F},
342 {0x9CA2, 0x0F},
343 {0x9CA3, 0x00},
344 {0x9CA4, 0x00},
345 {0x9CA5, 0x00},
346 {0x9CA6, 0x1E},
347 {0x9CA7, 0x1E},
348 {0x9CA8, 0x1E},
349 {0x9CA9, 0x00},
350 {0x9CAA, 0x00},
351 {0x9CAB, 0x00},
352 {0x9CAC, 0x09},
353 {0x9CAD, 0x09},
354 {0x9CAE, 0x09},
355 {0x9CBD, 0x50},
356 {0x9CBF, 0x50},
357 {0x9CC1, 0x50},
358 {0x9CC3, 0x40},
359 {0x9CC5, 0x40},
360 {0x9CC7, 0x40},
361 {0x9CC9, 0x0A},
362 {0x9CCB, 0x0A},
363 {0x9CCD, 0x0A},
364 {0x9D17, 0x35},
365 {0x9D1D, 0x31},
366 {0x9D29, 0x50},
367 {0x9D3B, 0x2F},
368 {0x9D41, 0x6B},
369 {0x9D47, 0x42},
370 {0x9D4D, 0x5A},
371 {0x9D6B, 0x00},
372 {0x9D71, 0xC8},
373 {0x9D73, 0x32},
374 {0x9D75, 0x04},
375 {0x9D7D, 0x42},
376 {0x9D83, 0x5A},
377 {0x9D94, 0x3F},
378 {0x9D95, 0x3F},
379 {0x9D96, 0x3F},
380 {0x9D97, 0x00},
381 {0x9D98, 0x00},
382 {0x9D99, 0x00},
383 {0x9D9A, 0x3F},
384 {0x9D9B, 0x3F},
385 {0x9D9C, 0x3F},
386 {0x9D9D, 0x1F},
387 {0x9D9E, 0x1F},
388 {0x9D9F, 0x1F},
389 {0x9DA0, 0x0F},
390 {0x9DA1, 0x0F},
391 {0x9DA2, 0x0F},
392 {0x9DA3, 0x00},
393 {0x9DA4, 0x00},
394 {0x9DA5, 0x00},
395 {0x9DA6, 0x1E},
396 {0x9DA7, 0x1E},
397 {0x9DA8, 0x1E},
398 {0x9DA9, 0x00},
399 {0x9DAA, 0x00},
400 {0x9DAB, 0x00},
401 {0x9DAC, 0x09},
402 {0x9DAD, 0x09},
403 {0x9DAE, 0x09},
404 {0x9DC9, 0x0A},
405 {0x9DCB, 0x0A},
406 {0x9DCD, 0x0A},
407 {0x9E17, 0x35},
408 {0x9E1D, 0x31},
409 {0x9E29, 0x50},
410 {0x9E3B, 0x2F},
411 {0x9E41, 0x6B},
412 {0x9E47, 0x2D},
413 {0x9E4D, 0x40},
414 {0x9E6B, 0x00},
415 {0x9E71, 0xC8},
416 {0x9E73, 0x32},
417 {0x9E75, 0x04},
418 {0x9E94, 0x0F},
419 {0x9E95, 0x0F},
420 {0x9E96, 0x0F},
421 {0x9E97, 0x00},
422 {0x9E98, 0x00},
423 {0x9E99, 0x00},
424 {0x9EA0, 0x0F},
425 {0x9EA1, 0x0F},
426 {0x9EA2, 0x0F},
427 {0x9EA3, 0x00},
428 {0x9EA4, 0x00},
429 {0x9EA5, 0x00},
430 {0x9EA6, 0x3F},
431 {0x9EA7, 0x3F},
432 {0x9EA8, 0x3F},
433 {0x9EA9, 0x00},
434 {0x9EAA, 0x00},
435 {0x9EAB, 0x00},
436 {0x9EAC, 0x09},
437 {0x9EAD, 0x09},
438 {0x9EAE, 0x09},
439 {0x9EC9, 0x0A},
440 {0x9ECB, 0x0A},
441 {0x9ECD, 0x0A},
442 {0x9F17, 0x35},
443 {0x9F1D, 0x31},
444 {0x9F29, 0x50},
445 {0x9F3B, 0x2F},
446 {0x9F41, 0x6B},
447 {0x9F47, 0x42},
448 {0x9F4D, 0x5A},
449 {0x9F6B, 0x00},
450 {0x9F71, 0xC8},
451 {0x9F73, 0x32},
452 {0x9F75, 0x04},
453 {0x9F94, 0x0F},
454 {0x9F95, 0x0F},
455 {0x9F96, 0x0F},
456 {0x9F97, 0x00},
457 {0x9F98, 0x00},
458 {0x9F99, 0x00},
459 {0x9F9A, 0x2F},
460 {0x9F9B, 0x2F},
461 {0x9F9C, 0x2F},
462 {0x9F9D, 0x00},
463 {0x9F9E, 0x00},
464 {0x9F9F, 0x00},
465 {0x9FA0, 0x0F},
466 {0x9FA1, 0x0F},
467 {0x9FA2, 0x0F},
468 {0x9FA3, 0x00},
469 {0x9FA4, 0x00},
470 {0x9FA5, 0x00},
471 {0x9FA6, 0x1E},
472 {0x9FA7, 0x1E},
473 {0x9FA8, 0x1E},
474 {0x9FA9, 0x00},
475 {0x9FAA, 0x00},
476 {0x9FAB, 0x00},
477 {0x9FAC, 0x09},
478 {0x9FAD, 0x09},
479 {0x9FAE, 0x09},
480 {0x9FC9, 0x0A},
481 {0x9FCB, 0x0A},
482 {0x9FCD, 0x0A},
483 {0xA14B, 0xFF},
484 {0xA151, 0x0C},
485 {0xA153, 0x50},
486 {0xA155, 0x02},
487 {0xA157, 0x00},
488 {0xA1AD, 0xFF},
489 {0xA1B3, 0x0C},
490 {0xA1B5, 0x50},
491 {0xA1B9, 0x00},
492 {0xA24B, 0xFF},
493 {0xA257, 0x00},
494 {0xA2AD, 0xFF},
495 {0xA2B9, 0x00},
496 {0xB21F, 0x04},
497 {0xB35C, 0x00},
498 {0xB35E, 0x08},
499
500 {0x0112, 0x0A},
501 {0x0113, 0x0A},
502 {0x0114, 0x03},
503 {0x0342, 0x16},
504 {0x0343, 0xA8},
505 {0x0340, 0x0F},
506 {0x0341, 0x3C},
507 {0x0344, 0x00},
508 {0x0345, 0x00},
509 {0x0346, 0x00},
510 {0x0347, 0x00},
511 {0x0348, 0x0F},
512 {0x0349, 0xD7},
513 {0x034A, 0x0B},
514 {0x034B, 0xDF},
515 {0x0220, 0x00},
516 {0x0221, 0x11},
517 {0x0381, 0x01},
518 {0x0383, 0x01},
519 {0x0385, 0x01},
520 {0x0387, 0x01},
521 {0x0900, 0x00},
522 {0x0901, 0x11},
523 {0x0902, 0x02},
524 {0x3140, 0x02},
525 {0x3C00, 0x00},
526 {0x3C01, 0x03},
527 {0x3C02, 0xDC},
528 {0x3F0D, 0x00},
529 {0x5748, 0x07},
530 {0x5749, 0xFF},
531 {0x574A, 0x00},
532 {0x574B, 0x00},
533 {0x7B53, 0x01},
534 {0x9369, 0x5A},
535 {0x936B, 0x55},
536 {0x936D, 0x28},
537 {0x9304, 0x03},
538 {0x9305, 0x00},
539 {0x9E9A, 0x2F},
540 {0x9E9B, 0x2F},
541 {0x9E9C, 0x2F},
542 {0x9E9D, 0x00},
543 {0x9E9E, 0x00},
544 {0x9E9F, 0x00},
545 {0xA2A9, 0x60},
546 {0xA2B7, 0x00},
547 {0x0401, 0x00},
548 {0x0404, 0x00},
549 {0x0405, 0x10},
550 {0x0408, 0x00},
551 {0x0409, 0x00},
552 {0x040A, 0x00},
553 {0x040B, 0x00},
554 {0x040C, 0x0F},
555 {0x040D, 0xD8},
556 {0x040E, 0x0B},
557 {0x040F, 0xE0},
558 {0x034C, 0x0F},
559 {0x034D, 0xD8},
560 {0x034E, 0x0B},
561 {0x034F, 0xE0},
562 {0x0301, 0x05},
563 {0x0303, 0x02},
564 {0x0305, 0x03},
565 {0x0306, 0x00},
566 {0x0307, 0xD4},
567 {0x0309, 0x0A},
568 {0x030B, 0x01},
569 {0x030D, 0x02},
570 {0x030E, 0x01},
571 {0x030F, 0x5E},
572 {0x0310, 0x00},
573 {0x0820, 0x1A},
574 {0x0821, 0x80},
575 {0x0822, 0x00},
576 {0x0823, 0x00},
577 {0x3E20, 0x01},
578 {0x3E37, 0x01},
579 {0x3F50, 0x00},
580 {0x3F56, 0x00},
581 {0x3F57, 0xA0},
582 {REG_NULL, 0x00},
583 };
584
585 static const struct regval imx378_linear_10_3840x2160_regs[] = {
586 {0x0101, 0x00},
587 {0x0136, 0x18},
588 {0x0137, 0x00},
589 {0xE000, 0x00},
590 {0x4AE9, 0x18},
591 {0x4AEA, 0x08},
592 {0xF61C, 0x04},
593 {0xF61E, 0x04},
594 {0x4AE9, 0x21},
595 {0x4AEA, 0x80},
596 {0x38A8, 0x1F},
597 {0x38A9, 0xFF},
598 {0x38AA, 0x1F},
599 {0x38AB, 0xFF},
600 {0x55D4, 0x00},
601 {0x55D5, 0x00},
602 {0x55D6, 0x07},
603 {0x55D7, 0xFF},
604 {0x55E8, 0x07},
605 {0x55E9, 0xFF},
606 {0x55EA, 0x00},
607 {0x55EB, 0x00},
608 {0x574C, 0x07},
609 {0x574D, 0xFF},
610 {0x574E, 0x00},
611 {0x574F, 0x00},
612 {0x5754, 0x00},
613 {0x5755, 0x00},
614 {0x5756, 0x07},
615 {0x5757, 0xFF},
616 {0x5973, 0x04},
617 {0x5974, 0x01},
618 {0x5D13, 0xC3},
619 {0x5D14, 0x58},
620 {0x5D15, 0xA3},
621 {0x5D16, 0x1D},
622 {0x5D17, 0x65},
623 {0x5D18, 0x8C},
624 {0x5D1A, 0x06},
625 {0x5D1B, 0xA9},
626 {0x5D1C, 0x45},
627 {0x5D1D, 0x3A},
628 {0x5D1E, 0xAB},
629 {0x5D1F, 0x15},
630 {0x5D21, 0x0E},
631 {0x5D22, 0x52},
632 {0x5D23, 0xAA},
633 {0x5D24, 0x7D},
634 {0x5D25, 0x57},
635 {0x5D26, 0xA8},
636 {0x5D37, 0x5A},
637 {0x5D38, 0x5A},
638 {0x5D77, 0x7F},
639 {0x7B75, 0x0E},
640 {0x7B76, 0x0B},
641 {0x7B77, 0x08},
642 {0x7B78, 0x0A},
643 {0x7B79, 0x47},
644 {0x7B7C, 0x00},
645 {0x7B7D, 0x00},
646 {0x8D1F, 0x00},
647 {0x8D27, 0x00},
648 {0x9004, 0x03},
649 {0x9200, 0x50},
650 {0x9201, 0x6C},
651 {0x9202, 0x71},
652 {0x9203, 0x00},
653 {0x9204, 0x71},
654 {0x9205, 0x01},
655 {0x9371, 0x6A},
656 {0x9373, 0x6A},
657 {0x9375, 0x64},
658 {0x991A, 0x00},
659 {0x996B, 0x8C},
660 {0x996C, 0x64},
661 {0x996D, 0x50},
662 {0x9A4C, 0x0D},
663 {0x9A4D, 0x0D},
664 {0xA001, 0x0A},
665 {0xA003, 0x0A},
666 {0xA005, 0x0A},
667 {0xA006, 0x01},
668 {0xA007, 0xC0},
669 {0xA009, 0xC0},
670
671 {0x3D8A, 0x01},
672 {0x4421, 0x08},
673 {0x7B3B, 0x01},
674 {0x7B4C, 0x00},
675 {0x9905, 0x00},
676 {0x9907, 0x00},
677 {0x9909, 0x00},
678 {0x990B, 0x00},
679 {0x9944, 0x3C},
680 {0x9947, 0x3C},
681 {0x994A, 0x8C},
682 {0x994B, 0x50},
683 {0x994C, 0x1B},
684 {0x994D, 0x8C},
685 {0x994E, 0x50},
686 {0x994F, 0x1B},
687 {0x9950, 0x8C},
688 {0x9951, 0x1B},
689 {0x9952, 0x0A},
690 {0x9953, 0x8C},
691 {0x9954, 0x1B},
692 {0x9955, 0x0A},
693 {0x9A13, 0x04},
694 {0x9A14, 0x04},
695 {0x9A19, 0x00},
696 {0x9A1C, 0x04},
697 {0x9A1D, 0x04},
698 {0x9A26, 0x05},
699 {0x9A27, 0x05},
700 {0x9A2C, 0x01},
701 {0x9A2D, 0x03},
702 {0x9A2F, 0x05},
703 {0x9A30, 0x05},
704 {0x9A41, 0x00},
705 {0x9A46, 0x00},
706 {0x9A47, 0x00},
707 {0x9C17, 0x35},
708 {0x9C1D, 0x31},
709 {0x9C29, 0x50},
710 {0x9C3B, 0x2F},
711 {0x9C41, 0x6B},
712 {0x9C47, 0x2D},
713 {0x9C4D, 0x40},
714 {0x9C6B, 0x00},
715 {0x9C71, 0xC8},
716 {0x9C73, 0x32},
717 {0x9C75, 0x04},
718 {0x9C7D, 0x2D},
719 {0x9C83, 0x40},
720 {0x9C94, 0x3F},
721 {0x9C95, 0x3F},
722 {0x9C96, 0x3F},
723 {0x9C97, 0x00},
724 {0x9C98, 0x00},
725 {0x9C99, 0x00},
726 {0x9C9A, 0x3F},
727 {0x9C9B, 0x3F},
728 {0x9C9C, 0x3F},
729 {0x9CA0, 0x0F},
730 {0x9CA1, 0x0F},
731 {0x9CA2, 0x0F},
732 {0x9CA3, 0x00},
733 {0x9CA4, 0x00},
734 {0x9CA5, 0x00},
735 {0x9CA6, 0x1E},
736 {0x9CA7, 0x1E},
737 {0x9CA8, 0x1E},
738 {0x9CA9, 0x00},
739 {0x9CAA, 0x00},
740 {0x9CAB, 0x00},
741 {0x9CAC, 0x09},
742 {0x9CAD, 0x09},
743 {0x9CAE, 0x09},
744 {0x9CBD, 0x50},
745 {0x9CBF, 0x50},
746 {0x9CC1, 0x50},
747 {0x9CC3, 0x40},
748 {0x9CC5, 0x40},
749 {0x9CC7, 0x40},
750 {0x9CC9, 0x0A},
751 {0x9CCB, 0x0A},
752 {0x9CCD, 0x0A},
753 {0x9D17, 0x35},
754 {0x9D1D, 0x31},
755 {0x9D29, 0x50},
756 {0x9D3B, 0x2F},
757 {0x9D41, 0x6B},
758 {0x9D47, 0x42},
759 {0x9D4D, 0x5A},
760 {0x9D6B, 0x00},
761 {0x9D71, 0xC8},
762 {0x9D73, 0x32},
763 {0x9D75, 0x04},
764 {0x9D7D, 0x42},
765 {0x9D83, 0x5A},
766 {0x9D94, 0x3F},
767 {0x9D95, 0x3F},
768 {0x9D96, 0x3F},
769 {0x9D97, 0x00},
770 {0x9D98, 0x00},
771 {0x9D99, 0x00},
772 {0x9D9A, 0x3F},
773 {0x9D9B, 0x3F},
774 {0x9D9C, 0x3F},
775 {0x9D9D, 0x1F},
776 {0x9D9E, 0x1F},
777 {0x9D9F, 0x1F},
778 {0x9DA0, 0x0F},
779 {0x9DA1, 0x0F},
780 {0x9DA2, 0x0F},
781 {0x9DA3, 0x00},
782 {0x9DA4, 0x00},
783 {0x9DA5, 0x00},
784 {0x9DA6, 0x1E},
785 {0x9DA7, 0x1E},
786 {0x9DA8, 0x1E},
787 {0x9DA9, 0x00},
788 {0x9DAA, 0x00},
789 {0x9DAB, 0x00},
790 {0x9DAC, 0x09},
791 {0x9DAD, 0x09},
792 {0x9DAE, 0x09},
793 {0x9DC9, 0x0A},
794 {0x9DCB, 0x0A},
795 {0x9DCD, 0x0A},
796 {0x9E17, 0x35},
797 {0x9E1D, 0x31},
798 {0x9E29, 0x50},
799 {0x9E3B, 0x2F},
800 {0x9E41, 0x6B},
801 {0x9E47, 0x2D},
802 {0x9E4D, 0x40},
803 {0x9E6B, 0x00},
804 {0x9E71, 0xC8},
805 {0x9E73, 0x32},
806 {0x9E75, 0x04},
807 {0x9E94, 0x0F},
808 {0x9E95, 0x0F},
809 {0x9E96, 0x0F},
810 {0x9E97, 0x00},
811 {0x9E98, 0x00},
812 {0x9E99, 0x00},
813 {0x9EA0, 0x0F},
814 {0x9EA1, 0x0F},
815 {0x9EA2, 0x0F},
816 {0x9EA3, 0x00},
817 {0x9EA4, 0x00},
818 {0x9EA5, 0x00},
819 {0x9EA6, 0x3F},
820 {0x9EA7, 0x3F},
821 {0x9EA8, 0x3F},
822 {0x9EA9, 0x00},
823 {0x9EAA, 0x00},
824 {0x9EAB, 0x00},
825 {0x9EAC, 0x09},
826 {0x9EAD, 0x09},
827 {0x9EAE, 0x09},
828 {0x9EC9, 0x0A},
829 {0x9ECB, 0x0A},
830 {0x9ECD, 0x0A},
831 {0x9F17, 0x35},
832 {0x9F1D, 0x31},
833 {0x9F29, 0x50},
834 {0x9F3B, 0x2F},
835 {0x9F41, 0x6B},
836 {0x9F47, 0x42},
837 {0x9F4D, 0x5A},
838 {0x9F6B, 0x00},
839 {0x9F71, 0xC8},
840 {0x9F73, 0x32},
841 {0x9F75, 0x04},
842 {0x9F94, 0x0F},
843 {0x9F95, 0x0F},
844 {0x9F96, 0x0F},
845 {0x9F97, 0x00},
846 {0x9F98, 0x00},
847 {0x9F99, 0x00},
848 {0x9F9A, 0x2F},
849 {0x9F9B, 0x2F},
850 {0x9F9C, 0x2F},
851 {0x9F9D, 0x00},
852 {0x9F9E, 0x00},
853 {0x9F9F, 0x00},
854 {0x9FA0, 0x0F},
855 {0x9FA1, 0x0F},
856 {0x9FA2, 0x0F},
857 {0x9FA3, 0x00},
858 {0x9FA4, 0x00},
859 {0x9FA5, 0x00},
860 {0x9FA6, 0x1E},
861 {0x9FA7, 0x1E},
862 {0x9FA8, 0x1E},
863 {0x9FA9, 0x00},
864 {0x9FAA, 0x00},
865 {0x9FAB, 0x00},
866 {0x9FAC, 0x09},
867 {0x9FAD, 0x09},
868 {0x9FAE, 0x09},
869 {0x9FC9, 0x0A},
870 {0x9FCB, 0x0A},
871 {0x9FCD, 0x0A},
872 {0xA14B, 0xFF},
873 {0xA151, 0x0C},
874 {0xA153, 0x50},
875 {0xA155, 0x02},
876 {0xA157, 0x00},
877 {0xA1AD, 0xFF},
878 {0xA1B3, 0x0C},
879 {0xA1B5, 0x50},
880 {0xA1B9, 0x00},
881 {0xA24B, 0xFF},
882 {0xA257, 0x00},
883 {0xA2AD, 0xFF},
884 {0xA2B9, 0x00},
885 {0xB21F, 0x04},
886 {0xB35C, 0x00},
887 {0xB35E, 0x08},
888
889 {0x0112, 0x0A},
890 {0x0113, 0x0A},
891 {0x0114, 0x03},
892 {0x0342, 0x16},
893 {0x0343, 0xA8},
894 {0x0340, 0x0F},
895 {0x0341, 0x3C},
896 {0x0344, 0x00},
897 {0x0345, 0x6C},
898 {0x0346, 0x01},
899 {0x0347, 0xB8},
900 {0x0348, 0x0F},
901 {0x0349, 0x6B},
902 {0x034A, 0x0A},
903 {0x034B, 0x27},
904 {0x0220, 0x00},
905 {0x0221, 0x11},
906 {0x0381, 0x01},
907 {0x0383, 0x01},
908 {0x0385, 0x01},
909 {0x0387, 0x01},
910 {0x0900, 0x00},
911 {0x0901, 0x11},
912 {0x0902, 0x02},
913 {0x3140, 0x02},
914 {0x3C00, 0x00},
915 {0x3C01, 0x03},
916 {0x3C02, 0xDC},
917 {0x3F0D, 0x00},
918 {0x5748, 0x07},
919 {0x5749, 0xFF},
920 {0x574A, 0x00},
921 {0x574B, 0x00},
922 {0x7B53, 0x01},
923 {0x9369, 0x5A},
924 {0x936B, 0x55},
925 {0x936D, 0x28},
926 {0x9304, 0x03},
927 {0x9305, 0x00},
928 {0x9E9A, 0x2F},
929 {0x9E9B, 0x2F},
930 {0x9E9C, 0x2F},
931 {0x9E9D, 0x00},
932 {0x9E9E, 0x00},
933 {0x9E9F, 0x00},
934 {0xA2A9, 0x60},
935 {0xA2B7, 0x00},
936 {0x0401, 0x00},
937 {0x0404, 0x00},
938 {0x0405, 0x10},
939 {0x0408, 0x00},
940 {0x0409, 0x00},
941 {0x040A, 0x00},
942 {0x040B, 0x00},
943 {0x040C, 0x0F},
944 {0x040D, 0x00},
945 {0x040E, 0x08},
946 {0x040F, 0x70},
947 {0x034C, 0x0F},
948 {0x034D, 0x00},
949 {0x034E, 0x08},
950 {0x034F, 0x70},
951 {0x0301, 0x05},
952 {0x0303, 0x02},
953 {0x0305, 0x03},
954 {0x0306, 0x00},
955 {0x0307, 0xD4},
956 {0x0309, 0x0A},
957 {0x030B, 0x01},
958 {0x030D, 0x02},
959 {0x030E, 0x01},
960 {0x030F, 0x5E},
961 {0x0310, 0x00},
962 {0x0820, 0x1A},
963 {0x0821, 0x80},
964 {0x0822, 0x00},
965 {0x0823, 0x00},
966 {0x3E20, 0x01},
967 {0x3E37, 0x01},
968 {0x3F50, 0x00},
969 {0x3F56, 0x00},
970 {0x3F57, 0xA0},
971 {REG_NULL, 0x00},
972 };
973
974 /*
975 *IMX378LQR All-pixel scan CSI-2_4lane 24Mhz
976 *AD:12bit Output:12bit 1696Mbps Master Mode 30fps
977 *Tool ver : Ver4.0
978 */
979 static const struct regval imx378_linear_12_4056x3040_regs[] = {
980 {0x0101, 0x00},
981 {0x0136, 0x18},
982 {0x0137, 0x00},
983 {0xE000, 0x00},
984 {0x4AE9, 0x18},
985 {0x4AEA, 0x08},
986 {0xF61C, 0x04},
987 {0xF61E, 0x04},
988 {0x4AE9, 0x21},
989 {0x4AEA, 0x80},
990 {0x38A8, 0x1F},
991 {0x38A9, 0xFF},
992 {0x38AA, 0x1F},
993 {0x38AB, 0xFF},
994 {0x55D4, 0x00},
995 {0x55D5, 0x00},
996 {0x55D6, 0x07},
997 {0x55D7, 0xFF},
998 {0x55E8, 0x07},
999 {0x55E9, 0xFF},
1000 {0x55EA, 0x00},
1001 {0x55EB, 0x00},
1002 {0x574C, 0x07},
1003 {0x574D, 0xFF},
1004 {0x574E, 0x00},
1005 {0x574F, 0x00},
1006 {0x5754, 0x00},
1007 {0x5755, 0x00},
1008 {0x5756, 0x07},
1009 {0x5757, 0xFF},
1010 {0x5973, 0x04},
1011 {0x5974, 0x01},
1012 {0x5D13, 0xC3},
1013 {0x5D14, 0x58},
1014 {0x5D15, 0xA3},
1015 {0x5D16, 0x1D},
1016 {0x5D17, 0x65},
1017 {0x5D18, 0x8C},
1018 {0x5D1A, 0x06},
1019 {0x5D1B, 0xA9},
1020 {0x5D1C, 0x45},
1021 {0x5D1D, 0x3A},
1022 {0x5D1E, 0xAB},
1023 {0x5D1F, 0x15},
1024 {0x5D21, 0x0E},
1025 {0x5D22, 0x52},
1026 {0x5D23, 0xAA},
1027 {0x5D24, 0x7D},
1028 {0x5D25, 0x57},
1029 {0x5D26, 0xA8},
1030 {0x5D37, 0x5A},
1031 {0x5D38, 0x5A},
1032 {0x5D77, 0x7F},
1033 {0x7B75, 0x0E},
1034 {0x7B76, 0x0B},
1035 {0x7B77, 0x08},
1036 {0x7B78, 0x0A},
1037 {0x7B79, 0x47},
1038 {0x7B7C, 0x00},
1039 {0x7B7D, 0x00},
1040 {0x8D1F, 0x00},
1041 {0x8D27, 0x00},
1042 {0x9004, 0x03},
1043 {0x9200, 0x50},
1044 {0x9201, 0x6C},
1045 {0x9202, 0x71},
1046 {0x9203, 0x00},
1047 {0x9204, 0x71},
1048 {0x9205, 0x01},
1049 {0x9371, 0x6A},
1050 {0x9373, 0x6A},
1051 {0x9375, 0x64},
1052 {0x991A, 0x00},
1053 {0x996B, 0x8C},
1054 {0x996C, 0x64},
1055 {0x996D, 0x50},
1056 {0x9A4C, 0x0D},
1057 {0x9A4D, 0x0D},
1058 {0xA001, 0x0A},
1059 {0xA003, 0x0A},
1060 {0xA005, 0x0A},
1061 {0xA006, 0x01},
1062 {0xA007, 0xC0},
1063 {0xA009, 0xC0},
1064
1065 {0x3D8A, 0x01},
1066 {0x4421, 0x08},
1067 {0x7B3B, 0x01},
1068 {0x7B4C, 0x00},
1069 {0x9905, 0x00},
1070 {0x9907, 0x00},
1071 {0x9909, 0x00},
1072 {0x990B, 0x00},
1073 {0x9944, 0x3C},
1074 {0x9947, 0x3C},
1075 {0x994A, 0x8C},
1076 {0x994B, 0x50},
1077 {0x994C, 0x1B},
1078 {0x994D, 0x8C},
1079 {0x994E, 0x50},
1080 {0x994F, 0x1B},
1081 {0x9950, 0x8C},
1082 {0x9951, 0x1B},
1083 {0x9952, 0x0A},
1084 {0x9953, 0x8C},
1085 {0x9954, 0x1B},
1086 {0x9955, 0x0A},
1087 {0x9A13, 0x04},
1088 {0x9A14, 0x04},
1089 {0x9A19, 0x00},
1090 {0x9A1C, 0x04},
1091 {0x9A1D, 0x04},
1092 {0x9A26, 0x05},
1093 {0x9A27, 0x05},
1094 {0x9A2C, 0x01},
1095 {0x9A2D, 0x03},
1096 {0x9A2F, 0x05},
1097 {0x9A30, 0x05},
1098 {0x9A41, 0x00},
1099 {0x9A46, 0x00},
1100 {0x9A47, 0x00},
1101 {0x9C17, 0x35},
1102 {0x9C1D, 0x31},
1103 {0x9C29, 0x50},
1104 {0x9C3B, 0x2F},
1105 {0x9C41, 0x6B},
1106 {0x9C47, 0x2D},
1107 {0x9C4D, 0x40},
1108 {0x9C6B, 0x00},
1109 {0x9C71, 0xC8},
1110 {0x9C73, 0x32},
1111 {0x9C75, 0x04},
1112 {0x9C7D, 0x2D},
1113 {0x9C83, 0x40},
1114 {0x9C94, 0x3F},
1115 {0x9C95, 0x3F},
1116 {0x9C96, 0x3F},
1117 {0x9C97, 0x00},
1118 {0x9C98, 0x00},
1119 {0x9C99, 0x00},
1120 {0x9C9A, 0x3F},
1121 {0x9C9B, 0x3F},
1122 {0x9C9C, 0x3F},
1123 {0x9CA0, 0x0F},
1124 {0x9CA1, 0x0F},
1125 {0x9CA2, 0x0F},
1126 {0x9CA3, 0x00},
1127 {0x9CA4, 0x00},
1128 {0x9CA5, 0x00},
1129 {0x9CA6, 0x1E},
1130 {0x9CA7, 0x1E},
1131 {0x9CA8, 0x1E},
1132 {0x9CA9, 0x00},
1133 {0x9CAA, 0x00},
1134 {0x9CAB, 0x00},
1135 {0x9CAC, 0x09},
1136 {0x9CAD, 0x09},
1137 {0x9CAE, 0x09},
1138 {0x9CBD, 0x50},
1139 {0x9CBF, 0x50},
1140 {0x9CC1, 0x50},
1141 {0x9CC3, 0x40},
1142 {0x9CC5, 0x40},
1143 {0x9CC7, 0x40},
1144 {0x9CC9, 0x0A},
1145 {0x9CCB, 0x0A},
1146 {0x9CCD, 0x0A},
1147 {0x9D17, 0x35},
1148 {0x9D1D, 0x31},
1149 {0x9D29, 0x50},
1150 {0x9D3B, 0x2F},
1151 {0x9D41, 0x6B},
1152 {0x9D47, 0x42},
1153 {0x9D4D, 0x5A},
1154 {0x9D6B, 0x00},
1155 {0x9D71, 0xC8},
1156 {0x9D73, 0x32},
1157 {0x9D75, 0x04},
1158 {0x9D7D, 0x42},
1159 {0x9D83, 0x5A},
1160 {0x9D94, 0x3F},
1161 {0x9D95, 0x3F},
1162 {0x9D96, 0x3F},
1163 {0x9D97, 0x00},
1164 {0x9D98, 0x00},
1165 {0x9D99, 0x00},
1166 {0x9D9A, 0x3F},
1167 {0x9D9B, 0x3F},
1168 {0x9D9C, 0x3F},
1169 {0x9D9D, 0x1F},
1170 {0x9D9E, 0x1F},
1171 {0x9D9F, 0x1F},
1172 {0x9DA0, 0x0F},
1173 {0x9DA1, 0x0F},
1174 {0x9DA2, 0x0F},
1175 {0x9DA3, 0x00},
1176 {0x9DA4, 0x00},
1177 {0x9DA5, 0x00},
1178 {0x9DA6, 0x1E},
1179 {0x9DA7, 0x1E},
1180 {0x9DA8, 0x1E},
1181 {0x9DA9, 0x00},
1182 {0x9DAA, 0x00},
1183 {0x9DAB, 0x00},
1184 {0x9DAC, 0x09},
1185 {0x9DAD, 0x09},
1186 {0x9DAE, 0x09},
1187 {0x9DC9, 0x0A},
1188 {0x9DCB, 0x0A},
1189 {0x9DCD, 0x0A},
1190 {0x9E17, 0x35},
1191 {0x9E1D, 0x31},
1192 {0x9E29, 0x50},
1193 {0x9E3B, 0x2F},
1194 {0x9E41, 0x6B},
1195 {0x9E47, 0x2D},
1196 {0x9E4D, 0x40},
1197 {0x9E6B, 0x00},
1198 {0x9E71, 0xC8},
1199 {0x9E73, 0x32},
1200 {0x9E75, 0x04},
1201 {0x9E94, 0x0F},
1202 {0x9E95, 0x0F},
1203 {0x9E96, 0x0F},
1204 {0x9E97, 0x00},
1205 {0x9E98, 0x00},
1206 {0x9E99, 0x00},
1207 {0x9EA0, 0x0F},
1208 {0x9EA1, 0x0F},
1209 {0x9EA2, 0x0F},
1210 {0x9EA3, 0x00},
1211 {0x9EA4, 0x00},
1212 {0x9EA5, 0x00},
1213 {0x9EA6, 0x3F},
1214 {0x9EA7, 0x3F},
1215 {0x9EA8, 0x3F},
1216 {0x9EA9, 0x00},
1217 {0x9EAA, 0x00},
1218 {0x9EAB, 0x00},
1219 {0x9EAC, 0x09},
1220 {0x9EAD, 0x09},
1221 {0x9EAE, 0x09},
1222 {0x9EC9, 0x0A},
1223 {0x9ECB, 0x0A},
1224 {0x9ECD, 0x0A},
1225 {0x9F17, 0x35},
1226 {0x9F1D, 0x31},
1227 {0x9F29, 0x50},
1228 {0x9F3B, 0x2F},
1229 {0x9F41, 0x6B},
1230 {0x9F47, 0x42},
1231 {0x9F4D, 0x5A},
1232 {0x9F6B, 0x00},
1233 {0x9F71, 0xC8},
1234 {0x9F73, 0x32},
1235 {0x9F75, 0x04},
1236 {0x9F94, 0x0F},
1237 {0x9F95, 0x0F},
1238 {0x9F96, 0x0F},
1239 {0x9F97, 0x00},
1240 {0x9F98, 0x00},
1241 {0x9F99, 0x00},
1242 {0x9F9A, 0x2F},
1243 {0x9F9B, 0x2F},
1244 {0x9F9C, 0x2F},
1245 {0x9F9D, 0x00},
1246 {0x9F9E, 0x00},
1247 {0x9F9F, 0x00},
1248 {0x9FA0, 0x0F},
1249 {0x9FA1, 0x0F},
1250 {0x9FA2, 0x0F},
1251 {0x9FA3, 0x00},
1252 {0x9FA4, 0x00},
1253 {0x9FA5, 0x00},
1254 {0x9FA6, 0x1E},
1255 {0x9FA7, 0x1E},
1256 {0x9FA8, 0x1E},
1257 {0x9FA9, 0x00},
1258 {0x9FAA, 0x00},
1259 {0x9FAB, 0x00},
1260 {0x9FAC, 0x09},
1261 {0x9FAD, 0x09},
1262 {0x9FAE, 0x09},
1263 {0x9FC9, 0x0A},
1264 {0x9FCB, 0x0A},
1265 {0x9FCD, 0x0A},
1266 {0xA14B, 0xFF},
1267 {0xA151, 0x0C},
1268 {0xA153, 0x50},
1269 {0xA155, 0x02},
1270 {0xA157, 0x00},
1271 {0xA1AD, 0xFF},
1272 {0xA1B3, 0x0C},
1273 {0xA1B5, 0x50},
1274 {0xA1B9, 0x00},
1275 {0xA24B, 0xFF},
1276 {0xA257, 0x00},
1277 {0xA2AD, 0xFF},
1278 {0xA2B9, 0x00},
1279 {0xB21F, 0x04},
1280 {0xB35C, 0x00},
1281 {0xB35E, 0x08},
1282
1283 {0x0112, 0x0C},
1284 {0x0113, 0x0C},
1285 {0x0114, 0x03},
1286 {0x0342, 0x1B},
1287 {0x0343, 0xD8},
1288 {0x0340, 0x0F},
1289 {0x0341, 0x57},
1290 {0x0344, 0x00},
1291 {0x0345, 0x00},
1292 {0x0346, 0x00},
1293 {0x0347, 0x00},
1294 {0x0348, 0x0F},
1295 {0x0349, 0xD7},
1296 {0x034A, 0x0B},
1297 {0x034B, 0xDF},
1298 {0x0220, 0x00},
1299 {0x0221, 0x11},
1300 {0x0381, 0x01},
1301 {0x0383, 0x01},
1302 {0x0385, 0x01},
1303 {0x0387, 0x01},
1304 {0x0900, 0x00},
1305 {0x0901, 0x11},
1306 {0x0902, 0x02},
1307 {0x3140, 0x02},
1308 {0x3C00, 0x00},
1309 {0x3C01, 0x03},
1310 {0x3C02, 0xA2},
1311 {0x3F0D, 0x01},
1312 {0x5748, 0x07},
1313 {0x5749, 0xFF},
1314 {0x574A, 0x00},
1315 {0x574B, 0x00},
1316 {0x7B53, 0x01},
1317 {0x9369, 0x5A},
1318 {0x936B, 0x55},
1319 {0x936D, 0x28},
1320 {0x9304, 0x03},
1321 {0x9305, 0x00},
1322 {0x9E9A, 0x2F},
1323 {0x9E9B, 0x2F},
1324 {0x9E9C, 0x2F},
1325 {0x9E9D, 0x00},
1326 {0x9E9E, 0x00},
1327 {0x9E9F, 0x00},
1328 {0xA2A9, 0x60},
1329 {0xA2B7, 0x00},
1330 {0x0401, 0x00},
1331 {0x0404, 0x00},
1332 {0x0405, 0x10},
1333 {0x0408, 0x00},
1334 {0x0409, 0x00},
1335 {0x040A, 0x00},
1336 {0x040B, 0x00},
1337 {0x040C, 0x0F},
1338 {0x040D, 0xD8},
1339 {0x040E, 0x0B},
1340 {0x040F, 0xE0},
1341 {0x034C, 0x0F},
1342 {0x034D, 0xD8},
1343 {0x034E, 0x0B},
1344 {0x034F, 0xE0},
1345 {0x0301, 0x05},
1346 {0x0303, 0x02},
1347 {0x0305, 0x02},
1348 {0x0306, 0x00},
1349 {0x0307, 0xAF},
1350 {0x0309, 0x0C},
1351 {0x030B, 0x01},
1352 {0x030D, 0x03},
1353 {0x030E, 0x00},
1354 {0x030F, 0xD4},
1355 {0x0310, 0x01},
1356 {0x0820, 0x1A},
1357 {0x0821, 0x80},
1358 {0x0822, 0x00},
1359 {0x0823, 0x00},
1360 {0x3E20, 0x01},
1361 {0x3E37, 0x01},
1362 {0x3F50, 0x00},
1363 {0x3F56, 0x00},
1364 {0x3F57, 0xB8},
1365 {REG_NULL, 0x00},
1366 };
1367
1368 static const struct regval imx378_linear_12_2028x1520_regs[] = {
1369 {0x0101, 0x00},
1370 {0x0136, 0x18},
1371 {0x0137, 0x00},
1372 {0xE000, 0x00},
1373 {0x4AE9, 0x18},
1374 {0x4AEA, 0x08},
1375 {0xF61C, 0x04},
1376 {0xF61E, 0x04},
1377 {0x4AE9, 0x21},
1378 {0x4AEA, 0x80},
1379 {0x38A8, 0x1F},
1380 {0x38A9, 0xFF},
1381 {0x38AA, 0x1F},
1382 {0x38AB, 0xFF},
1383 {0x55D4, 0x00},
1384 {0x55D5, 0x00},
1385 {0x55D6, 0x07},
1386 {0x55D7, 0xFF},
1387 {0x55E8, 0x07},
1388 {0x55E9, 0xFF},
1389 {0x55EA, 0x00},
1390 {0x55EB, 0x00},
1391 {0x574C, 0x07},
1392 {0x574D, 0xFF},
1393 {0x574E, 0x00},
1394 {0x574F, 0x00},
1395 {0x5754, 0x00},
1396 {0x5755, 0x00},
1397 {0x5756, 0x07},
1398 {0x5757, 0xFF},
1399 {0x5973, 0x04},
1400 {0x5974, 0x01},
1401 {0x5D13, 0xC3},
1402 {0x5D14, 0x58},
1403 {0x5D15, 0xA3},
1404 {0x5D16, 0x1D},
1405 {0x5D17, 0x65},
1406 {0x5D18, 0x8C},
1407 {0x5D1A, 0x06},
1408 {0x5D1B, 0xA9},
1409 {0x5D1C, 0x45},
1410 {0x5D1D, 0x3A},
1411 {0x5D1E, 0xAB},
1412 {0x5D1F, 0x15},
1413 {0x5D21, 0x0E},
1414 {0x5D22, 0x52},
1415 {0x5D23, 0xAA},
1416 {0x5D24, 0x7D},
1417 {0x5D25, 0x57},
1418 {0x5D26, 0xA8},
1419 {0x5D37, 0x5A},
1420 {0x5D38, 0x5A},
1421 {0x5D77, 0x7F},
1422 {0x7B75, 0x0E},
1423 {0x7B76, 0x0B},
1424 {0x7B77, 0x08},
1425 {0x7B78, 0x0A},
1426 {0x7B79, 0x47},
1427 {0x7B7C, 0x00},
1428 {0x7B7D, 0x00},
1429 {0x8D1F, 0x00},
1430 {0x8D27, 0x00},
1431 {0x9004, 0x03},
1432 {0x9200, 0x50},
1433 {0x9201, 0x6C},
1434 {0x9202, 0x71},
1435 {0x9203, 0x00},
1436 {0x9204, 0x71},
1437 {0x9205, 0x01},
1438 {0x9371, 0x6A},
1439 {0x9373, 0x6A},
1440 {0x9375, 0x64},
1441 {0x991A, 0x00},
1442 {0x996B, 0x8C},
1443 {0x996C, 0x64},
1444 {0x996D, 0x50},
1445 {0x9A4C, 0x0D},
1446 {0x9A4D, 0x0D},
1447 {0xA001, 0x0A},
1448 {0xA003, 0x0A},
1449 {0xA005, 0x0A},
1450 {0xA006, 0x01},
1451 {0xA007, 0xC0},
1452 {0xA009, 0xC0},
1453
1454 {0x3D8A, 0x01},
1455 {0x4421, 0x08},
1456 {0x7B3B, 0x01},
1457 {0x7B4C, 0x00},
1458 {0x9905, 0x00},
1459 {0x9907, 0x00},
1460 {0x9909, 0x00},
1461 {0x990B, 0x00},
1462 {0x9944, 0x3C},
1463 {0x9947, 0x3C},
1464 {0x994A, 0x8C},
1465 {0x994B, 0x50},
1466 {0x994C, 0x1B},
1467 {0x994D, 0x8C},
1468 {0x994E, 0x50},
1469 {0x994F, 0x1B},
1470 {0x9950, 0x8C},
1471 {0x9951, 0x1B},
1472 {0x9952, 0x0A},
1473 {0x9953, 0x8C},
1474 {0x9954, 0x1B},
1475 {0x9955, 0x0A},
1476 {0x9A13, 0x04},
1477 {0x9A14, 0x04},
1478 {0x9A19, 0x00},
1479 {0x9A1C, 0x04},
1480 {0x9A1D, 0x04},
1481 {0x9A26, 0x05},
1482 {0x9A27, 0x05},
1483 {0x9A2C, 0x01},
1484 {0x9A2D, 0x03},
1485 {0x9A2F, 0x05},
1486 {0x9A30, 0x05},
1487 {0x9A41, 0x00},
1488 {0x9A46, 0x00},
1489 {0x9A47, 0x00},
1490 {0x9C17, 0x35},
1491 {0x9C1D, 0x31},
1492 {0x9C29, 0x50},
1493 {0x9C3B, 0x2F},
1494 {0x9C41, 0x6B},
1495 {0x9C47, 0x2D},
1496 {0x9C4D, 0x40},
1497 {0x9C6B, 0x00},
1498 {0x9C71, 0xC8},
1499 {0x9C73, 0x32},
1500 {0x9C75, 0x04},
1501 {0x9C7D, 0x2D},
1502 {0x9C83, 0x40},
1503 {0x9C94, 0x3F},
1504 {0x9C95, 0x3F},
1505 {0x9C96, 0x3F},
1506 {0x9C97, 0x00},
1507 {0x9C98, 0x00},
1508 {0x9C99, 0x00},
1509 {0x9C9A, 0x3F},
1510 {0x9C9B, 0x3F},
1511 {0x9C9C, 0x3F},
1512 {0x9CA0, 0x0F},
1513 {0x9CA1, 0x0F},
1514 {0x9CA2, 0x0F},
1515 {0x9CA3, 0x00},
1516 {0x9CA4, 0x00},
1517 {0x9CA5, 0x00},
1518 {0x9CA6, 0x1E},
1519 {0x9CA7, 0x1E},
1520 {0x9CA8, 0x1E},
1521 {0x9CA9, 0x00},
1522 {0x9CAA, 0x00},
1523 {0x9CAB, 0x00},
1524 {0x9CAC, 0x09},
1525 {0x9CAD, 0x09},
1526 {0x9CAE, 0x09},
1527 {0x9CBD, 0x50},
1528 {0x9CBF, 0x50},
1529 {0x9CC1, 0x50},
1530 {0x9CC3, 0x40},
1531 {0x9CC5, 0x40},
1532 {0x9CC7, 0x40},
1533 {0x9CC9, 0x0A},
1534 {0x9CCB, 0x0A},
1535 {0x9CCD, 0x0A},
1536 {0x9D17, 0x35},
1537 {0x9D1D, 0x31},
1538 {0x9D29, 0x50},
1539 {0x9D3B, 0x2F},
1540 {0x9D41, 0x6B},
1541 {0x9D47, 0x42},
1542 {0x9D4D, 0x5A},
1543 {0x9D6B, 0x00},
1544 {0x9D71, 0xC8},
1545 {0x9D73, 0x32},
1546 {0x9D75, 0x04},
1547 {0x9D7D, 0x42},
1548 {0x9D83, 0x5A},
1549 {0x9D94, 0x3F},
1550 {0x9D95, 0x3F},
1551 {0x9D96, 0x3F},
1552 {0x9D97, 0x00},
1553 {0x9D98, 0x00},
1554 {0x9D99, 0x00},
1555 {0x9D9A, 0x3F},
1556 {0x9D9B, 0x3F},
1557 {0x9D9C, 0x3F},
1558 {0x9D9D, 0x1F},
1559 {0x9D9E, 0x1F},
1560 {0x9D9F, 0x1F},
1561 {0x9DA0, 0x0F},
1562 {0x9DA1, 0x0F},
1563 {0x9DA2, 0x0F},
1564 {0x9DA3, 0x00},
1565 {0x9DA4, 0x00},
1566 {0x9DA5, 0x00},
1567 {0x9DA6, 0x1E},
1568 {0x9DA7, 0x1E},
1569 {0x9DA8, 0x1E},
1570 {0x9DA9, 0x00},
1571 {0x9DAA, 0x00},
1572 {0x9DAB, 0x00},
1573 {0x9DAC, 0x09},
1574 {0x9DAD, 0x09},
1575 {0x9DAE, 0x09},
1576 {0x9DC9, 0x0A},
1577 {0x9DCB, 0x0A},
1578 {0x9DCD, 0x0A},
1579 {0x9E17, 0x35},
1580 {0x9E1D, 0x31},
1581 {0x9E29, 0x50},
1582 {0x9E3B, 0x2F},
1583 {0x9E41, 0x6B},
1584 {0x9E47, 0x2D},
1585 {0x9E4D, 0x40},
1586 {0x9E6B, 0x00},
1587 {0x9E71, 0xC8},
1588 {0x9E73, 0x32},
1589 {0x9E75, 0x04},
1590 {0x9E94, 0x0F},
1591 {0x9E95, 0x0F},
1592 {0x9E96, 0x0F},
1593 {0x9E97, 0x00},
1594 {0x9E98, 0x00},
1595 {0x9E99, 0x00},
1596 {0x9EA0, 0x0F},
1597 {0x9EA1, 0x0F},
1598 {0x9EA2, 0x0F},
1599 {0x9EA3, 0x00},
1600 {0x9EA4, 0x00},
1601 {0x9EA5, 0x00},
1602 {0x9EA6, 0x3F},
1603 {0x9EA7, 0x3F},
1604 {0x9EA8, 0x3F},
1605 {0x9EA9, 0x00},
1606 {0x9EAA, 0x00},
1607 {0x9EAB, 0x00},
1608 {0x9EAC, 0x09},
1609 {0x9EAD, 0x09},
1610 {0x9EAE, 0x09},
1611 {0x9EC9, 0x0A},
1612 {0x9ECB, 0x0A},
1613 {0x9ECD, 0x0A},
1614 {0x9F17, 0x35},
1615 {0x9F1D, 0x31},
1616 {0x9F29, 0x50},
1617 {0x9F3B, 0x2F},
1618 {0x9F41, 0x6B},
1619 {0x9F47, 0x42},
1620 {0x9F4D, 0x5A},
1621 {0x9F6B, 0x00},
1622 {0x9F71, 0xC8},
1623 {0x9F73, 0x32},
1624 {0x9F75, 0x04},
1625 {0x9F94, 0x0F},
1626 {0x9F95, 0x0F},
1627 {0x9F96, 0x0F},
1628 {0x9F97, 0x00},
1629 {0x9F98, 0x00},
1630 {0x9F99, 0x00},
1631 {0x9F9A, 0x2F},
1632 {0x9F9B, 0x2F},
1633 {0x9F9C, 0x2F},
1634 {0x9F9D, 0x00},
1635 {0x9F9E, 0x00},
1636 {0x9F9F, 0x00},
1637 {0x9FA0, 0x0F},
1638 {0x9FA1, 0x0F},
1639 {0x9FA2, 0x0F},
1640 {0x9FA3, 0x00},
1641 {0x9FA4, 0x00},
1642 {0x9FA5, 0x00},
1643 {0x9FA6, 0x1E},
1644 {0x9FA7, 0x1E},
1645 {0x9FA8, 0x1E},
1646 {0x9FA9, 0x00},
1647 {0x9FAA, 0x00},
1648 {0x9FAB, 0x00},
1649 {0x9FAC, 0x09},
1650 {0x9FAD, 0x09},
1651 {0x9FAE, 0x09},
1652 {0x9FC9, 0x0A},
1653 {0x9FCB, 0x0A},
1654 {0x9FCD, 0x0A},
1655 {0xA14B, 0xFF},
1656 {0xA151, 0x0C},
1657 {0xA153, 0x50},
1658 {0xA155, 0x02},
1659 {0xA157, 0x00},
1660 {0xA1AD, 0xFF},
1661 {0xA1B3, 0x0C},
1662 {0xA1B5, 0x50},
1663 {0xA1B9, 0x00},
1664 {0xA24B, 0xFF},
1665 {0xA257, 0x00},
1666 {0xA2AD, 0xFF},
1667 {0xA2B9, 0x00},
1668 {0xB21F, 0x04},
1669 {0xB35C, 0x00},
1670 {0xB35E, 0x08},
1671
1672 {0x0112, 0x0C},
1673 {0x0113, 0x0C},
1674 {0x0114, 0x03},
1675 {0x0342, 0x1B},
1676 {0x0343, 0xD8},
1677 {0x0340, 0x0F},
1678 {0x0341, 0x57},
1679 {0x0344, 0x00},
1680 {0x0345, 0x00},
1681 {0x0346, 0x00},
1682 {0x0347, 0x00},
1683 {0x0348, 0x0F},
1684 {0x0349, 0xD7},
1685 {0x034A, 0x0B},
1686 {0x034B, 0xDF},
1687 {0x0220, 0x00},
1688 {0x0221, 0x11},
1689 {0x0381, 0x01},
1690 {0x0383, 0x01},
1691 {0x0385, 0x01},
1692 {0x0387, 0x01},
1693 {0x0900, 0x01},
1694 {0x0901, 0x22},
1695 {0x0902, 0x02},
1696 {0x3140, 0x02},
1697 {0x3C00, 0x00},
1698 {0x3C01, 0x01},
1699 {0x3C02, 0x9C},
1700 {0x3F0D, 0x00},
1701 {0x5748, 0x00},
1702 {0x5749, 0x00},
1703 {0x574A, 0x00},
1704 {0x574B, 0xA4},
1705 {0x7B53, 0x00},
1706 {0x9369, 0x73},
1707 {0x936B, 0x64},
1708 {0x936D, 0x5F},
1709 {0x9304, 0x03},
1710 {0x9305, 0x80},
1711 {0x9E9A, 0x2F},
1712 {0x9E9B, 0x2F},
1713 {0x9E9C, 0x2F},
1714 {0x9E9D, 0x00},
1715 {0x9E9E, 0x00},
1716 {0x9E9F, 0x00},
1717 {0xA2A9, 0x27},
1718 {0xA2B7, 0x03},
1719 {0x0401, 0x00},
1720 {0x0404, 0x00},
1721 {0x0405, 0x10},
1722 {0x0408, 0x00},
1723 {0x0409, 0x00},
1724 {0x040A, 0x00},
1725 {0x040B, 0x00},
1726 {0x040C, 0x07},
1727 {0x040D, 0xEC},
1728 {0x040E, 0x05},
1729 {0x040F, 0xF0},
1730 {0x034C, 0x07},
1731 {0x034D, 0xEC},
1732 {0x034E, 0x05},
1733 {0x034F, 0xF0},
1734 {0x0301, 0x05},
1735 {0x0303, 0x02},
1736 {0x0305, 0x02},
1737 {0x0306, 0x00},
1738 {0x0307, 0xAF},
1739 {0x0309, 0x0C},
1740 {0x030B, 0x01},
1741 {0x030D, 0x03},
1742 {0x030E, 0x00},
1743 {0x030F, 0xD4},
1744 {0x0310, 0x01},
1745 {0x0820, 0x1A},
1746 {0x0821, 0x80},
1747 {0x0822, 0x00},
1748 {0x0823, 0x00},
1749 {0x3E20, 0x01},
1750 {0x3E37, 0x01},
1751 {0x3F50, 0x00},
1752 {0x3F56, 0x00},
1753 {0x3F57, 0xCC},
1754 {REG_NULL, 0x00},
1755 };
1756
1757 static const struct imx378_mode supported_modes[] = {
1758 {
1759 .width = 3840,
1760 .height = 2160,
1761 .max_fps = {
1762 .numerator = 10000,
1763 .denominator = 300000,
1764 },
1765 .exp_def = 0x0600,
1766 .hts_def = 0x16A8,
1767 .vts_def = 0x0F3C,
1768 .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1769 .reg_list = imx378_linear_10_3840x2160_regs,
1770 .hdr_mode = NO_HDR,
1771 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1772 }, {
1773 .width = 4056,
1774 .height = 3040,
1775 .max_fps = {
1776 .numerator = 10000,
1777 .denominator = 300000,
1778 },
1779 .exp_def = 0x0600,
1780 .hts_def = 0x16A8,
1781 .vts_def = 0x0F3C,
1782 .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1783 .reg_list = imx378_linear_10_4056x3040_regs,
1784 .hdr_mode = NO_HDR,
1785 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1786 }, {
1787 .width = 2028,
1788 .height = 1520,
1789 .max_fps = {
1790 .numerator = 10000,
1791 .denominator = 300000,
1792 },
1793 .exp_def = 0x0C80,
1794 .hts_def = 0x1BD8,
1795 .vts_def = 0x0F57,
1796 .bus_fmt = MEDIA_BUS_FMT_SRGGB12_1X12,
1797 .reg_list = imx378_linear_12_2028x1520_regs,
1798 .hdr_mode = NO_HDR,
1799 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1800 }, {
1801 .width = 4056,
1802 .height = 3040,
1803 .max_fps = {
1804 .numerator = 10000,
1805 .denominator = 300000,
1806 },
1807 .exp_def = 0x0600,
1808 .hts_def = 0x1BD8,
1809 .vts_def = 0x0F57,
1810 .bus_fmt = MEDIA_BUS_FMT_SRGGB12_1X12,
1811 .reg_list = imx378_linear_12_4056x3040_regs,
1812 .hdr_mode = NO_HDR,
1813 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1814 },
1815 };
1816
1817 static const s64 link_freq_menu_items[] = {
1818 IMX378_LINK_FREQ_848,
1819 };
1820
1821 static const char * const imx378_test_pattern_menu[] = {
1822 "Disabled",
1823 "Vertical Color Bar Type 1",
1824 "Vertical Color Bar Type 2",
1825 "Vertical Color Bar Type 3",
1826 "Vertical Color Bar Type 4"
1827 };
1828
1829 /* Write registers up to 4 at a time */
imx378_write_reg(struct i2c_client * client,u16 reg,int len,u32 val)1830 static int imx378_write_reg(struct i2c_client *client, u16 reg,
1831 int len, u32 val)
1832 {
1833 u32 buf_i, val_i;
1834 u8 buf[6];
1835 u8 *val_p;
1836 __be32 val_be;
1837
1838 if (len > 4)
1839 return -EINVAL;
1840
1841 buf[0] = reg >> 8;
1842 buf[1] = reg & 0xff;
1843
1844 val_be = cpu_to_be32(val);
1845 val_p = (u8 *)&val_be;
1846 buf_i = 2;
1847 val_i = 4 - len;
1848
1849 while (val_i < 4)
1850 buf[buf_i++] = val_p[val_i++];
1851
1852 if (i2c_master_send(client, buf, len + 2) != len + 2)
1853 return -EIO;
1854
1855 return 0;
1856 }
1857
imx378_write_array(struct i2c_client * client,const struct regval * regs)1858 static int imx378_write_array(struct i2c_client *client,
1859 const struct regval *regs)
1860 {
1861 u32 i;
1862 int ret = 0;
1863
1864 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
1865 if (unlikely(regs[i].addr == REG_DELAY))
1866 usleep_range(regs[i].val, regs[i].val * 2);
1867 else
1868 ret = imx378_write_reg(client, regs[i].addr,
1869 IMX378_REG_VALUE_08BIT,
1870 regs[i].val);
1871
1872 return ret;
1873 }
1874
1875 /* Read registers up to 4 at a time */
imx378_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)1876 static int imx378_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
1877 u32 *val)
1878 {
1879 struct i2c_msg msgs[2];
1880 u8 *data_be_p;
1881 __be32 data_be = 0;
1882 __be16 reg_addr_be = cpu_to_be16(reg);
1883 int ret, i;
1884
1885 if (len > 4 || !len)
1886 return -EINVAL;
1887
1888 data_be_p = (u8 *)&data_be;
1889 /* Write register address */
1890 msgs[0].addr = client->addr;
1891 msgs[0].flags = 0;
1892 msgs[0].len = 2;
1893 msgs[0].buf = (u8 *)®_addr_be;
1894
1895 /* Read data from register */
1896 msgs[1].addr = client->addr;
1897 msgs[1].flags = I2C_M_RD;
1898 msgs[1].len = len;
1899 msgs[1].buf = &data_be_p[4 - len];
1900
1901 for (i = 0; i < 3; i++) {
1902 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1903 if (ret == ARRAY_SIZE(msgs))
1904 break;
1905 }
1906 if (ret != ARRAY_SIZE(msgs) && i == 3)
1907 return -EIO;
1908
1909 *val = be32_to_cpu(data_be);
1910
1911 return 0;
1912 }
1913
imx378_get_reso_dist(const struct imx378_mode * mode,struct v4l2_mbus_framefmt * framefmt)1914 static int imx378_get_reso_dist(const struct imx378_mode *mode,
1915 struct v4l2_mbus_framefmt *framefmt)
1916 {
1917 return abs(mode->width - framefmt->width) +
1918 abs(mode->height - framefmt->height);
1919 }
1920
1921 static const struct imx378_mode *
imx378_find_best_fit(struct imx378 * imx378,struct v4l2_subdev_format * fmt)1922 imx378_find_best_fit(struct imx378 *imx378, struct v4l2_subdev_format *fmt)
1923 {
1924 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
1925 int dist;
1926 int cur_best_fit = 0;
1927 int cur_best_fit_dist = -1;
1928 unsigned int i;
1929
1930 for (i = 0; i < imx378->cfg_num; i++) {
1931 dist = imx378_get_reso_dist(&supported_modes[i], framefmt);
1932 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
1933 cur_best_fit_dist = dist;
1934 cur_best_fit = i;
1935 }
1936 }
1937
1938 return &supported_modes[cur_best_fit];
1939 }
1940
imx378_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1941 static int imx378_set_fmt(struct v4l2_subdev *sd,
1942 struct v4l2_subdev_pad_config *cfg,
1943 struct v4l2_subdev_format *fmt)
1944 {
1945 struct imx378 *imx378 = to_imx378(sd);
1946 const struct imx378_mode *mode;
1947 s64 h_blank, vblank_def;
1948
1949 mutex_lock(&imx378->mutex);
1950
1951 mode = imx378_find_best_fit(imx378, fmt);
1952 fmt->format.code = mode->bus_fmt;
1953 fmt->format.width = mode->width;
1954 fmt->format.height = mode->height;
1955 fmt->format.field = V4L2_FIELD_NONE;
1956 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1957 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1958 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
1959 #else
1960 mutex_unlock(&imx378->mutex);
1961 return -ENOTTY;
1962 #endif
1963 } else {
1964 imx378->cur_mode = mode;
1965 h_blank = mode->hts_def - mode->width;
1966 __v4l2_ctrl_modify_range(imx378->hblank, h_blank,
1967 h_blank, 1, h_blank);
1968 vblank_def = mode->vts_def - mode->height;
1969 __v4l2_ctrl_modify_range(imx378->vblank, vblank_def,
1970 IMX378_VTS_MAX - mode->height,
1971 1, vblank_def);
1972
1973 if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
1974 imx378->cur_link_freq = 0;
1975 imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_10BIT;
1976 } else if (imx378->cur_mode->bus_fmt ==
1977 MEDIA_BUS_FMT_SRGGB12_1X12) {
1978 imx378->cur_link_freq = 0;
1979 imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_12BIT;
1980 }
1981
1982 __v4l2_ctrl_s_ctrl_int64(imx378->pixel_rate,
1983 imx378->cur_pixel_rate);
1984 __v4l2_ctrl_s_ctrl(imx378->link_freq,
1985 imx378->cur_link_freq);
1986 }
1987
1988 mutex_unlock(&imx378->mutex);
1989
1990 return 0;
1991 }
1992
imx378_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)1993 static int imx378_get_fmt(struct v4l2_subdev *sd,
1994 struct v4l2_subdev_pad_config *cfg,
1995 struct v4l2_subdev_format *fmt)
1996 {
1997 struct imx378 *imx378 = to_imx378(sd);
1998 const struct imx378_mode *mode = imx378->cur_mode;
1999
2000 mutex_lock(&imx378->mutex);
2001 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
2002 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2003 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
2004 #else
2005 mutex_unlock(&imx378->mutex);
2006 return -ENOTTY;
2007 #endif
2008 } else {
2009 fmt->format.width = mode->width;
2010 fmt->format.height = mode->height;
2011 if (imx378->flip & IMX378_MIRROR_BIT_MASK) {
2012 fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
2013 if (imx378->flip & IMX378_FLIP_BIT_MASK)
2014 fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
2015 } else if (imx378->flip & IMX378_FLIP_BIT_MASK) {
2016 fmt->format.code = MEDIA_BUS_FMT_SGBRG10_1X10;
2017 } else {
2018 fmt->format.code = mode->bus_fmt;
2019 }
2020 fmt->format.field = V4L2_FIELD_NONE;
2021 /* format info: width/height/data type/virctual channel */
2022 if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
2023 fmt->reserved[0] = mode->vc[fmt->pad];
2024 else
2025 fmt->reserved[0] = mode->vc[PAD0];
2026 }
2027 mutex_unlock(&imx378->mutex);
2028
2029 return 0;
2030 }
2031
imx378_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)2032 static int imx378_enum_mbus_code(struct v4l2_subdev *sd,
2033 struct v4l2_subdev_pad_config *cfg,
2034 struct v4l2_subdev_mbus_code_enum *code)
2035 {
2036 struct imx378 *imx378 = to_imx378(sd);
2037
2038 if (code->index != 0)
2039 return -EINVAL;
2040 code->code = imx378->cur_mode->bus_fmt;
2041
2042 return 0;
2043 }
2044
imx378_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)2045 static int imx378_enum_frame_sizes(struct v4l2_subdev *sd,
2046 struct v4l2_subdev_pad_config *cfg,
2047 struct v4l2_subdev_frame_size_enum *fse)
2048 {
2049 struct imx378 *imx378 = to_imx378(sd);
2050
2051 if (fse->index >= imx378->cfg_num)
2052 return -EINVAL;
2053
2054 if (fse->code != supported_modes[0].bus_fmt)
2055 return -EINVAL;
2056
2057 fse->min_width = supported_modes[fse->index].width;
2058 fse->max_width = supported_modes[fse->index].width;
2059 fse->max_height = supported_modes[fse->index].height;
2060 fse->min_height = supported_modes[fse->index].height;
2061
2062 return 0;
2063 }
2064
imx378_enable_test_pattern(struct imx378 * imx378,u32 pattern)2065 static int imx378_enable_test_pattern(struct imx378 *imx378, u32 pattern)
2066 {
2067 u32 val;
2068
2069 if (pattern)
2070 val = (pattern - 1) | IMX378_TEST_PATTERN_ENABLE;
2071 else
2072 val = IMX378_TEST_PATTERN_DISABLE;
2073
2074 return imx378_write_reg(imx378->client,
2075 IMX378_REG_TEST_PATTERN,
2076 IMX378_REG_VALUE_08BIT,
2077 val);
2078 }
2079
imx378_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)2080 static int imx378_g_frame_interval(struct v4l2_subdev *sd,
2081 struct v4l2_subdev_frame_interval *fi)
2082 {
2083 struct imx378 *imx378 = to_imx378(sd);
2084 const struct imx378_mode *mode = imx378->cur_mode;
2085
2086 fi->interval = mode->max_fps;
2087
2088 return 0;
2089 }
2090
imx378_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)2091 static int imx378_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
2092 struct v4l2_mbus_config *config)
2093 {
2094 struct imx378 *imx378 = to_imx378(sd);
2095 const struct imx378_mode *mode = imx378->cur_mode;
2096 u32 val = 0;
2097
2098 if (mode->hdr_mode == NO_HDR)
2099 val = 1 << (IMX378_LANES - 1) |
2100 V4L2_MBUS_CSI2_CHANNEL_0 |
2101 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
2102
2103 if (mode->hdr_mode == HDR_X2)
2104 val = 1 << (IMX378_LANES - 1) |
2105 V4L2_MBUS_CSI2_CHANNEL_0 |
2106 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
2107 V4L2_MBUS_CSI2_CHANNEL_1;
2108
2109 config->type = V4L2_MBUS_CSI2_DPHY;
2110 config->flags = val;
2111
2112 return 0;
2113 }
2114
imx378_get_module_inf(struct imx378 * imx378,struct rkmodule_inf * inf)2115 static void imx378_get_module_inf(struct imx378 *imx378,
2116 struct rkmodule_inf *inf)
2117 {
2118 memset(inf, 0, sizeof(*inf));
2119 strlcpy(inf->base.sensor, IMX378_NAME, sizeof(inf->base.sensor));
2120 strlcpy(inf->base.module, imx378->module_name,
2121 sizeof(inf->base.module));
2122 strlcpy(inf->base.lens, imx378->len_name, sizeof(inf->base.lens));
2123 }
2124
imx378_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)2125 static long imx378_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
2126 {
2127 struct imx378 *imx378 = to_imx378(sd);
2128 struct rkmodule_hdr_cfg *hdr;
2129 long ret = 0;
2130 u32 i, h, w;
2131 u32 stream = 0;
2132
2133 switch (cmd) {
2134 case PREISP_CMD_SET_HDRAE_EXP:
2135 break;
2136 case RKMODULE_GET_MODULE_INFO:
2137 imx378_get_module_inf(imx378, (struct rkmodule_inf *)arg);
2138 break;
2139 case RKMODULE_GET_HDR_CFG:
2140 hdr = (struct rkmodule_hdr_cfg *)arg;
2141 hdr->esp.mode = HDR_NORMAL_VC;
2142 hdr->hdr_mode = imx378->cur_mode->hdr_mode;
2143 break;
2144 case RKMODULE_SET_HDR_CFG:
2145 hdr = (struct rkmodule_hdr_cfg *)arg;
2146 w = imx378->cur_mode->width;
2147 h = imx378->cur_mode->height;
2148 for (i = 0; i < imx378->cfg_num; i++) {
2149 if (w == supported_modes[i].width &&
2150 h == supported_modes[i].height &&
2151 supported_modes[i].hdr_mode == hdr->hdr_mode) {
2152 imx378->cur_mode = &supported_modes[i];
2153 break;
2154 }
2155 }
2156 if (i == imx378->cfg_num) {
2157 dev_err(&imx378->client->dev,
2158 "not find hdr mode:%d %dx%d config\n",
2159 hdr->hdr_mode, w, h);
2160 ret = -EINVAL;
2161 } else {
2162 w = imx378->cur_mode->hts_def -
2163 imx378->cur_mode->width;
2164 h = imx378->cur_mode->vts_def -
2165 imx378->cur_mode->height;
2166 __v4l2_ctrl_modify_range(imx378->hblank, w, w, 1, w);
2167 __v4l2_ctrl_modify_range(imx378->vblank, h,
2168 IMX378_VTS_MAX -
2169 imx378->cur_mode->height,
2170 1, h);
2171
2172 if (imx378->cur_mode->bus_fmt ==
2173 MEDIA_BUS_FMT_SRGGB10_1X10) {
2174 imx378->cur_link_freq = 0;
2175 imx378->cur_pixel_rate =
2176 PIXEL_RATE_WITH_848M_10BIT;
2177 } else if (imx378->cur_mode->bus_fmt ==
2178 MEDIA_BUS_FMT_SRGGB12_1X12) {
2179 imx378->cur_link_freq = 0;
2180 imx378->cur_pixel_rate =
2181 PIXEL_RATE_WITH_848M_12BIT;
2182 }
2183
2184 __v4l2_ctrl_s_ctrl_int64(imx378->pixel_rate,
2185 imx378->cur_pixel_rate);
2186 __v4l2_ctrl_s_ctrl(imx378->link_freq,
2187 imx378->cur_link_freq);
2188 }
2189 break;
2190 case RKMODULE_SET_QUICK_STREAM:
2191
2192 stream = *((u32 *)arg);
2193
2194 if (stream)
2195 ret = imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2196 IMX378_REG_VALUE_08BIT, IMX378_MODE_STREAMING);
2197 else
2198 ret = imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2199 IMX378_REG_VALUE_08BIT, IMX378_MODE_SW_STANDBY);
2200 break;
2201 default:
2202 ret = -ENOIOCTLCMD;
2203 break;
2204 }
2205
2206 return ret;
2207 }
2208
2209 #ifdef CONFIG_COMPAT
imx378_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)2210 static long imx378_compat_ioctl32(struct v4l2_subdev *sd,
2211 unsigned int cmd, unsigned long arg)
2212 {
2213 void __user *up = compat_ptr(arg);
2214 struct rkmodule_inf *inf;
2215 struct rkmodule_awb_cfg *cfg;
2216 struct rkmodule_hdr_cfg *hdr;
2217 struct preisp_hdrae_exp_s *hdrae;
2218 long ret;
2219 u32 stream = 0;
2220
2221 switch (cmd) {
2222 case RKMODULE_GET_MODULE_INFO:
2223 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
2224 if (!inf) {
2225 ret = -ENOMEM;
2226 return ret;
2227 }
2228
2229 ret = imx378_ioctl(sd, cmd, inf);
2230 if (!ret)
2231 ret = copy_to_user(up, inf, sizeof(*inf));
2232 kfree(inf);
2233 break;
2234 case RKMODULE_AWB_CFG:
2235 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
2236 if (!cfg) {
2237 ret = -ENOMEM;
2238 return ret;
2239 }
2240
2241 ret = copy_from_user(cfg, up, sizeof(*cfg));
2242 if (!ret)
2243 ret = imx378_ioctl(sd, cmd, cfg);
2244 kfree(cfg);
2245 break;
2246 case RKMODULE_GET_HDR_CFG:
2247 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2248 if (!hdr) {
2249 ret = -ENOMEM;
2250 return ret;
2251 }
2252
2253 ret = imx378_ioctl(sd, cmd, hdr);
2254 if (!ret)
2255 ret = copy_to_user(up, hdr, sizeof(*hdr));
2256 kfree(hdr);
2257 break;
2258 case RKMODULE_SET_HDR_CFG:
2259 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
2260 if (!hdr) {
2261 ret = -ENOMEM;
2262 return ret;
2263 }
2264
2265 ret = copy_from_user(hdr, up, sizeof(*hdr));
2266 if (!ret)
2267 ret = imx378_ioctl(sd, cmd, hdr);
2268 kfree(hdr);
2269 break;
2270 case PREISP_CMD_SET_HDRAE_EXP:
2271 hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
2272 if (!hdrae) {
2273 ret = -ENOMEM;
2274 return ret;
2275 }
2276
2277 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
2278 if (!ret)
2279 ret = imx378_ioctl(sd, cmd, hdrae);
2280 kfree(hdrae);
2281 break;
2282 case RKMODULE_SET_QUICK_STREAM:
2283 ret = copy_from_user(&stream, up, sizeof(u32));
2284 if (!ret)
2285 ret = imx378_ioctl(sd, cmd, &stream);
2286 break;
2287 default:
2288 ret = -ENOIOCTLCMD;
2289 break;
2290 }
2291
2292 return ret;
2293 }
2294 #endif
2295
imx378_set_flip(struct imx378 * imx378)2296 static int imx378_set_flip(struct imx378 *imx378)
2297 {
2298 int ret = 0;
2299 u32 val = 0;
2300
2301 ret = imx378_read_reg(imx378->client, IMX378_FLIP_MIRROR_REG,
2302 IMX378_REG_VALUE_08BIT, &val);
2303 if (imx378->flip & IMX378_MIRROR_BIT_MASK)
2304 val |= IMX378_MIRROR_BIT_MASK;
2305 else
2306 val &= ~IMX378_MIRROR_BIT_MASK;
2307 if (imx378->flip & IMX378_FLIP_BIT_MASK)
2308 val |= IMX378_FLIP_BIT_MASK;
2309 else
2310 val &= ~IMX378_FLIP_BIT_MASK;
2311 ret |= imx378_write_reg(imx378->client, IMX378_FLIP_MIRROR_REG,
2312 IMX378_REG_VALUE_08BIT, val);
2313
2314 return ret;
2315 }
2316
__imx378_start_stream(struct imx378 * imx378)2317 static int __imx378_start_stream(struct imx378 *imx378)
2318 {
2319 int ret;
2320
2321 ret = imx378_write_array(imx378->client, imx378->cur_mode->reg_list);
2322 if (ret)
2323 return ret;
2324 imx378->cur_vts = imx378->cur_mode->vts_def;
2325 /* In case these controls are set before streaming */
2326 ret = __v4l2_ctrl_handler_setup(&imx378->ctrl_handler);
2327 if (ret)
2328 return ret;
2329 if (imx378->has_init_exp && imx378->cur_mode->hdr_mode != NO_HDR) {
2330 ret = imx378_ioctl(&imx378->subdev, PREISP_CMD_SET_HDRAE_EXP,
2331 &imx378->init_hdrae_exp);
2332 if (ret) {
2333 dev_err(&imx378->client->dev,
2334 "init exp fail in hdr mode\n");
2335 return ret;
2336 }
2337 }
2338
2339 imx378_set_flip(imx378);
2340
2341 return imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2342 IMX378_REG_VALUE_08BIT, IMX378_MODE_STREAMING);
2343 }
2344
__imx378_stop_stream(struct imx378 * imx378)2345 static int __imx378_stop_stream(struct imx378 *imx378)
2346 {
2347 return imx378_write_reg(imx378->client, IMX378_REG_CTRL_MODE,
2348 IMX378_REG_VALUE_08BIT, IMX378_MODE_SW_STANDBY);
2349 }
2350
imx378_s_stream(struct v4l2_subdev * sd,int on)2351 static int imx378_s_stream(struct v4l2_subdev *sd, int on)
2352 {
2353 struct imx378 *imx378 = to_imx378(sd);
2354 struct i2c_client *client = imx378->client;
2355 int ret = 0;
2356
2357 mutex_lock(&imx378->mutex);
2358 on = !!on;
2359 if (on == imx378->streaming)
2360 goto unlock_and_return;
2361
2362 if (on) {
2363 ret = pm_runtime_get_sync(&client->dev);
2364 if (ret < 0) {
2365 pm_runtime_put_noidle(&client->dev);
2366 goto unlock_and_return;
2367 }
2368
2369 ret = __imx378_start_stream(imx378);
2370 if (ret) {
2371 v4l2_err(sd, "start stream failed while write regs\n");
2372 pm_runtime_put(&client->dev);
2373 goto unlock_and_return;
2374 }
2375 } else {
2376 __imx378_stop_stream(imx378);
2377 pm_runtime_put(&client->dev);
2378 }
2379
2380 imx378->streaming = on;
2381
2382 unlock_and_return:
2383 mutex_unlock(&imx378->mutex);
2384
2385 return ret;
2386 }
2387
imx378_s_power(struct v4l2_subdev * sd,int on)2388 static int imx378_s_power(struct v4l2_subdev *sd, int on)
2389 {
2390 struct imx378 *imx378 = to_imx378(sd);
2391 struct i2c_client *client = imx378->client;
2392 int ret = 0;
2393
2394 mutex_lock(&imx378->mutex);
2395
2396 /* If the power state is not modified - no work to do. */
2397 if (imx378->power_on == !!on)
2398 goto unlock_and_return;
2399
2400 if (on) {
2401 ret = pm_runtime_get_sync(&client->dev);
2402 if (ret < 0) {
2403 pm_runtime_put_noidle(&client->dev);
2404 goto unlock_and_return;
2405 }
2406
2407 imx378->power_on = true;
2408 } else {
2409 pm_runtime_put(&client->dev);
2410 imx378->power_on = false;
2411 }
2412
2413 unlock_and_return:
2414 mutex_unlock(&imx378->mutex);
2415
2416 return ret;
2417 }
2418
2419 /* Calculate the delay in us by clock rate and clock cycles */
imx378_cal_delay(u32 cycles)2420 static inline u32 imx378_cal_delay(u32 cycles)
2421 {
2422 return DIV_ROUND_UP(cycles, IMX378_XVCLK_FREQ / 1000 / 1000);
2423 }
2424
__imx378_power_on(struct imx378 * imx378)2425 static int __imx378_power_on(struct imx378 *imx378)
2426 {
2427 int ret;
2428 u32 delay_us;
2429 struct device *dev = &imx378->client->dev;
2430
2431 ret = clk_set_rate(imx378->xvclk, IMX378_XVCLK_FREQ);
2432 if (ret < 0) {
2433 dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
2434 return ret;
2435 }
2436 if (clk_get_rate(imx378->xvclk) != IMX378_XVCLK_FREQ)
2437 dev_warn(dev, "xvclk mismatched, modes are based on 37.125MHz\n");
2438 ret = clk_prepare_enable(imx378->xvclk);
2439 if (ret < 0) {
2440 dev_err(dev, "Failed to enable xvclk\n");
2441 return ret;
2442 }
2443
2444 if (!IS_ERR(imx378->reset_gpio))
2445 gpiod_set_value_cansleep(imx378->reset_gpio, 0);
2446
2447 ret = regulator_bulk_enable(IMX378_NUM_SUPPLIES, imx378->supplies);
2448 if (ret < 0) {
2449 dev_err(dev, "Failed to enable regulators\n");
2450 goto disable_clk;
2451 }
2452
2453 if (!IS_ERR(imx378->reset_gpio))
2454 gpiod_set_value_cansleep(imx378->reset_gpio, 1);
2455
2456 usleep_range(500, 1000);
2457 if (!IS_ERR(imx378->pwdn_gpio))
2458 gpiod_set_value_cansleep(imx378->pwdn_gpio, 1);
2459
2460 /* 8192 cycles prior to first SCCB transaction */
2461 delay_us = imx378_cal_delay(8192);
2462 usleep_range(delay_us, delay_us * 2);
2463
2464 return 0;
2465
2466 disable_clk:
2467 clk_disable_unprepare(imx378->xvclk);
2468
2469 return ret;
2470 }
2471
__imx378_power_off(struct imx378 * imx378)2472 static void __imx378_power_off(struct imx378 *imx378)
2473 {
2474 if (!IS_ERR(imx378->pwdn_gpio))
2475 gpiod_set_value_cansleep(imx378->pwdn_gpio, 0);
2476 clk_disable_unprepare(imx378->xvclk);
2477 if (!IS_ERR(imx378->reset_gpio))
2478 gpiod_set_value_cansleep(imx378->reset_gpio, 0);
2479 regulator_bulk_disable(IMX378_NUM_SUPPLIES, imx378->supplies);
2480 }
2481
imx378_runtime_resume(struct device * dev)2482 static int imx378_runtime_resume(struct device *dev)
2483 {
2484 struct i2c_client *client = to_i2c_client(dev);
2485 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2486 struct imx378 *imx378 = to_imx378(sd);
2487
2488 return __imx378_power_on(imx378);
2489 }
2490
imx378_runtime_suspend(struct device * dev)2491 static int imx378_runtime_suspend(struct device *dev)
2492 {
2493 struct i2c_client *client = to_i2c_client(dev);
2494 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2495 struct imx378 *imx378 = to_imx378(sd);
2496
2497 __imx378_power_off(imx378);
2498
2499 return 0;
2500 }
2501
2502 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
imx378_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)2503 static int imx378_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2504 {
2505 struct imx378 *imx378 = to_imx378(sd);
2506 struct v4l2_mbus_framefmt *try_fmt =
2507 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2508 const struct imx378_mode *def_mode = &supported_modes[0];
2509
2510 mutex_lock(&imx378->mutex);
2511 /* Initialize try_fmt */
2512 try_fmt->width = def_mode->width;
2513 try_fmt->height = def_mode->height;
2514 try_fmt->code = def_mode->bus_fmt;
2515 try_fmt->field = V4L2_FIELD_NONE;
2516
2517 mutex_unlock(&imx378->mutex);
2518 /* No crop or compose */
2519
2520 return 0;
2521 }
2522 #endif
2523
imx378_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)2524 static int imx378_enum_frame_interval(struct v4l2_subdev *sd,
2525 struct v4l2_subdev_pad_config *cfg,
2526 struct v4l2_subdev_frame_interval_enum *fie)
2527 {
2528 struct imx378 *imx378 = to_imx378(sd);
2529
2530 if (fie->index >= imx378->cfg_num)
2531 return -EINVAL;
2532
2533 fie->code = supported_modes[fie->index].bus_fmt;
2534 fie->width = supported_modes[fie->index].width;
2535 fie->height = supported_modes[fie->index].height;
2536 fie->interval = supported_modes[fie->index].max_fps;
2537 fie->reserved[0] = supported_modes[fie->index].hdr_mode;
2538 return 0;
2539 }
2540
2541 static const struct dev_pm_ops imx378_pm_ops = {
2542 SET_RUNTIME_PM_OPS(imx378_runtime_suspend,
2543 imx378_runtime_resume, NULL)
2544 };
2545
2546 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2547 static const struct v4l2_subdev_internal_ops imx378_internal_ops = {
2548 .open = imx378_open,
2549 };
2550 #endif
2551
2552 static const struct v4l2_subdev_core_ops imx378_core_ops = {
2553 .s_power = imx378_s_power,
2554 .ioctl = imx378_ioctl,
2555 #ifdef CONFIG_COMPAT
2556 .compat_ioctl32 = imx378_compat_ioctl32,
2557 #endif
2558 };
2559
2560 static const struct v4l2_subdev_video_ops imx378_video_ops = {
2561 .s_stream = imx378_s_stream,
2562 .g_frame_interval = imx378_g_frame_interval,
2563 };
2564
2565 static const struct v4l2_subdev_pad_ops imx378_pad_ops = {
2566 .enum_mbus_code = imx378_enum_mbus_code,
2567 .enum_frame_size = imx378_enum_frame_sizes,
2568 .enum_frame_interval = imx378_enum_frame_interval,
2569 .get_fmt = imx378_get_fmt,
2570 .set_fmt = imx378_set_fmt,
2571 .get_mbus_config = imx378_g_mbus_config,
2572 };
2573
2574 static const struct v4l2_subdev_ops imx378_subdev_ops = {
2575 .core = &imx378_core_ops,
2576 .video = &imx378_video_ops,
2577 .pad = &imx378_pad_ops,
2578 };
2579
imx378_set_ctrl(struct v4l2_ctrl * ctrl)2580 static int imx378_set_ctrl(struct v4l2_ctrl *ctrl)
2581 {
2582 struct imx378 *imx378 = container_of(ctrl->handler,
2583 struct imx378, ctrl_handler);
2584 struct i2c_client *client = imx378->client;
2585 s64 max;
2586 int ret = 0;
2587 u32 again = 0;
2588 u32 dgain = 0;
2589
2590 /* Propagate change of current control to all related controls */
2591 switch (ctrl->id) {
2592 case V4L2_CID_VBLANK:
2593 /* Update max exposure while meeting expected vblanking */
2594 max = imx378->cur_mode->height + ctrl->val - 4;
2595 __v4l2_ctrl_modify_range(imx378->exposure,
2596 imx378->exposure->minimum, max,
2597 imx378->exposure->step,
2598 imx378->exposure->default_value);
2599 break;
2600 }
2601
2602 if (!pm_runtime_get_if_in_use(&client->dev))
2603 return 0;
2604
2605 switch (ctrl->id) {
2606 case V4L2_CID_EXPOSURE:
2607 /* 4 least significant bits of expsoure are fractional part */
2608 ret = imx378_write_reg(imx378->client,
2609 IMX378_REG_EXPOSURE_H,
2610 IMX378_REG_VALUE_08BIT,
2611 IMX378_FETCH_EXP_H(ctrl->val));
2612 ret |= imx378_write_reg(imx378->client,
2613 IMX378_REG_EXPOSURE_L,
2614 IMX378_REG_VALUE_08BIT,
2615 IMX378_FETCH_EXP_L(ctrl->val));
2616 break;
2617 case V4L2_CID_ANALOGUE_GAIN:
2618 again = ctrl->val > 978 ? 978 : ctrl->val;
2619 dgain = ctrl->val > 978 ? ctrl->val - 978 : 256;
2620 ret = imx378_write_reg(imx378->client, IMX378_REG_GAIN_H,
2621 IMX378_REG_VALUE_08BIT,
2622 IMX378_FETCH_AGAIN_H(again));
2623 ret |= imx378_write_reg(imx378->client, IMX378_REG_GAIN_L,
2624 IMX378_REG_VALUE_08BIT,
2625 IMX378_FETCH_AGAIN_L(again));
2626 ret |= imx378_write_reg(imx378->client, IMX378_REG_DGAIN,
2627 IMX378_REG_VALUE_08BIT,
2628 IMX378_DGAIN_MODE);
2629 if (IMX378_DGAIN_MODE && dgain > 0) {
2630 ret |= imx378_write_reg(imx378->client,
2631 IMX378_REG_DGAINGR_H,
2632 IMX378_REG_VALUE_08BIT,
2633 IMX378_FETCH_DGAIN_H(dgain));
2634 ret |= imx378_write_reg(imx378->client,
2635 IMX378_REG_DGAINGR_L,
2636 IMX378_REG_VALUE_08BIT,
2637 IMX378_FETCH_DGAIN_L(dgain));
2638 } else if (dgain > 0) {
2639 ret |= imx378_write_reg(imx378->client,
2640 IMX378_REG_DGAINR_H,
2641 IMX378_REG_VALUE_08BIT,
2642 IMX378_FETCH_DGAIN_H(dgain));
2643 ret |= imx378_write_reg(imx378->client,
2644 IMX378_REG_DGAINR_L,
2645 IMX378_REG_VALUE_08BIT,
2646 IMX378_FETCH_DGAIN_L(dgain));
2647 ret |= imx378_write_reg(imx378->client,
2648 IMX378_REG_DGAINB_H,
2649 IMX378_REG_VALUE_08BIT,
2650 IMX378_FETCH_DGAIN_H(dgain));
2651 ret |= imx378_write_reg(imx378->client,
2652 IMX378_REG_DGAINB_L,
2653 IMX378_REG_VALUE_08BIT,
2654 IMX378_FETCH_DGAIN_L(dgain));
2655 ret |= imx378_write_reg(imx378->client,
2656 IMX378_REG_DGAINGB_H,
2657 IMX378_REG_VALUE_08BIT,
2658 IMX378_FETCH_DGAIN_H(dgain));
2659 ret |= imx378_write_reg(imx378->client,
2660 IMX378_REG_DGAINGB_L,
2661 IMX378_REG_VALUE_08BIT,
2662 IMX378_FETCH_DGAIN_L(dgain));
2663 ret |= imx378_write_reg(imx378->client,
2664 IMX378_REG_GAIN_GLOBAL_H,
2665 IMX378_REG_VALUE_08BIT,
2666 IMX378_FETCH_DGAIN_H(dgain));
2667 ret |= imx378_write_reg(imx378->client,
2668 IMX378_REG_GAIN_GLOBAL_L,
2669 IMX378_REG_VALUE_08BIT,
2670 IMX378_FETCH_DGAIN_L(dgain));
2671 }
2672 break;
2673 case V4L2_CID_VBLANK:
2674 ret = imx378_write_reg(imx378->client,
2675 IMX378_REG_VTS_H,
2676 IMX378_REG_VALUE_08BIT,
2677 (ctrl->val + imx378->cur_mode->height)
2678 >> 8);
2679 ret |= imx378_write_reg(imx378->client,
2680 IMX378_REG_VTS_L,
2681 IMX378_REG_VALUE_08BIT,
2682 (ctrl->val + imx378->cur_mode->height)
2683 & 0xff);
2684 imx378->cur_vts = ctrl->val + imx378->cur_mode->height;
2685 break;
2686 case V4L2_CID_HFLIP:
2687 if (ctrl->val)
2688 imx378->flip |= IMX378_MIRROR_BIT_MASK;
2689 else
2690 imx378->flip &= ~IMX378_MIRROR_BIT_MASK;
2691 break;
2692 case V4L2_CID_VFLIP:
2693 if (ctrl->val)
2694 imx378->flip |= IMX378_FLIP_BIT_MASK;
2695 else
2696 imx378->flip &= ~IMX378_FLIP_BIT_MASK;
2697 break;
2698 case V4L2_CID_TEST_PATTERN:
2699 ret = imx378_enable_test_pattern(imx378, ctrl->val);
2700 break;
2701 default:
2702 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
2703 __func__, ctrl->id, ctrl->val);
2704 break;
2705 }
2706
2707 pm_runtime_put(&client->dev);
2708
2709 return ret;
2710 }
2711
2712 static const struct v4l2_ctrl_ops imx378_ctrl_ops = {
2713 .s_ctrl = imx378_set_ctrl,
2714 };
2715
imx378_initialize_controls(struct imx378 * imx378)2716 static int imx378_initialize_controls(struct imx378 *imx378)
2717 {
2718 const struct imx378_mode *mode;
2719 struct v4l2_ctrl_handler *handler;
2720 s64 exposure_max, vblank_def;
2721 u32 h_blank;
2722 int ret;
2723
2724 handler = &imx378->ctrl_handler;
2725 mode = imx378->cur_mode;
2726 ret = v4l2_ctrl_handler_init(handler, 9);
2727 if (ret)
2728 return ret;
2729 handler->lock = &imx378->mutex;
2730
2731 imx378->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
2732 V4L2_CID_LINK_FREQ,
2733 0, 0, link_freq_menu_items);
2734
2735 if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
2736 imx378->cur_link_freq = 0;
2737 imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_10BIT;
2738 } else if (imx378->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB12_1X12) {
2739 imx378->cur_link_freq = 0;
2740 imx378->cur_pixel_rate = PIXEL_RATE_WITH_848M_12BIT;
2741 }
2742
2743 imx378->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
2744 V4L2_CID_PIXEL_RATE,
2745 0, PIXEL_RATE_WITH_848M_10BIT,
2746 1, imx378->cur_pixel_rate);
2747 v4l2_ctrl_s_ctrl(imx378->link_freq,
2748 imx378->cur_link_freq);
2749
2750 h_blank = mode->hts_def - mode->width;
2751 imx378->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
2752 h_blank, h_blank, 1, h_blank);
2753 if (imx378->hblank)
2754 imx378->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2755
2756 vblank_def = mode->vts_def - mode->height;
2757 imx378->vblank = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2758 V4L2_CID_VBLANK, vblank_def,
2759 IMX378_VTS_MAX - mode->height,
2760 1, vblank_def);
2761 imx378->cur_vts = mode->vts_def;
2762 exposure_max = mode->vts_def - 4;
2763 imx378->exposure = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2764 V4L2_CID_EXPOSURE,
2765 IMX378_EXPOSURE_MIN,
2766 exposure_max,
2767 IMX378_EXPOSURE_STEP,
2768 mode->exp_def);
2769 imx378->anal_gain = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2770 V4L2_CID_ANALOGUE_GAIN,
2771 IMX378_GAIN_MIN,
2772 IMX378_GAIN_MAX,
2773 IMX378_GAIN_STEP,
2774 IMX378_GAIN_DEFAULT);
2775 imx378->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
2776 &imx378_ctrl_ops,
2777 V4L2_CID_TEST_PATTERN,
2778 ARRAY_SIZE(imx378_test_pattern_menu) - 1,
2779 0, 0, imx378_test_pattern_menu);
2780
2781 imx378->h_flip = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2782 V4L2_CID_HFLIP, 0, 1, 1, 0);
2783
2784 imx378->v_flip = v4l2_ctrl_new_std(handler, &imx378_ctrl_ops,
2785 V4L2_CID_VFLIP, 0, 1, 1, 0);
2786 imx378->flip = 0;
2787
2788 if (handler->error) {
2789 ret = handler->error;
2790 dev_err(&imx378->client->dev,
2791 "Failed to init controls( %d )\n", ret);
2792 goto err_free_handler;
2793 }
2794
2795 imx378->subdev.ctrl_handler = handler;
2796 imx378->has_init_exp = false;
2797 return 0;
2798
2799 err_free_handler:
2800 v4l2_ctrl_handler_free(handler);
2801
2802 return ret;
2803 }
2804
imx378_check_sensor_id(struct imx378 * imx378,struct i2c_client * client)2805 static int imx378_check_sensor_id(struct imx378 *imx378,
2806 struct i2c_client *client)
2807 {
2808 struct device *dev = &imx378->client->dev;
2809 u16 id = 0;
2810 u32 reg_H = 0;
2811 u32 reg_L = 0;
2812 int ret;
2813
2814 ret = imx378_read_reg(client, IMX378_REG_CHIP_ID_H,
2815 IMX378_REG_VALUE_08BIT, ®_H);
2816 ret |= imx378_read_reg(client, IMX378_REG_CHIP_ID_L,
2817 IMX378_REG_VALUE_08BIT, ®_L);
2818 id = ((reg_H << 8) & 0xff00) | (reg_L & 0xff);
2819 if (!(reg_H == (CHIP_ID >> 8) || reg_L == (CHIP_ID & 0xff))) {
2820 dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
2821 return -ENODEV;
2822 }
2823 dev_info(dev, "detected imx378 %04x sensor\n", id);
2824 return 0;
2825 }
2826
imx378_configure_regulators(struct imx378 * imx378)2827 static int imx378_configure_regulators(struct imx378 *imx378)
2828 {
2829 unsigned int i;
2830
2831 for (i = 0; i < IMX378_NUM_SUPPLIES; i++)
2832 imx378->supplies[i].supply = imx378_supply_names[i];
2833
2834 return devm_regulator_bulk_get(&imx378->client->dev,
2835 IMX378_NUM_SUPPLIES,
2836 imx378->supplies);
2837 }
2838
imx378_probe(struct i2c_client * client,const struct i2c_device_id * id)2839 static int imx378_probe(struct i2c_client *client,
2840 const struct i2c_device_id *id)
2841 {
2842 struct device *dev = &client->dev;
2843 struct device_node *node = dev->of_node;
2844 struct imx378 *imx378;
2845 struct v4l2_subdev *sd;
2846 char facing[2];
2847 int ret;
2848 u32 i, hdr_mode = 0;
2849
2850 dev_info(dev, "driver version: %02x.%02x.%02x",
2851 DRIVER_VERSION >> 16,
2852 (DRIVER_VERSION & 0xff00) >> 8,
2853 DRIVER_VERSION & 0x00ff);
2854
2855 imx378 = devm_kzalloc(dev, sizeof(*imx378), GFP_KERNEL);
2856 if (!imx378)
2857 return -ENOMEM;
2858
2859 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
2860 &imx378->module_index);
2861 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
2862 &imx378->module_facing);
2863 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
2864 &imx378->module_name);
2865 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
2866 &imx378->len_name);
2867 if (ret) {
2868 dev_err(dev, "could not get module information!\n");
2869 return -EINVAL;
2870 }
2871
2872 ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
2873 if (ret) {
2874 hdr_mode = NO_HDR;
2875 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
2876 }
2877
2878 imx378->client = client;
2879 imx378->cfg_num = ARRAY_SIZE(supported_modes);
2880 for (i = 0; i < imx378->cfg_num; i++) {
2881 if (hdr_mode == supported_modes[i].hdr_mode) {
2882 imx378->cur_mode = &supported_modes[i];
2883 break;
2884 }
2885 }
2886
2887 if (i == imx378->cfg_num)
2888 imx378->cur_mode = &supported_modes[0];
2889
2890 imx378->xvclk = devm_clk_get(dev, "xvclk");
2891 if (IS_ERR(imx378->xvclk)) {
2892 dev_err(dev, "Failed to get xvclk\n");
2893 return -EINVAL;
2894 }
2895
2896 imx378->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2897 if (IS_ERR(imx378->reset_gpio))
2898 dev_warn(dev, "Failed to get reset-gpios\n");
2899
2900 imx378->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2901 if (IS_ERR(imx378->pwdn_gpio))
2902 dev_warn(dev, "Failed to get pwdn-gpios\n");
2903
2904 ret = imx378_configure_regulators(imx378);
2905 if (ret) {
2906 dev_err(dev, "Failed to get power regulators\n");
2907 return ret;
2908 }
2909
2910 mutex_init(&imx378->mutex);
2911
2912 sd = &imx378->subdev;
2913 v4l2_i2c_subdev_init(sd, client, &imx378_subdev_ops);
2914
2915 ret = imx378_initialize_controls(imx378);
2916 if (ret)
2917 goto err_destroy_mutex;
2918
2919 ret = __imx378_power_on(imx378);
2920 if (ret)
2921 goto err_free_handler;
2922
2923 ret = imx378_check_sensor_id(imx378, client);
2924 if (ret)
2925 goto err_power_off;
2926
2927 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
2928 sd->internal_ops = &imx378_internal_ops;
2929 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2930 #endif
2931 #if defined(CONFIG_MEDIA_CONTROLLER)
2932 imx378->pad.flags = MEDIA_PAD_FL_SOURCE;
2933 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
2934 ret = media_entity_pads_init(&sd->entity, 1, &imx378->pad);
2935 if (ret < 0)
2936 goto err_power_off;
2937 #endif
2938
2939 memset(facing, 0, sizeof(facing));
2940 if (strcmp(imx378->module_facing, "back") == 0)
2941 facing[0] = 'b';
2942 else
2943 facing[0] = 'f';
2944
2945 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
2946 imx378->module_index, facing,
2947 IMX378_NAME, dev_name(sd->dev));
2948 ret = v4l2_async_register_subdev_sensor_common(sd);
2949 if (ret) {
2950 dev_err(dev, "v4l2 async register subdev failed\n");
2951 goto err_clean_entity;
2952 }
2953
2954 pm_runtime_set_active(dev);
2955 pm_runtime_enable(dev);
2956 pm_runtime_idle(dev);
2957
2958 return 0;
2959
2960 err_clean_entity:
2961 #if defined(CONFIG_MEDIA_CONTROLLER)
2962 media_entity_cleanup(&sd->entity);
2963 #endif
2964 err_power_off:
2965 __imx378_power_off(imx378);
2966 err_free_handler:
2967 v4l2_ctrl_handler_free(&imx378->ctrl_handler);
2968 err_destroy_mutex:
2969 mutex_destroy(&imx378->mutex);
2970
2971 return ret;
2972 }
2973
imx378_remove(struct i2c_client * client)2974 static int imx378_remove(struct i2c_client *client)
2975 {
2976 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2977 struct imx378 *imx378 = to_imx378(sd);
2978
2979 v4l2_async_unregister_subdev(sd);
2980 #if defined(CONFIG_MEDIA_CONTROLLER)
2981 media_entity_cleanup(&sd->entity);
2982 #endif
2983 v4l2_ctrl_handler_free(&imx378->ctrl_handler);
2984 mutex_destroy(&imx378->mutex);
2985
2986 pm_runtime_disable(&client->dev);
2987 if (!pm_runtime_status_suspended(&client->dev))
2988 __imx378_power_off(imx378);
2989 pm_runtime_set_suspended(&client->dev);
2990
2991 return 0;
2992 }
2993
2994 #if IS_ENABLED(CONFIG_OF)
2995 static const struct of_device_id imx378_of_match[] = {
2996 { .compatible = "sony,imx378" },
2997 {},
2998 };
2999 MODULE_DEVICE_TABLE(of, imx378_of_match);
3000 #endif
3001
3002 static const struct i2c_device_id imx378_match_id[] = {
3003 { "sony,imx378", 0 },
3004 { },
3005 };
3006
3007 static struct i2c_driver imx378_i2c_driver = {
3008 .driver = {
3009 .name = IMX378_NAME,
3010 .pm = &imx378_pm_ops,
3011 .of_match_table = of_match_ptr(imx378_of_match),
3012 },
3013 .probe = &imx378_probe,
3014 .remove = &imx378_remove,
3015 .id_table = imx378_match_id,
3016 };
3017
sensor_mod_init(void)3018 static int __init sensor_mod_init(void)
3019 {
3020 return i2c_add_driver(&imx378_i2c_driver);
3021 }
3022
sensor_mod_exit(void)3023 static void __exit sensor_mod_exit(void)
3024 {
3025 i2c_del_driver(&imx378_i2c_driver);
3026 }
3027
3028 device_initcall_sync(sensor_mod_init);
3029 module_exit(sensor_mod_exit);
3030
3031 MODULE_DESCRIPTION("Sony imx378 sensor driver");
3032 MODULE_LICENSE("GPL v2");
3033