forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/imx464.c
....@@ -26,8 +26,11 @@
2626 #include <media/v4l2-async.h>
2727 #include <media/v4l2-ctrls.h>
2828 #include <media/v4l2-subdev.h>
29
+#include <media/v4l2-fwnode.h>
30
+#include <media/v4l2-mediabus.h>
2931 #include <linux/pinctrl/consumer.h>
3032 #include <linux/rk-preisp.h>
33
+#include <linux/of_graph.h>
3134
3235 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
3336
....@@ -42,15 +45,12 @@
4245 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
4346
4447 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
45
-#define IMX464_10BIT_LINEAR_PIXEL_RATE (MIPI_FREQ_445M * 2 / 10 * 4)
4648 #define IMX464_10BIT_HDR2_PIXEL_RATE (MIPI_FREQ_594M * 2 / 10 * 4)
47
-#define IMX464_10BIT_HDR3_PIXEL_RATE (MIPI_FREQ_594M * 2 / 10 * 4)
48
-#define IMX464_12BIT_PIXEL_RATE (MIPI_FREQ_360M * 2 / 12 * 4)
4949 #define IMX464_XVCLK_FREQ_37M 37125000
5050 #define IMX464_XVCLK_FREQ_24M 24000000
5151
52
-#define CHIP_ID 0x00
53
-#define IMX464_REG_CHIP_ID 0x0000
52
+#define CHIP_ID 0x06
53
+#define IMX464_REG_CHIP_ID 0x3057
5454
5555 #define IMX464_REG_CTRL_MODE 0x3000
5656 #define IMX464_MODE_SW_STANDBY BIT(0)
....@@ -133,8 +133,6 @@
133133 #define IMX464_REG_VALUE_16BIT 2
134134 #define IMX464_REG_VALUE_24BIT 3
135135
136
-#define IMX464_2LANES 2
137
-#define IMX464_4LANES 4
138136 #define IMX464_BITS_PER_SAMPLE 10
139137
140138 #define IMX464_VREVERSE_REG 0x304f
....@@ -150,12 +148,10 @@
150148
151149 #define USED_SYS_DEBUG
152150
153
-static bool g_isHCG;
154
-
155151 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
156152 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
157153
158
-#define IMX464_NAME "IMX464"
154
+#define IMX464_NAME "imx464"
159155
160156 static const char * const IMX464_supply_names[] = {
161157 "avdd", /* Analog power */
....@@ -164,14 +160,6 @@
164160 };
165161
166162 #define IMX464_NUM_SUPPLIES ARRAY_SIZE(IMX464_supply_names)
167
-
168
-enum IMX464_max_pad {
169
- PAD0, /* link to isp */
170
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
171
- PAD2, /* link to csi wr1 | hdr x3:L */
172
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
173
- PAD_MAX,
174
-};
175163
176164 struct regval {
177165 u16 addr;
....@@ -186,6 +174,9 @@
186174 u32 hts_def;
187175 u32 vts_def;
188176 u32 exp_def;
177
+ u32 mipi_freq_idx;
178
+ u32 mclk;
179
+ u32 bpp;
189180 const struct regval *reg_list;
190181 u32 hdr_mode;
191182 u32 vc[PAD_MAX];
....@@ -213,19 +204,22 @@
213204 struct v4l2_ctrl *pixel_rate;
214205 struct v4l2_ctrl *link_freq;
215206 struct mutex mutex;
207
+ struct v4l2_fwnode_endpoint bus_cfg;
216208 bool streaming;
217209 bool power_on;
210
+ bool has_init_exp;
211
+ const struct IMX464_mode *support_modes;
218212 const struct IMX464_mode *cur_mode;
219213 u32 module_index;
220214 u32 cfg_num;
221
- u32 cur_pixel_rate;
222
- u32 cur_link_freq;
215
+ u32 cur_vts;
216
+ u32 cur_mclk;
223217 const char *module_facing;
224218 const char *module_name;
225219 const char *len_name;
226
- u32 cur_vts;
227
- bool has_init_exp;
220
+ enum rkmodule_sync_mode sync_mode;
228221 struct preisp_hdrae_exp_s init_hdrae_exp;
222
+ bool isHCG;
229223 };
230224
231225 #define to_IMX464(sd) container_of(sd, struct IMX464, subdev)
....@@ -237,16 +231,16 @@
237231 {REG_NULL, 0x00},
238232 };
239233
240
-static const struct regval IMX464_linear_10bit_2688x1520_regs[] = {
234
+static __maybe_unused const struct regval IMX464_linear_10bit_2688x1520_2lane_37m_regs[] = {
241235 {0x3000, 0x01},
242236 {0x3002, 0x01},
243237 {0x300C, 0x5B},
244238 {0x300D, 0x40},
245
- {0x3030, 0xE4},
246
- {0x3031, 0x0C},
239
+ {0x3034, 0xDC},
240
+ {0x3035, 0x05},
247241 {0x3050, 0x00},
248
- {0x3058, 0x06},
249
- {0x3059, 0x09},
242
+ {0x3058, 0x83},
243
+ {0x3059, 0x04},
250244 {0x30BE, 0x5E},
251245 {0x30E8, 0x14},
252246 {0x3110, 0x02},
....@@ -256,6 +250,488 @@
256250 {0x319D, 0x00},
257251 {0x319E, 0x02},
258252 {0x31A1, 0x00},
253
+ {0x3288, 0x22},
254
+ {0x328A, 0x02},
255
+ {0x328C, 0xA2},
256
+ {0x328E, 0x22},
257
+ {0x3415, 0x27},
258
+ {0x3418, 0x27},
259
+ {0x3428, 0xFE},
260
+ {0x349E, 0x6A},
261
+ {0x34A2, 0x9A},
262
+ {0x34A4, 0x8A},
263
+ {0x34A6, 0x8E},
264
+ {0x34AA, 0xD8},
265
+ {0x35BC, 0x00},
266
+ {0x35BE, 0xFF},
267
+ {0x35CC, 0x1B},
268
+ {0x35CD, 0x00},
269
+ {0x35CE, 0x2A},
270
+ {0x35CF, 0x00},
271
+ {0x35DC, 0x07},
272
+ {0x35DE, 0x1A},
273
+ {0x35DF, 0x00},
274
+ {0x35E4, 0x2B},
275
+ {0x35E5, 0x00},
276
+ {0x35E6, 0x07},
277
+ {0x35E7, 0x01},
278
+ {0x3648, 0x01},
279
+ {0x3678, 0x01},
280
+ {0x367C, 0x69},
281
+ {0x367E, 0x69},
282
+ {0x3680, 0x69},
283
+ {0x3682, 0x69},
284
+ {0x3718, 0x1C},
285
+ {0x371D, 0x05},
286
+ {0x375D, 0x11},
287
+ {0x375E, 0x43},
288
+ {0x375F, 0x76},
289
+ {0x3760, 0x07},
290
+ {0x3768, 0x1B},
291
+ {0x3769, 0x1B},
292
+ {0x376A, 0x1A},
293
+ {0x376B, 0x19},
294
+ {0x376C, 0x17},
295
+ {0x376D, 0x0F},
296
+ {0x376E, 0x0B},
297
+ {0x376F, 0x0B},
298
+ {0x3770, 0x0B},
299
+ {0x3776, 0x89},
300
+ {0x3777, 0x00},
301
+ {0x3778, 0xCA},
302
+ {0x3779, 0x00},
303
+ {0x377A, 0x45},
304
+ {0x377B, 0x01},
305
+ {0x377C, 0x56},
306
+ {0x377D, 0x02},
307
+ {0x377E, 0xFE},
308
+ {0x377F, 0x03},
309
+ {0x3780, 0xFE},
310
+ {0x3781, 0x05},
311
+ {0x3782, 0xFE},
312
+ {0x3783, 0x06},
313
+ {0x3784, 0x7F},
314
+ {0x3788, 0x1F},
315
+ {0x378A, 0xCA},
316
+ {0x378B, 0x00},
317
+ {0x378C, 0x45},
318
+ {0x378D, 0x01},
319
+ {0x378E, 0x56},
320
+ {0x378F, 0x02},
321
+ {0x3790, 0xFE},
322
+ {0x3791, 0x03},
323
+ {0x3792, 0xFE},
324
+ {0x3793, 0x05},
325
+ {0x3794, 0xFE},
326
+ {0x3795, 0x06},
327
+ {0x3796, 0x7F},
328
+ {0x3798, 0xBF},
329
+ {0x3A01, 0x01},
330
+ {0x3A18, 0x7F},
331
+ {0x3A1A, 0x37},
332
+ {0x3A1C, 0x37},
333
+ {0x3A1E, 0xF7},
334
+ {0x3A1F, 0x00},
335
+ {0x3A20, 0x3F},
336
+ {0x3A22, 0x6F},
337
+ {0x3A24, 0x3F},
338
+ {0x3A26, 0x5F},
339
+ {0x3A28, 0x2F},
340
+ {REG_NULL, 0x00},
341
+};
342
+
343
+static __maybe_unused const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_37m_regs[] = {
344
+ {0x3000, 0x01},
345
+ {0x3002, 0x01},
346
+ {0x300C, 0x5B},
347
+ {0x300D, 0x40},
348
+ {0x3034, 0xDC},
349
+ {0x3035, 0x05},
350
+ {0x3048, 0x01},
351
+ {0x3049, 0x01},
352
+ {0x304A, 0x01},
353
+ {0x304B, 0x01},
354
+ {0x304C, 0x13},
355
+ {0x304D, 0x00},
356
+ {0x3050, 0x00},
357
+ {0x3058, 0xF4},
358
+ {0x3059, 0x0A},
359
+ {0x3068, 0x3D},
360
+ {0x30BE, 0x5E},
361
+ {0x30E8, 0x0A},
362
+ {0x3110, 0x02},
363
+ {0x314C, 0x80},//
364
+ {0x315A, 0x02},
365
+ {0x316A, 0x7E},
366
+ {0x319D, 0x00},
367
+ {0x319E, 0x01},//1188M
368
+ {0x31A1, 0x00},
369
+ {0x31D7, 0x01},
370
+ {0x3200, 0x10},
371
+ {0x3288, 0x22},
372
+ {0x328A, 0x02},
373
+ {0x328C, 0xA2},
374
+ {0x328E, 0x22},
375
+ {0x3415, 0x27},
376
+ {0x3418, 0x27},
377
+ {0x3428, 0xFE},
378
+ {0x349E, 0x6A},
379
+ {0x34A2, 0x9A},
380
+ {0x34A4, 0x8A},
381
+ {0x34A6, 0x8E},
382
+ {0x34AA, 0xD8},
383
+ {0x35BC, 0x00},
384
+ {0x35BE, 0xFF},
385
+ {0x35CC, 0x1B},
386
+ {0x35CD, 0x00},
387
+ {0x35CE, 0x2A},
388
+ {0x35CF, 0x00},
389
+ {0x35DC, 0x07},
390
+ {0x35DE, 0x1A},
391
+ {0x35DF, 0x00},
392
+ {0x35E4, 0x2B},
393
+ {0x35E5, 0x00},
394
+ {0x35E6, 0x07},
395
+ {0x35E7, 0x01},
396
+ {0x3648, 0x01},
397
+ {0x3678, 0x01},
398
+ {0x367C, 0x69},
399
+ {0x367E, 0x69},
400
+ {0x3680, 0x69},
401
+ {0x3682, 0x69},
402
+ {0x3718, 0x1C},
403
+ {0x371D, 0x05},
404
+ {0x375D, 0x11},
405
+ {0x375E, 0x43},
406
+ {0x375F, 0x76},
407
+ {0x3760, 0x07},
408
+ {0x3768, 0x1B},
409
+ {0x3769, 0x1B},
410
+ {0x376A, 0x1A},
411
+ {0x376B, 0x19},
412
+ {0x376C, 0x17},
413
+ {0x376D, 0x0F},
414
+ {0x376E, 0x0B},
415
+ {0x376F, 0x0B},
416
+ {0x3770, 0x0B},
417
+ {0x3776, 0x89},
418
+ {0x3777, 0x00},
419
+ {0x3778, 0xCA},
420
+ {0x3779, 0x00},
421
+ {0x377A, 0x45},
422
+ {0x377B, 0x01},
423
+ {0x377C, 0x56},
424
+ {0x377D, 0x02},
425
+ {0x377E, 0xFE},
426
+ {0x377F, 0x03},
427
+ {0x3780, 0xFE},
428
+ {0x3781, 0x05},
429
+ {0x3782, 0xFE},
430
+ {0x3783, 0x06},
431
+ {0x3784, 0x7F},
432
+ {0x3788, 0x1F},
433
+ {0x378A, 0xCA},
434
+ {0x378B, 0x00},
435
+ {0x378C, 0x45},
436
+ {0x378D, 0x01},
437
+ {0x378E, 0x56},
438
+ {0x378F, 0x02},
439
+ {0x3790, 0xFE},
440
+ {0x3791, 0x03},
441
+ {0x3792, 0xFE},
442
+ {0x3793, 0x05},
443
+ {0x3794, 0xFE},
444
+ {0x3795, 0x06},
445
+ {0x3796, 0x7F},
446
+ {0x3798, 0xBF},
447
+ {0x3A01, 0x01},
448
+ {0x3A18, 0x8F},
449
+ {0x3A1A, 0x4F},
450
+ {0x3A1C, 0x47},
451
+ {0x3A1E, 0x37},
452
+ {0x3A1F, 0x01},
453
+ {0x3A20, 0x4F},
454
+ {0x3A22, 0x87},
455
+ {0x3A24, 0x4F},
456
+ {0x3A26, 0x7F},
457
+ {0x3A28, 0x3F},
458
+ {REG_NULL, 0x00},
459
+};
460
+
461
+static const struct regval IMX464_linear_10bit_2688x1520_2lane_regs[] = {
462
+ {0x3000, 0x01},
463
+ {0x3002, 0x01},
464
+ {0x300C, 0x3b},
465
+ {0x300D, 0x2a},
466
+ {0x3034, 0xDC},
467
+ {0x3035, 0x05},
468
+ {0x3048, 0x00},
469
+ {0x3049, 0x00},
470
+ {0x304A, 0x03},
471
+ {0x304B, 0x02},
472
+ {0x304C, 0x14},
473
+ {0x304D, 0x03},
474
+ {0x3050, 0x00},
475
+ {0x3058, 0x83},
476
+ {0x3059, 0x04},
477
+ {0x3068, 0xc9},
478
+ {0x30BE, 0x5E},
479
+ {0x30E8, 0x14},
480
+ {0x3110, 0x02},
481
+ {0x314C, 0x29},
482
+ {0x314D, 0x01},
483
+ {0x315A, 0x06},
484
+ {0x3168, 0xA0},
485
+ {0x316A, 0x7E},
486
+ {0x319D, 0x00},
487
+ {0x319E, 0x02},
488
+ {0x31A1, 0x00},
489
+ {0x31D7, 0x00},
490
+ {0x3200, 0x11},
491
+ {0x3288, 0x22},
492
+ {0x328A, 0x02},
493
+ {0x328C, 0xA2},
494
+ {0x328E, 0x22},
495
+ {0x3415, 0x27},
496
+ {0x3418, 0x27},
497
+ {0x3428, 0xFE},
498
+ {0x349E, 0x6A},
499
+ {0x34A2, 0x9A},
500
+ {0x34A4, 0x8A},
501
+ {0x34A6, 0x8E},
502
+ {0x34AA, 0xD8},
503
+ {0x35BC, 0x00},
504
+ {0x35BE, 0xFF},
505
+ {0x35CC, 0x1B},
506
+ {0x35CD, 0x00},
507
+ {0x35CE, 0x2A},
508
+ {0x35CF, 0x00},
509
+ {0x35DC, 0x07},
510
+ {0x35DE, 0x1A},
511
+ {0x35DF, 0x00},
512
+ {0x35E4, 0x2B},
513
+ {0x35E5, 0x00},
514
+ {0x35E6, 0x07},
515
+ {0x35E7, 0x01},
516
+ {0x3648, 0x01},
517
+ {0x3678, 0x01},
518
+ {0x367C, 0x69},
519
+ {0x367E, 0x69},
520
+ {0x3680, 0x69},
521
+ {0x3682, 0x69},
522
+ {0x3718, 0x1C},
523
+ {0x371D, 0x05},
524
+ {0x375D, 0x11},
525
+ {0x375E, 0x43},
526
+ {0x375F, 0x76},
527
+ {0x3760, 0x07},
528
+ {0x3768, 0x1B},
529
+ {0x3769, 0x1B},
530
+ {0x376A, 0x1A},
531
+ {0x376B, 0x19},
532
+ {0x376C, 0x17},
533
+ {0x376D, 0x0F},
534
+ {0x376E, 0x0B},
535
+ {0x376F, 0x0B},
536
+ {0x3770, 0x0B},
537
+ {0x3776, 0x89},
538
+ {0x3777, 0x00},
539
+ {0x3778, 0xCA},
540
+ {0x3779, 0x00},
541
+ {0x377A, 0x45},
542
+ {0x377B, 0x01},
543
+ {0x377C, 0x56},
544
+ {0x377D, 0x02},
545
+ {0x377E, 0xFE},
546
+ {0x377F, 0x03},
547
+ {0x3780, 0xFE},
548
+ {0x3781, 0x05},
549
+ {0x3782, 0xFE},
550
+ {0x3783, 0x06},
551
+ {0x3784, 0x7F},
552
+ {0x3788, 0x1F},
553
+ {0x378A, 0xCA},
554
+ {0x378B, 0x00},
555
+ {0x378C, 0x45},
556
+ {0x378D, 0x01},
557
+ {0x378E, 0x56},
558
+ {0x378F, 0x02},
559
+ {0x3790, 0xFE},
560
+ {0x3791, 0x03},
561
+ {0x3792, 0xFE},
562
+ {0x3793, 0x05},
563
+ {0x3794, 0xFE},
564
+ {0x3795, 0x06},
565
+ {0x3796, 0x7F},
566
+ {0x3798, 0xBF},
567
+ {0x3A01, 0x01},
568
+ {0x3A18, 0x7F},
569
+ {0x3A1A, 0x37},
570
+ {0x3A1C, 0x37},
571
+ {0x3A1E, 0xF7},
572
+ {0x3A1F, 0x00},
573
+ {0x3A20, 0x3F},
574
+ {0x3A22, 0x6F},
575
+ {0x3A24, 0x3F},
576
+ {0x3A26, 0x5F},
577
+ {0x3A28, 0x2F},
578
+ {REG_NULL, 0x00},
579
+};
580
+
581
+static const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_regs[] = {
582
+ {0x3000, 0x01},
583
+ {0x3002, 0x01},
584
+ {0x300C, 0x3B},
585
+ {0x300D, 0x2A},
586
+ {0x3034, 0xDC},
587
+ {0x3035, 0x05},
588
+ {0x3048, 0x01},
589
+ {0x3049, 0x01},
590
+ {0x304A, 0x04},
591
+ {0x304B, 0x04},
592
+ {0x304C, 0x13},
593
+ {0x304D, 0x00},
594
+ {0x3050, 0x00},
595
+ {0x3058, 0xF4},
596
+ {0x3059, 0x0A},
597
+ {0x3068, 0x3D},
598
+ {0x30BE, 0x5E},
599
+ {0x30E8, 0x14},
600
+ {0x3110, 0x02},
601
+ {0x314C, 0x29},//
602
+ {0x314D, 0x01},//
603
+ {0x315A, 0x06},
604
+ {0x3168, 0xA0},
605
+ {0x316A, 0x7E},
606
+ {0x319D, 0x00},
607
+ {0x319E, 0x02},//1188M
608
+ {0x31A1, 0x00},
609
+ {0x31D7, 0x01},
610
+ {0x3200, 0x10},
611
+ {0x3288, 0x22},
612
+ {0x328A, 0x02},
613
+ {0x328C, 0xA2},
614
+ {0x328E, 0x22},
615
+ {0x3415, 0x27},
616
+ {0x3418, 0x27},
617
+ {0x3428, 0xFE},
618
+ {0x349E, 0x6A},
619
+ {0x34A2, 0x9A},
620
+ {0x34A4, 0x8A},
621
+ {0x34A6, 0x8E},
622
+ {0x34AA, 0xD8},
623
+ {0x35BC, 0x00},
624
+ {0x35BE, 0xFF},
625
+ {0x35CC, 0x1B},
626
+ {0x35CD, 0x00},
627
+ {0x35CE, 0x2A},
628
+ {0x35CF, 0x00},
629
+ {0x35DC, 0x07},
630
+ {0x35DE, 0x1A},
631
+ {0x35DF, 0x00},
632
+ {0x35E4, 0x2B},
633
+ {0x35E5, 0x00},
634
+ {0x35E6, 0x07},
635
+ {0x35E7, 0x01},
636
+ {0x3648, 0x01},
637
+ {0x3678, 0x01},
638
+ {0x367C, 0x69},
639
+ {0x367E, 0x69},
640
+ {0x3680, 0x69},
641
+ {0x3682, 0x69},
642
+ {0x3718, 0x1C},
643
+ {0x371D, 0x05},
644
+ {0x375D, 0x11},
645
+ {0x375E, 0x43},
646
+ {0x375F, 0x76},
647
+ {0x3760, 0x07},
648
+ {0x3768, 0x1B},
649
+ {0x3769, 0x1B},
650
+ {0x376A, 0x1A},
651
+ {0x376B, 0x19},
652
+ {0x376C, 0x17},
653
+ {0x376D, 0x0F},
654
+ {0x376E, 0x0B},
655
+ {0x376F, 0x0B},
656
+ {0x3770, 0x0B},
657
+ {0x3776, 0x89},
658
+ {0x3777, 0x00},
659
+ {0x3778, 0xCA},
660
+ {0x3779, 0x00},
661
+ {0x377A, 0x45},
662
+ {0x377B, 0x01},
663
+ {0x377C, 0x56},
664
+ {0x377D, 0x02},
665
+ {0x377E, 0xFE},
666
+ {0x377F, 0x03},
667
+ {0x3780, 0xFE},
668
+ {0x3781, 0x05},
669
+ {0x3782, 0xFE},
670
+ {0x3783, 0x06},
671
+ {0x3784, 0x7F},
672
+ {0x3788, 0x1F},
673
+ {0x378A, 0xCA},
674
+ {0x378B, 0x00},
675
+ {0x378C, 0x45},
676
+ {0x378D, 0x01},
677
+ {0x378E, 0x56},
678
+ {0x378F, 0x02},
679
+ {0x3790, 0xFE},
680
+ {0x3791, 0x03},
681
+ {0x3792, 0xFE},
682
+ {0x3793, 0x05},
683
+ {0x3794, 0xFE},
684
+ {0x3795, 0x06},
685
+ {0x3796, 0x7F},
686
+ {0x3798, 0xBF},
687
+ {0x3A01, 0x01},
688
+ {0x3A18, 0x7F},
689
+ {0x3A1A, 0x37},
690
+ {0x3A1C, 0x37},
691
+ {0x3A1E, 0xF7},
692
+ {0x3A1F, 0x00},
693
+ {0x3A20, 0x3F},
694
+ {0x3A22, 0x6F},
695
+ {0x3A24, 0x3F},
696
+ {0x3A26, 0x5F},
697
+ {0x3A28, 0x2F},
698
+ {REG_NULL, 0x00},
699
+};
700
+
701
+static const struct regval IMX464_linear_10bit_2688x1520_regs[] = {
702
+ {0x3000, 0x01},
703
+ {0x3002, 0x01},
704
+ {0x300C, 0x5B},
705
+ {0x300D, 0x40},
706
+ {0x3030, 0xE4},
707
+ {0x3031, 0x0C},
708
+ {0x3034, 0xee},
709
+ {0x3035, 0x02},
710
+ {0x3048, 0x00},
711
+ {0x3049, 0x00},
712
+ {0x304A, 0x03},
713
+ {0x304B, 0x02},
714
+ {0x304C, 0x14},
715
+ {0x3050, 0x00},
716
+ {0x3058, 0x06},
717
+ {0x3059, 0x09},
718
+ {0x305C, 0x09},
719
+ {0x3060, 0x21},
720
+ {0x3061, 0x01},
721
+ {0x3068, 0xc9},
722
+ {0x306C, 0x56},
723
+ {0x306D, 0x09},
724
+ {0x30BE, 0x5E},
725
+ {0x30E8, 0x14},
726
+ {0x3110, 0x02},
727
+ {0x314C, 0xC0},
728
+ {0x315A, 0x06},
729
+ {0x316A, 0x7E},
730
+ {0x319D, 0x00},
731
+ {0x319E, 0x02},
732
+ {0x31A1, 0x00},
733
+ {0x31D7, 0x00},
734
+ {0x3200, 0x11},
259735 {0x3288, 0x22},
260736 {0x328A, 0x02},
261737 {0x328C, 0xA2},
....@@ -350,6 +826,10 @@
350826 {0x3002, 0x01},
351827 {0x300C, 0x5B},
352828 {0x300D, 0x40},
829
+ {0x3030, 0x72},
830
+ {0x3031, 0x06},
831
+ {0x3034, 0xee},
832
+ {0x3035, 0x02},
353833 {0x3048, 0x01},
354834 {0x3049, 0x01},
355835 {0x304A, 0x04},
....@@ -358,7 +838,12 @@
358838 {0x3050, 0x00},
359839 {0x3058, 0x06},
360840 {0x3059, 0x09},
841
+ {0x305C, 0x09},
842
+ {0x3060, 0x21},
843
+ {0x3061, 0x01},
361844 {0x3068, 0x6D},
845
+ {0x306C, 0x56},
846
+ {0x306D, 0x09},
362847 {0x30BE, 0x5E},
363848 {0x30E8, 0x14},
364849 {0x3110, 0x02},
....@@ -498,6 +983,7 @@
498983 {0x319E, 0x01},
499984 {0x31A1, 0x00},
500985 {0x31D7, 0x03},
986
+ {0x3200, 0x10},
501987 {0x3288, 0x22},
502988 {0x328A, 0x02},
503989 {0x328C, 0xA2},
....@@ -584,7 +1070,6 @@
5841070 {0x3A24, 0x4F},
5851071 {0x3A26, 0x5F},
5861072 {0x3A28, 0x3F},
587
- {0x3200, 0x10},
5881073 {REG_NULL, 0x00},
5891074 };
5901075
....@@ -824,6 +1309,33 @@
8241309 {REG_NULL, 0x00},
8251310 };
8261311
1312
+static __maybe_unused const struct regval IMX464_interal_sync_master_start_regs[] = {
1313
+ {0x3010, 0x07},
1314
+ {0x31a1, 0x00},
1315
+ {REG_NULL, 0x00},
1316
+};
1317
+static __maybe_unused const struct regval IMX464_interal_sync_master_stop_regs[] = {
1318
+ {0x31a1, 0x0f},
1319
+ {REG_NULL, 0x00},
1320
+};
1321
+
1322
+static __maybe_unused const struct regval IMX464_external_sync_master_start_regs[] = {
1323
+ {0x3010, 0x05},
1324
+ {0x31a1, 0x03},
1325
+ {0x31d9, 0x01},
1326
+ {REG_NULL, 0x00},
1327
+};
1328
+static __maybe_unused const struct regval IMX464_external_sync_master_stop_regs[] = {
1329
+ {0x31a1, 0x0f},
1330
+ {REG_NULL, 0x00},
1331
+};
1332
+
1333
+static __maybe_unused const struct regval IMX464_slave_start_regs[] = {
1334
+ {0x3010, 0x05},
1335
+ {0x31a1, 0x0f},
1336
+ {REG_NULL, 0x00},
1337
+};
1338
+
8271339 /*
8281340 * The width and height must be configured to be
8291341 * the same as the current output resolution of the sensor.
....@@ -848,6 +1360,9 @@
8481360 .exp_def = 0x0906,
8491361 .hts_def = 0x05dc * 2,
8501362 .vts_def = 0x0ce4,
1363
+ .mipi_freq_idx = 0,
1364
+ .bpp = 10,
1365
+ .mclk = 37125000,
8511366 .reg_list = IMX464_linear_10bit_2688x1520_regs,
8521367 .hdr_mode = NO_HDR,
8531368 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
....@@ -863,6 +1378,9 @@
8631378 .exp_def = 0x03de,
8641379 .hts_def = 0x02ee * 4,
8651380 .vts_def = 0x0672 * 2,
1381
+ .mipi_freq_idx = 1,
1382
+ .bpp = 10,
1383
+ .mclk = 37125000,
8661384 .reg_list = IMX464_hdr_2x_10bit_2688x1520_regs,
8671385 .hdr_mode = HDR_X2,
8681386 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
....@@ -889,12 +1407,57 @@
8891407 #else
8901408 .vts_def = 0x04D1 * 4,
8911409 #endif
1410
+ .mipi_freq_idx = 1,
1411
+ .bpp = 10,
1412
+ .mclk = 37125000,
8921413 .reg_list = IMX464_hdr_3x_10bit_2688x1520_regs,
8931414 .hdr_mode = HDR_X3,
8941415 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
8951416 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
8961417 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr1
8971418 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1419
+ },
1420
+};
1421
+
1422
+static const struct IMX464_mode supported_modes_2lane[] = {
1423
+ {
1424
+ .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1425
+ .width = 2712,
1426
+ .height = 1538,
1427
+ .max_fps = {
1428
+ .numerator = 10000,
1429
+ .denominator = 300000,
1430
+ },
1431
+ .exp_def = 0x0600,
1432
+ .hts_def = 0x05dc * 2,
1433
+ .vts_def = 0x672,
1434
+ .mipi_freq_idx = 0,
1435
+ .bpp = 10,
1436
+ .mclk = 24000000,
1437
+ .reg_list = IMX464_linear_10bit_2688x1520_2lane_regs,
1438
+ .hdr_mode = NO_HDR,
1439
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1440
+ },
1441
+ {
1442
+ .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1443
+ .width = 2712,
1444
+ .height = 1538,
1445
+ .max_fps = {
1446
+ .numerator = 10000,
1447
+ .denominator = 150000,
1448
+ },
1449
+ .exp_def = 0x0600,
1450
+ .hts_def = 0x05dc * 4,
1451
+ .vts_def = 0x0672 * 2,
1452
+ .mipi_freq_idx = 0,
1453
+ .bpp = 10,
1454
+ .mclk = 24000000,
1455
+ .reg_list = IMX464_hdr_2x_10bit_2688x1520_2lane_regs,
1456
+ .hdr_mode = HDR_X2,
1457
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1458
+ .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1459
+ .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1460
+ .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
8981461 },
8991462 };
9001463
....@@ -997,15 +1560,15 @@
9971560 unsigned int i;
9981561
9991562 for (i = 0; i < IMX464->cfg_num; i++) {
1000
- dist = IMX464_get_reso_dist(&supported_modes[i], framefmt);
1563
+ dist = IMX464_get_reso_dist(&IMX464->support_modes[i], framefmt);
10011564 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
1002
- supported_modes[i].bus_fmt == framefmt->code) {
1565
+ IMX464->support_modes[i].bus_fmt == framefmt->code) {
10031566 cur_best_fit_dist = dist;
10041567 cur_best_fit = i;
10051568 }
10061569 }
10071570
1008
- return &supported_modes[cur_best_fit];
1571
+ return &IMX464->support_modes[cur_best_fit];
10091572 }
10101573
10111574 static int IMX464_set_fmt(struct v4l2_subdev *sd,
....@@ -1015,8 +1578,7 @@
10151578 struct IMX464 *IMX464 = to_IMX464(sd);
10161579 const struct IMX464_mode *mode;
10171580 s64 h_blank, vblank_def;
1018
- struct device *dev = &IMX464->client->dev;
1019
- int ret = 0;
1581
+ u64 pixel_rate = 0;
10201582
10211583 mutex_lock(&IMX464->mutex);
10221584
....@@ -1042,42 +1604,12 @@
10421604 IMX464_VTS_MAX - mode->height,
10431605 1, vblank_def);
10441606 IMX464->cur_vts = IMX464->cur_mode->vts_def;
1045
- if (mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
1046
- IMX464->cur_link_freq = 1;
1047
- if (mode->hdr_mode == NO_HDR) {
1048
- IMX464->cur_pixel_rate = IMX464_10BIT_LINEAR_PIXEL_RATE;
1049
- IMX464->cur_link_freq = 0;
1050
- } else if (mode->hdr_mode == HDR_X2)
1051
- IMX464->cur_pixel_rate = IMX464_10BIT_HDR2_PIXEL_RATE;
1052
- else if (mode->hdr_mode == HDR_X3)
1053
- IMX464->cur_pixel_rate = IMX464_10BIT_HDR3_PIXEL_RATE;
1054
-
1055
- clk_disable_unprepare(IMX464->xvclk);
1056
- ret = clk_set_rate(IMX464->xvclk, IMX464_XVCLK_FREQ_37M);
1057
- if (ret < 0)
1058
- dev_err(dev, "Failed to set xvclk rate\n");
1059
- if (clk_get_rate(IMX464->xvclk) != IMX464_XVCLK_FREQ_37M)
1060
- dev_err(dev, "xvclk mismatched\n");
1061
- ret = clk_prepare_enable(IMX464->xvclk);
1062
- if (ret < 0)
1063
- dev_err(dev, "Failed to enable xvclk\n");
1064
- } else {
1065
- IMX464->cur_pixel_rate = IMX464_12BIT_PIXEL_RATE;
1066
- IMX464->cur_link_freq = 0;
1067
- clk_disable_unprepare(IMX464->xvclk);
1068
- ret = clk_set_rate(IMX464->xvclk, IMX464_XVCLK_FREQ_24M);
1069
- if (ret < 0)
1070
- dev_err(dev, "Failed to set xvclk rate\n");
1071
- if (clk_get_rate(IMX464->xvclk) != IMX464_XVCLK_FREQ_24M)
1072
- dev_err(dev, "xvclk mismatched\n");
1073
- ret = clk_prepare_enable(IMX464->xvclk);
1074
- if (ret < 0)
1075
- dev_err(dev, "Failed to enable xvclk\n");
1076
- }
1607
+ pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
1608
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
10771609 __v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
1078
- IMX464->cur_pixel_rate);
1610
+ pixel_rate);
10791611 __v4l2_ctrl_s_ctrl(IMX464->link_freq,
1080
- IMX464->cur_link_freq);
1612
+ mode->mipi_freq_idx);
10811613 }
10821614
10831615 mutex_unlock(&IMX464->mutex);
....@@ -1137,13 +1669,13 @@
11371669 if (fse->index >= IMX464->cfg_num)
11381670 return -EINVAL;
11391671
1140
- if (fse->code != supported_modes[fse->index].bus_fmt)
1672
+ if (fse->code != IMX464->support_modes[fse->index].bus_fmt)
11411673 return -EINVAL;
11421674
1143
- fse->min_width = supported_modes[fse->index].width;
1144
- fse->max_width = supported_modes[fse->index].width;
1145
- fse->max_height = supported_modes[fse->index].height;
1146
- fse->min_height = supported_modes[fse->index].height;
1675
+ fse->min_width = IMX464->support_modes[fse->index].width;
1676
+ fse->max_width = IMX464->support_modes[fse->index].width;
1677
+ fse->max_height = IMX464->support_modes[fse->index].height;
1678
+ fse->min_height = IMX464->support_modes[fse->index].height;
11471679
11481680 return 0;
11491681 }
....@@ -1154,38 +1686,37 @@
11541686 struct IMX464 *IMX464 = to_IMX464(sd);
11551687 const struct IMX464_mode *mode = IMX464->cur_mode;
11561688
1157
- mutex_lock(&IMX464->mutex);
11581689 fi->interval = mode->max_fps;
1159
- mutex_unlock(&IMX464->mutex);
11601690
11611691 return 0;
11621692 }
11631693
1164
-static int IMX464_g_mbus_config(struct v4l2_subdev *sd,
1694
+static int IMX464_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
11651695 struct v4l2_mbus_config *config)
11661696 {
11671697 struct IMX464 *IMX464 = to_IMX464(sd);
11681698 const struct IMX464_mode *mode = IMX464->cur_mode;
11691699 u32 val = 0;
1700
+ u32 lane_num = IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
11701701
11711702 if (mode->hdr_mode == NO_HDR) {
1172
- val = 1 << (IMX464_4LANES - 1) |
1703
+ val = 1 << (lane_num - 1) |
11731704 V4L2_MBUS_CSI2_CHANNEL_0 |
11741705 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
11751706 }
11761707 if (mode->hdr_mode == HDR_X2)
1177
- val = 1 << (IMX464_4LANES - 1) |
1708
+ val = 1 << (lane_num - 1) |
11781709 V4L2_MBUS_CSI2_CHANNEL_0 |
11791710 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
11801711 V4L2_MBUS_CSI2_CHANNEL_1;
11811712 if (mode->hdr_mode == HDR_X3)
1182
- val = 1 << (IMX464_4LANES - 1) |
1713
+ val = 1 << (lane_num - 1) |
11831714 V4L2_MBUS_CSI2_CHANNEL_0 |
11841715 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
11851716 V4L2_MBUS_CSI2_CHANNEL_1 |
11861717 V4L2_MBUS_CSI2_CHANNEL_2;
11871718
1188
- config->type = V4L2_MBUS_CSI2;
1719
+ config->type = V4L2_MBUS_CSI2_DPHY;
11891720 config->flags = val;
11901721
11911722 return 0;
....@@ -1241,12 +1772,12 @@
12411772 l_exp_time = m_exp_time;
12421773 cg_mode = ae->middle_cg_mode;
12431774 }
1244
- if (!g_isHCG && cg_mode == GAIN_MODE_HCG) {
1775
+ if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
12451776 gain_switch = 0x01 | 0x100;
1246
- g_isHCG = true;
1247
- } else if (g_isHCG && cg_mode == GAIN_MODE_LCG) {
1777
+ IMX464->isHCG = true;
1778
+ } else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
12481779 gain_switch = 0x00 | 0x100;
1249
- g_isHCG = false;
1780
+ IMX464->isHCG = false;
12501781 }
12511782 ret = imx464_write_reg(client,
12521783 IMX464_GROUP_HOLD_REG,
....@@ -1323,7 +1854,7 @@
13231854 __LINE__, rhs1, s_exp_time, rhs1_old,
13241855 (rhs1_old + 2 * BRL - fsc + 2));
13251856
1326
- rhs1 = (rhs1 >> 2) * 4 + 1;
1857
+ rhs1 = ((rhs1 + 3) >> 2) * 4 + 1;
13271858 rhs1_old = rhs1;
13281859
13291860 if (rhs1 - s_exp_time <= SHR1_MIN) {
....@@ -1428,12 +1959,12 @@
14281959 //3 stagger
14291960 cg_mode = ae->long_cg_mode;
14301961 }
1431
- if (!g_isHCG && cg_mode == GAIN_MODE_HCG) {
1962
+ if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
14321963 gain_switch = 0x01 | 0x100;
1433
- g_isHCG = true;
1434
- } else if (g_isHCG && cg_mode == GAIN_MODE_LCG) {
1964
+ IMX464->isHCG = true;
1965
+ } else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
14351966 gain_switch = 0x00 | 0x100;
1436
- g_isHCG = false;
1967
+ IMX464->isHCG = false;
14371968 }
14381969
14391970 dev_dbg(&client->dev,
....@@ -1670,12 +2201,12 @@
16702201 int cur_cg = *cg;
16712202 u32 gain_switch = 0;
16722203
1673
- if (g_isHCG && cur_cg == GAIN_MODE_LCG) {
2204
+ if (IMX464->isHCG && cur_cg == GAIN_MODE_LCG) {
16742205 gain_switch = 0x00 | 0x100;
1675
- g_isHCG = false;
1676
- } else if (!g_isHCG && cur_cg == GAIN_MODE_HCG) {
2206
+ IMX464->isHCG = false;
2207
+ } else if (!IMX464->isHCG && cur_cg == GAIN_MODE_HCG) {
16772208 gain_switch = 0x01 | 0x100;
1678
- g_isHCG = true;
2209
+ IMX464->isHCG = true;
16792210 }
16802211 ret = imx464_write_reg(client,
16812212 IMX464_GROUP_HOLD_REG,
....@@ -1743,12 +2274,26 @@
17432274 }
17442275 #endif
17452276
2277
+static int IMX464_get_channel_info(struct IMX464 *IMX464, struct rkmodule_channel_info *ch_info)
2278
+{
2279
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
2280
+ return -EINVAL;
2281
+ ch_info->vc = IMX464->cur_mode->vc[ch_info->index];
2282
+ ch_info->width = IMX464->cur_mode->width;
2283
+ ch_info->height = IMX464->cur_mode->height;
2284
+ ch_info->bus_fmt = IMX464->cur_mode->bus_fmt;
2285
+ return 0;
2286
+}
2287
+
17462288 static long IMX464_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
17472289 {
17482290 struct IMX464 *IMX464 = to_IMX464(sd);
17492291 struct rkmodule_hdr_cfg *hdr;
2292
+ struct rkmodule_channel_info *ch_info;
17502293 u32 i, h, w, stream;
17512294 long ret = 0;
2295
+ u64 pixel_rate = 0;
2296
+ u32 *sync_mode = NULL;
17522297
17532298 switch (cmd) {
17542299 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1770,10 +2315,10 @@
17702315 w = IMX464->cur_mode->width;
17712316 h = IMX464->cur_mode->height;
17722317 for (i = 0; i < IMX464->cfg_num; i++) {
1773
- if (w == supported_modes[i].width &&
1774
- h == supported_modes[i].height &&
1775
- supported_modes[i].hdr_mode == hdr->hdr_mode) {
1776
- IMX464->cur_mode = &supported_modes[i];
2318
+ if (w == IMX464->support_modes[i].width &&
2319
+ h == IMX464->support_modes[i].height &&
2320
+ IMX464->support_modes[i].hdr_mode == hdr->hdr_mode) {
2321
+ IMX464->cur_mode = &IMX464->support_modes[i];
17772322 break;
17782323 }
17792324 }
....@@ -1790,16 +2335,12 @@
17902335 IMX464_VTS_MAX - IMX464->cur_mode->height,
17912336 1, h);
17922337 IMX464->cur_vts = IMX464->cur_mode->vts_def;
1793
- if (IMX464->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
1794
- if (IMX464->cur_mode->hdr_mode == NO_HDR)
1795
- IMX464->cur_pixel_rate = IMX464_10BIT_LINEAR_PIXEL_RATE;
1796
- else if (IMX464->cur_mode->hdr_mode == HDR_X2)
1797
- IMX464->cur_pixel_rate = IMX464_10BIT_HDR2_PIXEL_RATE;
1798
- else if (IMX464->cur_mode->hdr_mode == HDR_X3)
1799
- IMX464->cur_pixel_rate = IMX464_10BIT_HDR3_PIXEL_RATE;
1800
- __v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
1801
- IMX464->cur_pixel_rate);
1802
- }
2338
+ pixel_rate = (u32)link_freq_menu_items[IMX464->cur_mode->mipi_freq_idx] / IMX464->cur_mode->bpp * 2 *
2339
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
2340
+ __v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
2341
+ pixel_rate);
2342
+ __v4l2_ctrl_s_ctrl(IMX464->link_freq,
2343
+ IMX464->cur_mode->mipi_freq_idx);
18032344 }
18042345 break;
18052346 case RKMODULE_SET_CONVERSION_GAIN:
....@@ -1809,16 +2350,25 @@
18092350
18102351 stream = *((u32 *)arg);
18112352
1812
- if (stream) {
2353
+ if (stream)
18132354 ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
18142355 IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
1815
- usleep_range(30000, 40000);
1816
- imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
1817
- IMX464_REG_VALUE_08BIT, 0);
1818
- } else {
2356
+ else
18192357 ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
18202358 IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
1821
- }
2359
+
2360
+ break;
2361
+ case RKMODULE_GET_CHANNEL_INFO:
2362
+ ch_info = (struct rkmodule_channel_info *)arg;
2363
+ ret = IMX464_get_channel_info(IMX464, ch_info);
2364
+ break;
2365
+ case RKMODULE_GET_SYNC_MODE:
2366
+ sync_mode = (u32 *)arg;
2367
+ *sync_mode = IMX464->sync_mode;
2368
+ break;
2369
+ case RKMODULE_SET_SYNC_MODE:
2370
+ sync_mode = (u32 *)arg;
2371
+ IMX464->sync_mode = *sync_mode;
18222372 break;
18232373 default:
18242374 ret = -ENOIOCTLCMD;
....@@ -1837,9 +2387,11 @@
18372387 struct rkmodule_awb_cfg *cfg;
18382388 struct rkmodule_hdr_cfg *hdr;
18392389 struct preisp_hdrae_exp_s *hdrae;
2390
+ struct rkmodule_channel_info *ch_info;
18402391 long ret;
18412392 u32 cg = 0;
18422393 u32 stream;
2394
+ u32 sync_mode;
18432395
18442396 switch (cmd) {
18452397 case RKMODULE_GET_MODULE_INFO:
....@@ -1850,8 +2402,11 @@
18502402 }
18512403
18522404 ret = IMX464_ioctl(sd, cmd, inf);
1853
- if (!ret)
2405
+ if (!ret) {
18542406 ret = copy_to_user(up, inf, sizeof(*inf));
2407
+ if (ret)
2408
+ ret = -EFAULT;
2409
+ }
18552410 kfree(inf);
18562411 break;
18572412 case RKMODULE_AWB_CFG:
....@@ -1864,6 +2419,8 @@
18642419 ret = copy_from_user(cfg, up, sizeof(*cfg));
18652420 if (!ret)
18662421 ret = IMX464_ioctl(sd, cmd, cfg);
2422
+ else
2423
+ ret = -EFAULT;
18672424 kfree(cfg);
18682425 break;
18692426 case RKMODULE_GET_HDR_CFG:
....@@ -1874,8 +2431,11 @@
18742431 }
18752432
18762433 ret = IMX464_ioctl(sd, cmd, hdr);
1877
- if (!ret)
2434
+ if (!ret) {
18782435 ret = copy_to_user(up, hdr, sizeof(*hdr));
2436
+ if (ret)
2437
+ ret = -EFAULT;
2438
+ }
18792439 kfree(hdr);
18802440 break;
18812441 case RKMODULE_SET_HDR_CFG:
....@@ -1888,6 +2448,8 @@
18882448 ret = copy_from_user(hdr, up, sizeof(*hdr));
18892449 if (!ret)
18902450 ret = IMX464_ioctl(sd, cmd, hdr);
2451
+ else
2452
+ ret = -EFAULT;
18912453 kfree(hdr);
18922454 break;
18932455 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1900,18 +2462,54 @@
19002462 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
19012463 if (!ret)
19022464 ret = IMX464_ioctl(sd, cmd, hdrae);
2465
+ else
2466
+ ret = -EFAULT;
19032467 kfree(hdrae);
19042468 break;
19052469 case RKMODULE_SET_CONVERSION_GAIN:
19062470 ret = copy_from_user(&cg, up, sizeof(cg));
19072471 if (!ret)
19082472 ret = IMX464_ioctl(sd, cmd, &cg);
2473
+ else
2474
+ ret = -EFAULT;
19092475 break;
19102476 case RKMODULE_SET_QUICK_STREAM:
19112477 ret = copy_from_user(&stream, up, sizeof(u32));
19122478 if (!ret)
19132479 ret = IMX464_ioctl(sd, cmd, &stream);
2480
+ else
2481
+ ret = -EFAULT;
19142482
2483
+ break;
2484
+ case RKMODULE_GET_CHANNEL_INFO:
2485
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2486
+ if (!ch_info) {
2487
+ ret = -ENOMEM;
2488
+ return ret;
2489
+ }
2490
+
2491
+ ret = IMX464_ioctl(sd, cmd, ch_info);
2492
+ if (!ret) {
2493
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2494
+ if (ret)
2495
+ ret = -EFAULT;
2496
+ }
2497
+ kfree(ch_info);
2498
+ break;
2499
+ case RKMODULE_GET_SYNC_MODE:
2500
+ ret = IMX464_ioctl(sd, cmd, &sync_mode);
2501
+ if (!ret) {
2502
+ ret = copy_to_user(up, &sync_mode, sizeof(u32));
2503
+ if (ret)
2504
+ ret = -EFAULT;
2505
+ }
2506
+ break;
2507
+ case RKMODULE_SET_SYNC_MODE:
2508
+ ret = copy_from_user(&sync_mode, up, sizeof(u32));
2509
+ if (!ret)
2510
+ ret = IMX464_ioctl(sd, cmd, &sync_mode);
2511
+ else
2512
+ ret = -EFAULT;
19152513 break;
19162514 default:
19172515 ret = -ENOIOCTLCMD;
....@@ -1922,17 +2520,20 @@
19222520 }
19232521 #endif
19242522
1925
-static int IMX464_init_conversion_gain(struct IMX464 *IMX464)
2523
+static int IMX464_init_conversion_gain(struct IMX464 *IMX464, bool isHCG)
19262524 {
1927
- int ret = 0;
19282525 struct i2c_client *client = IMX464->client;
2526
+ int ret = 0;
2527
+ u32 val = 0;
19292528
2529
+ if (isHCG)
2530
+ val = 0x01;
2531
+ else
2532
+ val = 0;
19302533 ret = imx464_write_reg(client,
19312534 IMX464_GAIN_SWITCH_REG,
19322535 IMX464_REG_VALUE_08BIT,
1933
- 0X00);
1934
- if (!ret)
1935
- g_isHCG = false;
2536
+ val);
19362537 return ret;
19372538 }
19382539
....@@ -1943,7 +2544,7 @@
19432544 ret = IMX464_write_array(IMX464->client, IMX464->cur_mode->reg_list);
19442545 if (ret)
19452546 return ret;
1946
- ret = IMX464_init_conversion_gain(IMX464);
2547
+ ret = IMX464_init_conversion_gain(IMX464, IMX464->isHCG);
19472548 if (ret)
19482549 return ret;
19492550 /* In case these controls are set before streaming */
....@@ -1959,18 +2560,43 @@
19592560 return ret;
19602561 }
19612562 }
1962
- imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
1963
- IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
1964
- usleep_range(30000, 40000);
1965
- return imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
1966
- IMX464_REG_VALUE_08BIT, 0);
2563
+
2564
+ if (IMX464->sync_mode == EXTERNAL_MASTER_MODE) {
2565
+ ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_start_regs);
2566
+ v4l2_err(&IMX464->subdev, "cur externam master mode\n");
2567
+ } else if (IMX464->sync_mode == INTERNAL_MASTER_MODE) {
2568
+ ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_start_regs);
2569
+ v4l2_err(&IMX464->subdev, "cur intertal master\n");
2570
+ } else if (IMX464->sync_mode == SLAVE_MODE) {
2571
+ ret |= IMX464_write_array(IMX464->client, IMX464_slave_start_regs);
2572
+ v4l2_err(&IMX464->subdev, "cur slave mode\n");
2573
+ }
2574
+ if (IMX464->sync_mode == NO_SYNC_MODE) {
2575
+ ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2576
+ IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
2577
+ usleep_range(30000, 40000);
2578
+ ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2579
+ IMX464_REG_VALUE_08BIT, 0);
2580
+ } else {
2581
+ ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2582
+ IMX464_REG_VALUE_08BIT, 0);
2583
+ }
2584
+ return ret;
19672585 }
19682586
19692587 static int __IMX464_stop_stream(struct IMX464 *IMX464)
19702588 {
2589
+ int ret = 0;
2590
+
19712591 IMX464->has_init_exp = false;
1972
- return imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
1973
- IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
2592
+ ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2593
+ IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
2594
+
2595
+ if (IMX464->sync_mode == EXTERNAL_MASTER_MODE)
2596
+ ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_stop_regs);
2597
+ else if (IMX464->sync_mode == INTERNAL_MASTER_MODE)
2598
+ ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_stop_regs);
2599
+ return ret;
19742600 }
19752601
19762602 static int IMX464_s_stream(struct v4l2_subdev *sd, int on)
....@@ -2059,7 +2685,6 @@
20592685 int ret;
20602686 u32 delay_us;
20612687 struct device *dev = &IMX464->client->dev;
2062
- unsigned long mclk = 0;
20632688
20642689 if (!IS_ERR_OR_NULL(IMX464->pins_default)) {
20652690 ret = pinctrl_select_state(IMX464->pinctrl,
....@@ -2067,15 +2692,14 @@
20672692 if (ret < 0)
20682693 dev_err(dev, "could not set pins\n");
20692694 }
2070
- if (IMX464->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10)
2071
- mclk = IMX464_XVCLK_FREQ_37M;
2072
- else
2073
- mclk = IMX464_XVCLK_FREQ_24M;
2074
- ret = clk_set_rate(IMX464->xvclk, mclk);
2695
+
2696
+ ret = clk_set_rate(IMX464->xvclk, IMX464->cur_mode->mclk);
20752697 if (ret < 0)
20762698 dev_warn(dev, "Failed to set xvclk rate\n");
2077
- if (clk_get_rate(IMX464->xvclk) != mclk)
2078
- dev_warn(dev, "xvclk mismatched\n");
2699
+ if (clk_get_rate(IMX464->xvclk) != IMX464->cur_mode->mclk)
2700
+ dev_warn(dev, "xvclk mismatched, %lu\n", clk_get_rate(IMX464->xvclk));
2701
+ else
2702
+ IMX464->cur_mclk = IMX464->cur_mode->mclk;
20792703 ret = clk_prepare_enable(IMX464->xvclk);
20802704 if (ret < 0) {
20812705 dev_err(dev, "Failed to enable xvclk\n");
....@@ -2089,7 +2713,7 @@
20892713 dev_err(dev, "Failed to enable regulators\n");
20902714 goto disable_clk;
20912715 }
2092
-
2716
+ usleep_range(15000, 16000);
20932717 if (!IS_ERR(IMX464->reset_gpio))
20942718 gpiod_set_value_cansleep(IMX464->reset_gpio, 1);
20952719
....@@ -2126,6 +2750,7 @@
21262750 dev_err(dev, "could not set pins\n");
21272751 }
21282752 regulator_bulk_disable(IMX464_NUM_SUPPLIES, IMX464->supplies);
2753
+ usleep_range(15000, 16000);
21292754 }
21302755
21312756 static int IMX464_runtime_resume(struct device *dev)
....@@ -2154,7 +2779,7 @@
21542779 struct IMX464 *IMX464 = to_IMX464(sd);
21552780 struct v4l2_mbus_framefmt *try_fmt =
21562781 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2157
- const struct IMX464_mode *def_mode = &supported_modes[0];
2782
+ const struct IMX464_mode *def_mode = &IMX464->support_modes[0];
21582783
21592784 mutex_lock(&IMX464->mutex);
21602785 /* Initialize try_fmt */
....@@ -2179,16 +2804,16 @@
21792804 if (fie->index >= IMX464->cfg_num)
21802805 return -EINVAL;
21812806
2182
- fie->code = supported_modes[fie->index].bus_fmt;
2183
- fie->width = supported_modes[fie->index].width;
2184
- fie->height = supported_modes[fie->index].height;
2185
- fie->interval = supported_modes[fie->index].max_fps;
2186
- fie->reserved[0] = supported_modes[fie->index].hdr_mode;
2807
+ fie->code = IMX464->support_modes[fie->index].bus_fmt;
2808
+ fie->width = IMX464->support_modes[fie->index].width;
2809
+ fie->height = IMX464->support_modes[fie->index].height;
2810
+ fie->interval = IMX464->support_modes[fie->index].max_fps;
2811
+ fie->reserved[0] = IMX464->support_modes[fie->index].hdr_mode;
21872812 return 0;
21882813 }
21892814
21902815 #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
2191
-#define DST_WIDTH 2688
2816
+#define DST_WIDTH 2560
21922817 #define DST_HEIGHT 1520
21932818
21942819 /*
....@@ -2238,7 +2863,6 @@
22382863 static const struct v4l2_subdev_video_ops IMX464_video_ops = {
22392864 .s_stream = IMX464_s_stream,
22402865 .g_frame_interval = IMX464_g_frame_interval,
2241
- .g_mbus_config = IMX464_g_mbus_config,
22422866 };
22432867
22442868 static const struct v4l2_subdev_pad_ops IMX464_pad_ops = {
....@@ -2248,6 +2872,7 @@
22482872 .get_fmt = IMX464_get_fmt,
22492873 .set_fmt = IMX464_set_fmt,
22502874 .get_selection = IMX464_get_selection,
2875
+ .get_mbus_config = IMX464_g_mbus_config,
22512876 };
22522877
22532878 static const struct v4l2_subdev_ops IMX464_subdev_ops = {
....@@ -2266,7 +2891,7 @@
22662891 u32 vts = 0;
22672892 int ret = 0;
22682893 u32 shr0 = 0;
2269
- //u32 flip = 0;
2894
+ u32 flip = 0;
22702895
22712896 /* Propagate change of current control to all related controls */
22722897 switch (ctrl->id) {
....@@ -2342,8 +2967,64 @@
23422967 vts);
23432968 break;
23442969 case V4L2_CID_HFLIP:
2970
+ ret = imx464_write_reg(client,
2971
+ IMX464_GROUP_HOLD_REG,
2972
+ IMX464_REG_VALUE_08BIT,
2973
+ IMX464_GROUP_HOLD_START);
2974
+ ret |= imx464_write_reg(IMX464->client, IMX464_HREVERSE_REG,
2975
+ IMX464_REG_VALUE_08BIT, !!ctrl->val);
2976
+ ret |= imx464_write_reg(client,
2977
+ IMX464_GROUP_HOLD_REG,
2978
+ IMX464_REG_VALUE_08BIT,
2979
+ IMX464_GROUP_HOLD_END);
23452980 break;
23462981 case V4L2_CID_VFLIP:
2982
+ flip = ctrl->val;
2983
+ ret = imx464_write_reg(client,
2984
+ IMX464_GROUP_HOLD_REG,
2985
+ IMX464_REG_VALUE_08BIT,
2986
+ IMX464_GROUP_HOLD_START);
2987
+ ret |= imx464_write_reg(IMX464->client, IMX464_VREVERSE_REG,
2988
+ IMX464_REG_VALUE_08BIT, !!flip);
2989
+ if (flip) {
2990
+ ret |= imx464_write_reg(IMX464->client, 0x3074,
2991
+ IMX464_REG_VALUE_08BIT, 0x40);
2992
+ ret |= imx464_write_reg(IMX464->client, 0x3075,
2993
+ IMX464_REG_VALUE_08BIT, 0x06);
2994
+ ret |= imx464_write_reg(IMX464->client, 0x3080,
2995
+ IMX464_REG_VALUE_08BIT, 0xff);
2996
+ ret |= imx464_write_reg(IMX464->client, 0x30ad,
2997
+ IMX464_REG_VALUE_08BIT, 0x7e);
2998
+ ret |= imx464_write_reg(IMX464->client, 0x30b6,
2999
+ IMX464_REG_VALUE_08BIT, 0xff);
3000
+ ret |= imx464_write_reg(IMX464->client, 0x30b7,
3001
+ IMX464_REG_VALUE_08BIT, 0x01);
3002
+ ret |= imx464_write_reg(IMX464->client, 0x30d8,
3003
+ IMX464_REG_VALUE_08BIT, 0x45);
3004
+ ret |= imx464_write_reg(IMX464->client, 0x3114,
3005
+ IMX464_REG_VALUE_08BIT, 0x01);
3006
+ } else {
3007
+ ret |= imx464_write_reg(IMX464->client, 0x3074,
3008
+ IMX464_REG_VALUE_08BIT, 0x3c);
3009
+ ret |= imx464_write_reg(IMX464->client, 0x3075,
3010
+ IMX464_REG_VALUE_08BIT, 0x00);
3011
+ ret |= imx464_write_reg(IMX464->client, 0x3080,
3012
+ IMX464_REG_VALUE_08BIT, 0x01);
3013
+ ret |= imx464_write_reg(IMX464->client, 0x30ad,
3014
+ IMX464_REG_VALUE_08BIT, 0x02);
3015
+ ret |= imx464_write_reg(IMX464->client, 0x30b6,
3016
+ IMX464_REG_VALUE_08BIT, 0x00);
3017
+ ret |= imx464_write_reg(IMX464->client, 0x30b7,
3018
+ IMX464_REG_VALUE_08BIT, 0x00);
3019
+ ret |= imx464_write_reg(IMX464->client, 0x30d8,
3020
+ IMX464_REG_VALUE_08BIT, 0x44);
3021
+ ret |= imx464_write_reg(IMX464->client, 0x3114,
3022
+ IMX464_REG_VALUE_08BIT, 0x02);
3023
+ }
3024
+ ret |= imx464_write_reg(client,
3025
+ IMX464_GROUP_HOLD_REG,
3026
+ IMX464_REG_VALUE_08BIT,
3027
+ IMX464_GROUP_HOLD_END);
23473028 break;
23483029 default:
23493030 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
....@@ -2366,6 +3047,7 @@
23663047 struct v4l2_ctrl_handler *handler;
23673048 s64 exposure_max, vblank_def;
23683049 u32 h_blank;
3050
+ u64 pixel_rate = 0;
23693051 int ret;
23703052
23713053 handler = &IMX464->ctrl_handler;
....@@ -2378,28 +3060,13 @@
23783060 IMX464->link_freq = v4l2_ctrl_new_int_menu(handler,
23793061 NULL, V4L2_CID_LINK_FREQ,
23803062 1, 0, link_freq_menu_items);
2381
- if (IMX464->cur_mode->bus_fmt == MEDIA_BUS_FMT_SRGGB10_1X10) {
2382
- IMX464->cur_link_freq = 1;
2383
- if (IMX464->cur_mode->hdr_mode == NO_HDR) {
2384
- IMX464->cur_pixel_rate =
2385
- IMX464_10BIT_LINEAR_PIXEL_RATE;
2386
- IMX464->cur_link_freq = 0;
2387
- } else if (IMX464->cur_mode->hdr_mode == HDR_X2)
2388
- IMX464->cur_pixel_rate =
2389
- IMX464_10BIT_HDR2_PIXEL_RATE;
2390
- else if (IMX464->cur_mode->hdr_mode == HDR_X3)
2391
- IMX464->cur_pixel_rate =
2392
- IMX464_10BIT_HDR3_PIXEL_RATE;
2393
- } else {
2394
- IMX464->cur_link_freq = 0;
2395
- IMX464->cur_pixel_rate =
2396
- IMX464_12BIT_PIXEL_RATE;
2397
- }
23983063 __v4l2_ctrl_s_ctrl(IMX464->link_freq,
2399
- IMX464->cur_link_freq);
3064
+ IMX464->cur_mode->mipi_freq_idx);
3065
+ pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
3066
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
24003067 IMX464->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
24013068 V4L2_CID_PIXEL_RATE, 0, IMX464_10BIT_HDR2_PIXEL_RATE,
2402
- 1, IMX464->cur_pixel_rate);
3069
+ 1, pixel_rate);
24033070
24043071 h_blank = mode->hts_def - mode->width;
24053072 IMX464->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
....@@ -2436,6 +3103,7 @@
24363103
24373104 IMX464->subdev.ctrl_handler = handler;
24383105 IMX464->has_init_exp = false;
3106
+ IMX464->isHCG = false;
24393107
24403108 return 0;
24413109
....@@ -2483,9 +3151,12 @@
24833151 struct device_node *node = dev->of_node;
24843152 struct IMX464 *IMX464;
24853153 struct v4l2_subdev *sd;
3154
+ struct device_node *endpoint;
24863155 char facing[2];
24873156 int ret;
24883157 u32 i, hdr_mode = 0;
3158
+ const char *sync_mode_name = NULL;
3159
+
24893160
24903161 dev_info(dev, "driver version: %02x.%02x.%02x",
24913162 DRIVER_VERSION >> 16,
....@@ -2509,6 +3180,20 @@
25093180 return -EINVAL;
25103181 }
25113182
3183
+ ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
3184
+ &sync_mode_name);
3185
+ if (ret) {
3186
+ IMX464->sync_mode = NO_SYNC_MODE;
3187
+ dev_err(dev, "could not get sync mode!\n");
3188
+ } else {
3189
+ if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0)
3190
+ IMX464->sync_mode = EXTERNAL_MASTER_MODE;
3191
+ else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0)
3192
+ IMX464->sync_mode = INTERNAL_MASTER_MODE;
3193
+ else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0)
3194
+ IMX464->sync_mode = SLAVE_MODE;
3195
+ }
3196
+
25123197 ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
25133198 &hdr_mode);
25143199 if (ret) {
....@@ -2516,15 +3201,32 @@
25163201 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
25173202 }
25183203 IMX464->client = client;
3204
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
3205
+ if (!endpoint) {
3206
+ dev_err(dev, "Failed to get endpoint\n");
3207
+ return -EINVAL;
3208
+ }
3209
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
3210
+ &IMX464->bus_cfg);
3211
+ if (ret) {
3212
+ dev_err(dev, "Failed to get bus cfg\n");
3213
+ return ret;
3214
+ }
3215
+ if (IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
3216
+ IMX464->support_modes = supported_modes;
3217
+ IMX464->cfg_num = ARRAY_SIZE(supported_modes);
3218
+ } else {
3219
+ IMX464->support_modes = supported_modes_2lane;
3220
+ IMX464->cfg_num = ARRAY_SIZE(supported_modes_2lane);
3221
+ }
25193222
2520
- IMX464->cfg_num = ARRAY_SIZE(supported_modes);
25213223 for (i = 0; i < IMX464->cfg_num; i++) {
2522
- if (hdr_mode == supported_modes[i].hdr_mode) {
2523
- IMX464->cur_mode = &supported_modes[i];
3224
+ if (hdr_mode == IMX464->support_modes[i].hdr_mode) {
3225
+ IMX464->cur_mode = &IMX464->support_modes[i];
25243226 break;
25253227 }
25263228 }
2527
- IMX464->cur_mode = &supported_modes[0];
3229
+ IMX464->cur_mode = &IMX464->support_modes[0];
25283230 IMX464->xvclk = devm_clk_get(dev, "xvclk");
25293231 if (IS_ERR(IMX464->xvclk)) {
25303232 dev_err(dev, "Failed to get xvclk\n");
....@@ -2610,7 +3312,6 @@
26103312 pm_runtime_enable(dev);
26113313 pm_runtime_idle(dev);
26123314
2613
- g_isHCG = false;
26143315 #ifdef USED_SYS_DEBUG
26153316 add_sysfs_interfaces(dev);
26163317 #endif
....@@ -2654,14 +3355,14 @@
26543355
26553356 #if IS_ENABLED(CONFIG_OF)
26563357 static const struct of_device_id IMX464_of_match[] = {
2657
- { .compatible = "sony,IMX464" },
3358
+ { .compatible = "sony,imx464" },
26583359 {},
26593360 };
26603361 MODULE_DEVICE_TABLE(of, IMX464_of_match);
26613362 #endif
26623363
26633364 static const struct i2c_device_id IMX464_match_id[] = {
2664
- { "sony,IMX464", 0 },
3365
+ { "sony,imx464", 0 },
26653366 { },
26663367 };
26673368