hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/drivers/media/i2c/imx464.c
....@@ -10,6 +10,7 @@
1010 * V0.0X01.0X03 support enum sensor fmt
1111 */
1212
13
+//#define DEBUG
1314 #include <linux/clk.h>
1415 #include <linux/device.h>
1516 #include <linux/delay.h>
....@@ -26,8 +27,11 @@
2627 #include <media/v4l2-async.h>
2728 #include <media/v4l2-ctrls.h>
2829 #include <media/v4l2-subdev.h>
30
+#include <media/v4l2-fwnode.h>
31
+#include <media/v4l2-mediabus.h>
2932 #include <linux/pinctrl/consumer.h>
3033 #include <linux/rk-preisp.h>
34
+#include <linux/of_graph.h>
3135
3236 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x03)
3337
....@@ -42,15 +46,12 @@
4246 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
4347
4448 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
45
-#define IMX464_10BIT_LINEAR_PIXEL_RATE (MIPI_FREQ_445M * 2 / 10 * 4)
4649 #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)
4950 #define IMX464_XVCLK_FREQ_37M 37125000
5051 #define IMX464_XVCLK_FREQ_24M 24000000
5152
52
-#define CHIP_ID 0x00
53
-#define IMX464_REG_CHIP_ID 0x0000
53
+#define CHIP_ID 0x06
54
+#define IMX464_REG_CHIP_ID 0x3057
5455
5556 #define IMX464_REG_CTRL_MODE 0x3000
5657 #define IMX464_MODE_SW_STANDBY BIT(0)
....@@ -133,8 +134,6 @@
133134 #define IMX464_REG_VALUE_16BIT 2
134135 #define IMX464_REG_VALUE_24BIT 3
135136
136
-#define IMX464_2LANES 2
137
-#define IMX464_4LANES 4
138137 #define IMX464_BITS_PER_SAMPLE 10
139138
140139 #define IMX464_VREVERSE_REG 0x304f
....@@ -150,12 +149,10 @@
150149
151150 #define USED_SYS_DEBUG
152151
153
-static bool g_isHCG;
154
-
155152 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
156153 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
157154
158
-#define IMX464_NAME "IMX464"
155
+#define IMX464_NAME "imx464"
159156
160157 static const char * const IMX464_supply_names[] = {
161158 "avdd", /* Analog power */
....@@ -165,17 +162,17 @@
165162
166163 #define IMX464_NUM_SUPPLIES ARRAY_SIZE(IMX464_supply_names)
167164
165
+struct regval {
166
+ u16 addr;
167
+ u8 val;
168
+};
169
+
168170 enum IMX464_max_pad {
169171 PAD0, /* link to isp */
170172 PAD1, /* link to csi wr0 | hdr x2:L x3:M */
171173 PAD2, /* link to csi wr1 | hdr x3:L */
172174 PAD3, /* link to csi wr2 | hdr x2:M x3:S */
173175 PAD_MAX,
174
-};
175
-
176
-struct regval {
177
- u16 addr;
178
- u8 val;
179176 };
180177
181178 struct IMX464_mode {
....@@ -186,6 +183,9 @@
186183 u32 hts_def;
187184 u32 vts_def;
188185 u32 exp_def;
186
+ u32 mipi_freq_idx;
187
+ u32 mclk;
188
+ u32 bpp;
189189 const struct regval *reg_list;
190190 u32 hdr_mode;
191191 u32 vc[PAD_MAX];
....@@ -213,19 +213,22 @@
213213 struct v4l2_ctrl *pixel_rate;
214214 struct v4l2_ctrl *link_freq;
215215 struct mutex mutex;
216
+ struct v4l2_fwnode_endpoint bus_cfg;
216217 bool streaming;
217218 bool power_on;
219
+ bool has_init_exp;
220
+ const struct IMX464_mode *support_modes;
218221 const struct IMX464_mode *cur_mode;
219222 u32 module_index;
220223 u32 cfg_num;
221
- u32 cur_pixel_rate;
222
- u32 cur_link_freq;
224
+ u32 cur_vts;
225
+ u32 cur_mclk;
223226 const char *module_facing;
224227 const char *module_name;
225228 const char *len_name;
226
- u32 cur_vts;
227
- bool has_init_exp;
229
+ enum rkmodule_sync_mode sync_mode;
228230 struct preisp_hdrae_exp_s init_hdrae_exp;
231
+ bool isHCG;
229232 };
230233
231234 #define to_IMX464(sd) container_of(sd, struct IMX464, subdev)
....@@ -237,16 +240,16 @@
237240 {REG_NULL, 0x00},
238241 };
239242
240
-static const struct regval IMX464_linear_10bit_2688x1520_regs[] = {
243
+static __maybe_unused const struct regval IMX464_linear_10bit_2688x1520_2lane_37m_regs[] = {
241244 {0x3000, 0x01},
242245 {0x3002, 0x01},
243246 {0x300C, 0x5B},
244247 {0x300D, 0x40},
245
- {0x3030, 0xE4},
246
- {0x3031, 0x0C},
248
+ {0x3034, 0xDC},
249
+ {0x3035, 0x05},
247250 {0x3050, 0x00},
248
- {0x3058, 0x06},
249
- {0x3059, 0x09},
251
+ {0x3058, 0x83},
252
+ {0x3059, 0x04},
250253 {0x30BE, 0x5E},
251254 {0x30E8, 0x14},
252255 {0x3110, 0x02},
....@@ -256,6 +259,488 @@
256259 {0x319D, 0x00},
257260 {0x319E, 0x02},
258261 {0x31A1, 0x00},
262
+ {0x3288, 0x22},
263
+ {0x328A, 0x02},
264
+ {0x328C, 0xA2},
265
+ {0x328E, 0x22},
266
+ {0x3415, 0x27},
267
+ {0x3418, 0x27},
268
+ {0x3428, 0xFE},
269
+ {0x349E, 0x6A},
270
+ {0x34A2, 0x9A},
271
+ {0x34A4, 0x8A},
272
+ {0x34A6, 0x8E},
273
+ {0x34AA, 0xD8},
274
+ {0x35BC, 0x00},
275
+ {0x35BE, 0xFF},
276
+ {0x35CC, 0x1B},
277
+ {0x35CD, 0x00},
278
+ {0x35CE, 0x2A},
279
+ {0x35CF, 0x00},
280
+ {0x35DC, 0x07},
281
+ {0x35DE, 0x1A},
282
+ {0x35DF, 0x00},
283
+ {0x35E4, 0x2B},
284
+ {0x35E5, 0x00},
285
+ {0x35E6, 0x07},
286
+ {0x35E7, 0x01},
287
+ {0x3648, 0x01},
288
+ {0x3678, 0x01},
289
+ {0x367C, 0x69},
290
+ {0x367E, 0x69},
291
+ {0x3680, 0x69},
292
+ {0x3682, 0x69},
293
+ {0x3718, 0x1C},
294
+ {0x371D, 0x05},
295
+ {0x375D, 0x11},
296
+ {0x375E, 0x43},
297
+ {0x375F, 0x76},
298
+ {0x3760, 0x07},
299
+ {0x3768, 0x1B},
300
+ {0x3769, 0x1B},
301
+ {0x376A, 0x1A},
302
+ {0x376B, 0x19},
303
+ {0x376C, 0x17},
304
+ {0x376D, 0x0F},
305
+ {0x376E, 0x0B},
306
+ {0x376F, 0x0B},
307
+ {0x3770, 0x0B},
308
+ {0x3776, 0x89},
309
+ {0x3777, 0x00},
310
+ {0x3778, 0xCA},
311
+ {0x3779, 0x00},
312
+ {0x377A, 0x45},
313
+ {0x377B, 0x01},
314
+ {0x377C, 0x56},
315
+ {0x377D, 0x02},
316
+ {0x377E, 0xFE},
317
+ {0x377F, 0x03},
318
+ {0x3780, 0xFE},
319
+ {0x3781, 0x05},
320
+ {0x3782, 0xFE},
321
+ {0x3783, 0x06},
322
+ {0x3784, 0x7F},
323
+ {0x3788, 0x1F},
324
+ {0x378A, 0xCA},
325
+ {0x378B, 0x00},
326
+ {0x378C, 0x45},
327
+ {0x378D, 0x01},
328
+ {0x378E, 0x56},
329
+ {0x378F, 0x02},
330
+ {0x3790, 0xFE},
331
+ {0x3791, 0x03},
332
+ {0x3792, 0xFE},
333
+ {0x3793, 0x05},
334
+ {0x3794, 0xFE},
335
+ {0x3795, 0x06},
336
+ {0x3796, 0x7F},
337
+ {0x3798, 0xBF},
338
+ {0x3A01, 0x01},
339
+ {0x3A18, 0x7F},
340
+ {0x3A1A, 0x37},
341
+ {0x3A1C, 0x37},
342
+ {0x3A1E, 0xF7},
343
+ {0x3A1F, 0x00},
344
+ {0x3A20, 0x3F},
345
+ {0x3A22, 0x6F},
346
+ {0x3A24, 0x3F},
347
+ {0x3A26, 0x5F},
348
+ {0x3A28, 0x2F},
349
+ {REG_NULL, 0x00},
350
+};
351
+
352
+static __maybe_unused const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_37m_regs[] = {
353
+ {0x3000, 0x01},
354
+ {0x3002, 0x01},
355
+ {0x300C, 0x5B},
356
+ {0x300D, 0x40},
357
+ {0x3034, 0xDC},
358
+ {0x3035, 0x05},
359
+ {0x3048, 0x01},
360
+ {0x3049, 0x01},
361
+ {0x304A, 0x01},
362
+ {0x304B, 0x01},
363
+ {0x304C, 0x13},
364
+ {0x304D, 0x00},
365
+ {0x3050, 0x00},
366
+ {0x3058, 0xF4},
367
+ {0x3059, 0x0A},
368
+ {0x3068, 0x3D},
369
+ {0x30BE, 0x5E},
370
+ {0x30E8, 0x0A},
371
+ {0x3110, 0x02},
372
+ {0x314C, 0x80},//
373
+ {0x315A, 0x02},
374
+ {0x316A, 0x7E},
375
+ {0x319D, 0x00},
376
+ {0x319E, 0x01},//1188M
377
+ {0x31A1, 0x00},
378
+ {0x31D7, 0x01},
379
+ {0x3200, 0x10},
380
+ {0x3288, 0x22},
381
+ {0x328A, 0x02},
382
+ {0x328C, 0xA2},
383
+ {0x328E, 0x22},
384
+ {0x3415, 0x27},
385
+ {0x3418, 0x27},
386
+ {0x3428, 0xFE},
387
+ {0x349E, 0x6A},
388
+ {0x34A2, 0x9A},
389
+ {0x34A4, 0x8A},
390
+ {0x34A6, 0x8E},
391
+ {0x34AA, 0xD8},
392
+ {0x35BC, 0x00},
393
+ {0x35BE, 0xFF},
394
+ {0x35CC, 0x1B},
395
+ {0x35CD, 0x00},
396
+ {0x35CE, 0x2A},
397
+ {0x35CF, 0x00},
398
+ {0x35DC, 0x07},
399
+ {0x35DE, 0x1A},
400
+ {0x35DF, 0x00},
401
+ {0x35E4, 0x2B},
402
+ {0x35E5, 0x00},
403
+ {0x35E6, 0x07},
404
+ {0x35E7, 0x01},
405
+ {0x3648, 0x01},
406
+ {0x3678, 0x01},
407
+ {0x367C, 0x69},
408
+ {0x367E, 0x69},
409
+ {0x3680, 0x69},
410
+ {0x3682, 0x69},
411
+ {0x3718, 0x1C},
412
+ {0x371D, 0x05},
413
+ {0x375D, 0x11},
414
+ {0x375E, 0x43},
415
+ {0x375F, 0x76},
416
+ {0x3760, 0x07},
417
+ {0x3768, 0x1B},
418
+ {0x3769, 0x1B},
419
+ {0x376A, 0x1A},
420
+ {0x376B, 0x19},
421
+ {0x376C, 0x17},
422
+ {0x376D, 0x0F},
423
+ {0x376E, 0x0B},
424
+ {0x376F, 0x0B},
425
+ {0x3770, 0x0B},
426
+ {0x3776, 0x89},
427
+ {0x3777, 0x00},
428
+ {0x3778, 0xCA},
429
+ {0x3779, 0x00},
430
+ {0x377A, 0x45},
431
+ {0x377B, 0x01},
432
+ {0x377C, 0x56},
433
+ {0x377D, 0x02},
434
+ {0x377E, 0xFE},
435
+ {0x377F, 0x03},
436
+ {0x3780, 0xFE},
437
+ {0x3781, 0x05},
438
+ {0x3782, 0xFE},
439
+ {0x3783, 0x06},
440
+ {0x3784, 0x7F},
441
+ {0x3788, 0x1F},
442
+ {0x378A, 0xCA},
443
+ {0x378B, 0x00},
444
+ {0x378C, 0x45},
445
+ {0x378D, 0x01},
446
+ {0x378E, 0x56},
447
+ {0x378F, 0x02},
448
+ {0x3790, 0xFE},
449
+ {0x3791, 0x03},
450
+ {0x3792, 0xFE},
451
+ {0x3793, 0x05},
452
+ {0x3794, 0xFE},
453
+ {0x3795, 0x06},
454
+ {0x3796, 0x7F},
455
+ {0x3798, 0xBF},
456
+ {0x3A01, 0x01},
457
+ {0x3A18, 0x8F},
458
+ {0x3A1A, 0x4F},
459
+ {0x3A1C, 0x47},
460
+ {0x3A1E, 0x37},
461
+ {0x3A1F, 0x01},
462
+ {0x3A20, 0x4F},
463
+ {0x3A22, 0x87},
464
+ {0x3A24, 0x4F},
465
+ {0x3A26, 0x7F},
466
+ {0x3A28, 0x3F},
467
+ {REG_NULL, 0x00},
468
+};
469
+
470
+static const struct regval IMX464_linear_10bit_2688x1520_2lane_regs[] = {
471
+ {0x3000, 0x01},
472
+ {0x3002, 0x01},
473
+ {0x300C, 0x3b},
474
+ {0x300D, 0x2a},
475
+ {0x3034, 0xDC},
476
+ {0x3035, 0x05},
477
+ {0x3048, 0x00},
478
+ {0x3049, 0x00},
479
+ {0x304A, 0x03},
480
+ {0x304B, 0x02},
481
+ {0x304C, 0x14},
482
+ {0x304D, 0x03},
483
+ {0x3050, 0x00},
484
+ {0x3058, 0x83},
485
+ {0x3059, 0x04},
486
+ {0x3068, 0xc9},
487
+ {0x30BE, 0x5E},
488
+ {0x30E8, 0x14},
489
+ {0x3110, 0x02},
490
+ {0x314C, 0x29},
491
+ {0x314D, 0x01},
492
+ {0x315A, 0x06},
493
+ {0x3168, 0xA0},
494
+ {0x316A, 0x7E},
495
+ {0x319D, 0x00},
496
+ {0x319E, 0x02},
497
+ {0x31A1, 0x00},
498
+ {0x31D7, 0x00},
499
+ {0x3200, 0x11},
500
+ {0x3288, 0x22},
501
+ {0x328A, 0x02},
502
+ {0x328C, 0xA2},
503
+ {0x328E, 0x22},
504
+ {0x3415, 0x27},
505
+ {0x3418, 0x27},
506
+ {0x3428, 0xFE},
507
+ {0x349E, 0x6A},
508
+ {0x34A2, 0x9A},
509
+ {0x34A4, 0x8A},
510
+ {0x34A6, 0x8E},
511
+ {0x34AA, 0xD8},
512
+ {0x35BC, 0x00},
513
+ {0x35BE, 0xFF},
514
+ {0x35CC, 0x1B},
515
+ {0x35CD, 0x00},
516
+ {0x35CE, 0x2A},
517
+ {0x35CF, 0x00},
518
+ {0x35DC, 0x07},
519
+ {0x35DE, 0x1A},
520
+ {0x35DF, 0x00},
521
+ {0x35E4, 0x2B},
522
+ {0x35E5, 0x00},
523
+ {0x35E6, 0x07},
524
+ {0x35E7, 0x01},
525
+ {0x3648, 0x01},
526
+ {0x3678, 0x01},
527
+ {0x367C, 0x69},
528
+ {0x367E, 0x69},
529
+ {0x3680, 0x69},
530
+ {0x3682, 0x69},
531
+ {0x3718, 0x1C},
532
+ {0x371D, 0x05},
533
+ {0x375D, 0x11},
534
+ {0x375E, 0x43},
535
+ {0x375F, 0x76},
536
+ {0x3760, 0x07},
537
+ {0x3768, 0x1B},
538
+ {0x3769, 0x1B},
539
+ {0x376A, 0x1A},
540
+ {0x376B, 0x19},
541
+ {0x376C, 0x17},
542
+ {0x376D, 0x0F},
543
+ {0x376E, 0x0B},
544
+ {0x376F, 0x0B},
545
+ {0x3770, 0x0B},
546
+ {0x3776, 0x89},
547
+ {0x3777, 0x00},
548
+ {0x3778, 0xCA},
549
+ {0x3779, 0x00},
550
+ {0x377A, 0x45},
551
+ {0x377B, 0x01},
552
+ {0x377C, 0x56},
553
+ {0x377D, 0x02},
554
+ {0x377E, 0xFE},
555
+ {0x377F, 0x03},
556
+ {0x3780, 0xFE},
557
+ {0x3781, 0x05},
558
+ {0x3782, 0xFE},
559
+ {0x3783, 0x06},
560
+ {0x3784, 0x7F},
561
+ {0x3788, 0x1F},
562
+ {0x378A, 0xCA},
563
+ {0x378B, 0x00},
564
+ {0x378C, 0x45},
565
+ {0x378D, 0x01},
566
+ {0x378E, 0x56},
567
+ {0x378F, 0x02},
568
+ {0x3790, 0xFE},
569
+ {0x3791, 0x03},
570
+ {0x3792, 0xFE},
571
+ {0x3793, 0x05},
572
+ {0x3794, 0xFE},
573
+ {0x3795, 0x06},
574
+ {0x3796, 0x7F},
575
+ {0x3798, 0xBF},
576
+ {0x3A01, 0x01},
577
+ {0x3A18, 0x7F},
578
+ {0x3A1A, 0x37},
579
+ {0x3A1C, 0x37},
580
+ {0x3A1E, 0xF7},
581
+ {0x3A1F, 0x00},
582
+ {0x3A20, 0x3F},
583
+ {0x3A22, 0x6F},
584
+ {0x3A24, 0x3F},
585
+ {0x3A26, 0x5F},
586
+ {0x3A28, 0x2F},
587
+ {REG_NULL, 0x00},
588
+};
589
+
590
+static const struct regval IMX464_hdr_2x_10bit_2688x1520_2lane_regs[] = {
591
+ {0x3000, 0x01},
592
+ {0x3002, 0x01},
593
+ {0x300C, 0x3B},
594
+ {0x300D, 0x2A},
595
+ {0x3034, 0xDC},
596
+ {0x3035, 0x05},
597
+ {0x3048, 0x01},
598
+ {0x3049, 0x01},
599
+ {0x304A, 0x04},
600
+ {0x304B, 0x04},
601
+ {0x304C, 0x13},
602
+ {0x304D, 0x00},
603
+ {0x3050, 0x00},
604
+ {0x3058, 0xF4},
605
+ {0x3059, 0x0A},
606
+ {0x3068, 0x3D},
607
+ {0x30BE, 0x5E},
608
+ {0x30E8, 0x14},
609
+ {0x3110, 0x02},
610
+ {0x314C, 0x29},//
611
+ {0x314D, 0x01},//
612
+ {0x315A, 0x06},
613
+ {0x3168, 0xA0},
614
+ {0x316A, 0x7E},
615
+ {0x319D, 0x00},
616
+ {0x319E, 0x02},//1188M
617
+ {0x31A1, 0x00},
618
+ {0x31D7, 0x01},
619
+ {0x3200, 0x10},
620
+ {0x3288, 0x22},
621
+ {0x328A, 0x02},
622
+ {0x328C, 0xA2},
623
+ {0x328E, 0x22},
624
+ {0x3415, 0x27},
625
+ {0x3418, 0x27},
626
+ {0x3428, 0xFE},
627
+ {0x349E, 0x6A},
628
+ {0x34A2, 0x9A},
629
+ {0x34A4, 0x8A},
630
+ {0x34A6, 0x8E},
631
+ {0x34AA, 0xD8},
632
+ {0x35BC, 0x00},
633
+ {0x35BE, 0xFF},
634
+ {0x35CC, 0x1B},
635
+ {0x35CD, 0x00},
636
+ {0x35CE, 0x2A},
637
+ {0x35CF, 0x00},
638
+ {0x35DC, 0x07},
639
+ {0x35DE, 0x1A},
640
+ {0x35DF, 0x00},
641
+ {0x35E4, 0x2B},
642
+ {0x35E5, 0x00},
643
+ {0x35E6, 0x07},
644
+ {0x35E7, 0x01},
645
+ {0x3648, 0x01},
646
+ {0x3678, 0x01},
647
+ {0x367C, 0x69},
648
+ {0x367E, 0x69},
649
+ {0x3680, 0x69},
650
+ {0x3682, 0x69},
651
+ {0x3718, 0x1C},
652
+ {0x371D, 0x05},
653
+ {0x375D, 0x11},
654
+ {0x375E, 0x43},
655
+ {0x375F, 0x76},
656
+ {0x3760, 0x07},
657
+ {0x3768, 0x1B},
658
+ {0x3769, 0x1B},
659
+ {0x376A, 0x1A},
660
+ {0x376B, 0x19},
661
+ {0x376C, 0x17},
662
+ {0x376D, 0x0F},
663
+ {0x376E, 0x0B},
664
+ {0x376F, 0x0B},
665
+ {0x3770, 0x0B},
666
+ {0x3776, 0x89},
667
+ {0x3777, 0x00},
668
+ {0x3778, 0xCA},
669
+ {0x3779, 0x00},
670
+ {0x377A, 0x45},
671
+ {0x377B, 0x01},
672
+ {0x377C, 0x56},
673
+ {0x377D, 0x02},
674
+ {0x377E, 0xFE},
675
+ {0x377F, 0x03},
676
+ {0x3780, 0xFE},
677
+ {0x3781, 0x05},
678
+ {0x3782, 0xFE},
679
+ {0x3783, 0x06},
680
+ {0x3784, 0x7F},
681
+ {0x3788, 0x1F},
682
+ {0x378A, 0xCA},
683
+ {0x378B, 0x00},
684
+ {0x378C, 0x45},
685
+ {0x378D, 0x01},
686
+ {0x378E, 0x56},
687
+ {0x378F, 0x02},
688
+ {0x3790, 0xFE},
689
+ {0x3791, 0x03},
690
+ {0x3792, 0xFE},
691
+ {0x3793, 0x05},
692
+ {0x3794, 0xFE},
693
+ {0x3795, 0x06},
694
+ {0x3796, 0x7F},
695
+ {0x3798, 0xBF},
696
+ {0x3A01, 0x01},
697
+ {0x3A18, 0x7F},
698
+ {0x3A1A, 0x37},
699
+ {0x3A1C, 0x37},
700
+ {0x3A1E, 0xF7},
701
+ {0x3A1F, 0x00},
702
+ {0x3A20, 0x3F},
703
+ {0x3A22, 0x6F},
704
+ {0x3A24, 0x3F},
705
+ {0x3A26, 0x5F},
706
+ {0x3A28, 0x2F},
707
+ {REG_NULL, 0x00},
708
+};
709
+
710
+static const struct regval IMX464_linear_10bit_2688x1520_regs[] = {
711
+ {0x3000, 0x01},
712
+ {0x3002, 0x01},
713
+ {0x300C, 0x5B},
714
+ {0x300D, 0x40},
715
+ {0x3030, 0xE4},
716
+ {0x3031, 0x0C},
717
+ {0x3034, 0xee},
718
+ {0x3035, 0x02},
719
+ {0x3048, 0x00},
720
+ {0x3049, 0x00},
721
+ {0x304A, 0x03},
722
+ {0x304B, 0x02},
723
+ {0x304C, 0x14},
724
+ {0x3050, 0x00},
725
+ {0x3058, 0x06},
726
+ {0x3059, 0x09},
727
+ {0x305C, 0x09},
728
+ {0x3060, 0x21},
729
+ {0x3061, 0x01},
730
+ {0x3068, 0xc9},
731
+ {0x306C, 0x56},
732
+ {0x306D, 0x09},
733
+ {0x30BE, 0x5E},
734
+ {0x30E8, 0x14},
735
+ {0x3110, 0x02},
736
+ {0x314C, 0xC0},
737
+ {0x315A, 0x06},
738
+ {0x316A, 0x7E},
739
+ {0x319D, 0x00},
740
+ {0x319E, 0x02},
741
+ {0x31A1, 0x00},
742
+ {0x31D7, 0x00},
743
+ {0x3200, 0x11},
259744 {0x3288, 0x22},
260745 {0x328A, 0x02},
261746 {0x328C, 0xA2},
....@@ -350,6 +835,10 @@
350835 {0x3002, 0x01},
351836 {0x300C, 0x5B},
352837 {0x300D, 0x40},
838
+ {0x3030, 0x72},
839
+ {0x3031, 0x06},
840
+ {0x3034, 0xee},
841
+ {0x3035, 0x02},
353842 {0x3048, 0x01},
354843 {0x3049, 0x01},
355844 {0x304A, 0x04},
....@@ -358,7 +847,12 @@
358847 {0x3050, 0x00},
359848 {0x3058, 0x06},
360849 {0x3059, 0x09},
850
+ {0x305C, 0x09},
851
+ {0x3060, 0x21},
852
+ {0x3061, 0x01},
361853 {0x3068, 0x6D},
854
+ {0x306C, 0x56},
855
+ {0x306D, 0x09},
362856 {0x30BE, 0x5E},
363857 {0x30E8, 0x14},
364858 {0x3110, 0x02},
....@@ -498,6 +992,7 @@
498992 {0x319E, 0x01},
499993 {0x31A1, 0x00},
500994 {0x31D7, 0x03},
995
+ {0x3200, 0x10},
501996 {0x3288, 0x22},
502997 {0x328A, 0x02},
503998 {0x328C, 0xA2},
....@@ -584,7 +1079,6 @@
5841079 {0x3A24, 0x4F},
5851080 {0x3A26, 0x5F},
5861081 {0x3A28, 0x3F},
587
- {0x3200, 0x10},
5881082 {REG_NULL, 0x00},
5891083 };
5901084
....@@ -824,6 +1318,33 @@
8241318 {REG_NULL, 0x00},
8251319 };
8261320
1321
+static __maybe_unused const struct regval IMX464_interal_sync_master_start_regs[] = {
1322
+ {0x3010, 0x07},
1323
+ {0x31a1, 0x00},
1324
+ {REG_NULL, 0x00},
1325
+};
1326
+static __maybe_unused const struct regval IMX464_interal_sync_master_stop_regs[] = {
1327
+ {0x31a1, 0x0f},
1328
+ {REG_NULL, 0x00},
1329
+};
1330
+
1331
+static __maybe_unused const struct regval IMX464_external_sync_master_start_regs[] = {
1332
+ {0x3010, 0x05},
1333
+ {0x31a1, 0x03},
1334
+ {0x31d9, 0x01},
1335
+ {REG_NULL, 0x00},
1336
+};
1337
+static __maybe_unused const struct regval IMX464_external_sync_master_stop_regs[] = {
1338
+ {0x31a1, 0x0f},
1339
+ {REG_NULL, 0x00},
1340
+};
1341
+
1342
+static __maybe_unused const struct regval IMX464_slave_start_regs[] = {
1343
+ {0x3010, 0x05},
1344
+ {0x31a1, 0x0f},
1345
+ {REG_NULL, 0x00},
1346
+};
1347
+
8271348 /*
8281349 * The width and height must be configured to be
8291350 * the same as the current output resolution of the sensor.
....@@ -848,6 +1369,9 @@
8481369 .exp_def = 0x0906,
8491370 .hts_def = 0x05dc * 2,
8501371 .vts_def = 0x0ce4,
1372
+ .mipi_freq_idx = 0,
1373
+ .bpp = 10,
1374
+ .mclk = 37125000,
8511375 .reg_list = IMX464_linear_10bit_2688x1520_regs,
8521376 .hdr_mode = NO_HDR,
8531377 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
....@@ -863,6 +1387,9 @@
8631387 .exp_def = 0x03de,
8641388 .hts_def = 0x02ee * 4,
8651389 .vts_def = 0x0672 * 2,
1390
+ .mipi_freq_idx = 1,
1391
+ .bpp = 10,
1392
+ .mclk = 37125000,
8661393 .reg_list = IMX464_hdr_2x_10bit_2688x1520_regs,
8671394 .hdr_mode = HDR_X2,
8681395 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
....@@ -889,12 +1416,57 @@
8891416 #else
8901417 .vts_def = 0x04D1 * 4,
8911418 #endif
1419
+ .mipi_freq_idx = 1,
1420
+ .bpp = 10,
1421
+ .mclk = 37125000,
8921422 .reg_list = IMX464_hdr_3x_10bit_2688x1520_regs,
8931423 .hdr_mode = HDR_X3,
8941424 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
8951425 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
8961426 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr1
8971427 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
1428
+ },
1429
+};
1430
+
1431
+static const struct IMX464_mode supported_modes_2lane[] = {
1432
+ {
1433
+ .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1434
+ .width = 2712,
1435
+ .height = 1538,
1436
+ .max_fps = {
1437
+ .numerator = 10000,
1438
+ .denominator = 300000,
1439
+ },
1440
+ .exp_def = 0x0600,
1441
+ .hts_def = 0x05dc * 2,
1442
+ .vts_def = 0x672,
1443
+ .mipi_freq_idx = 0,
1444
+ .bpp = 10,
1445
+ .mclk = 24000000,
1446
+ .reg_list = IMX464_linear_10bit_2688x1520_2lane_regs,
1447
+ .hdr_mode = NO_HDR,
1448
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
1449
+ },
1450
+ {
1451
+ .bus_fmt = MEDIA_BUS_FMT_SRGGB10_1X10,
1452
+ .width = 2712,
1453
+ .height = 1538,
1454
+ .max_fps = {
1455
+ .numerator = 10000,
1456
+ .denominator = 150000,
1457
+ },
1458
+ .exp_def = 0x0600,
1459
+ .hts_def = 0x05dc * 4,
1460
+ .vts_def = 0x0672 * 2,
1461
+ .mipi_freq_idx = 0,
1462
+ .bpp = 10,
1463
+ .mclk = 24000000,
1464
+ .reg_list = IMX464_hdr_2x_10bit_2688x1520_2lane_regs,
1465
+ .hdr_mode = HDR_X2,
1466
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
1467
+ .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
1468
+ .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
1469
+ .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
8981470 },
8991471 };
9001472
....@@ -997,15 +1569,15 @@
9971569 unsigned int i;
9981570
9991571 for (i = 0; i < IMX464->cfg_num; i++) {
1000
- dist = IMX464_get_reso_dist(&supported_modes[i], framefmt);
1572
+ dist = IMX464_get_reso_dist(&IMX464->support_modes[i], framefmt);
10011573 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
1002
- supported_modes[i].bus_fmt == framefmt->code) {
1574
+ IMX464->support_modes[i].bus_fmt == framefmt->code) {
10031575 cur_best_fit_dist = dist;
10041576 cur_best_fit = i;
10051577 }
10061578 }
10071579
1008
- return &supported_modes[cur_best_fit];
1580
+ return &IMX464->support_modes[cur_best_fit];
10091581 }
10101582
10111583 static int IMX464_set_fmt(struct v4l2_subdev *sd,
....@@ -1015,8 +1587,7 @@
10151587 struct IMX464 *IMX464 = to_IMX464(sd);
10161588 const struct IMX464_mode *mode;
10171589 s64 h_blank, vblank_def;
1018
- struct device *dev = &IMX464->client->dev;
1019
- int ret = 0;
1590
+ u64 pixel_rate = 0;
10201591
10211592 mutex_lock(&IMX464->mutex);
10221593
....@@ -1042,42 +1613,12 @@
10421613 IMX464_VTS_MAX - mode->height,
10431614 1, vblank_def);
10441615 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
- }
1616
+ pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
1617
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
10771618 __v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
1078
- IMX464->cur_pixel_rate);
1619
+ pixel_rate);
10791620 __v4l2_ctrl_s_ctrl(IMX464->link_freq,
1080
- IMX464->cur_link_freq);
1621
+ mode->mipi_freq_idx);
10811622 }
10821623
10831624 mutex_unlock(&IMX464->mutex);
....@@ -1137,13 +1678,13 @@
11371678 if (fse->index >= IMX464->cfg_num)
11381679 return -EINVAL;
11391680
1140
- if (fse->code != supported_modes[fse->index].bus_fmt)
1681
+ if (fse->code != IMX464->support_modes[fse->index].bus_fmt)
11411682 return -EINVAL;
11421683
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;
1684
+ fse->min_width = IMX464->support_modes[fse->index].width;
1685
+ fse->max_width = IMX464->support_modes[fse->index].width;
1686
+ fse->max_height = IMX464->support_modes[fse->index].height;
1687
+ fse->min_height = IMX464->support_modes[fse->index].height;
11471688
11481689 return 0;
11491690 }
....@@ -1167,19 +1708,20 @@
11671708 struct IMX464 *IMX464 = to_IMX464(sd);
11681709 const struct IMX464_mode *mode = IMX464->cur_mode;
11691710 u32 val = 0;
1711
+ u32 lane_num = IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
11701712
11711713 if (mode->hdr_mode == NO_HDR) {
1172
- val = 1 << (IMX464_4LANES - 1) |
1714
+ val = 1 << (lane_num - 1) |
11731715 V4L2_MBUS_CSI2_CHANNEL_0 |
11741716 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
11751717 }
11761718 if (mode->hdr_mode == HDR_X2)
1177
- val = 1 << (IMX464_4LANES - 1) |
1719
+ val = 1 << (lane_num - 1) |
11781720 V4L2_MBUS_CSI2_CHANNEL_0 |
11791721 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
11801722 V4L2_MBUS_CSI2_CHANNEL_1;
11811723 if (mode->hdr_mode == HDR_X3)
1182
- val = 1 << (IMX464_4LANES - 1) |
1724
+ val = 1 << (lane_num - 1) |
11831725 V4L2_MBUS_CSI2_CHANNEL_0 |
11841726 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
11851727 V4L2_MBUS_CSI2_CHANNEL_1 |
....@@ -1241,12 +1783,12 @@
12411783 l_exp_time = m_exp_time;
12421784 cg_mode = ae->middle_cg_mode;
12431785 }
1244
- if (!g_isHCG && cg_mode == GAIN_MODE_HCG) {
1786
+ if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
12451787 gain_switch = 0x01 | 0x100;
1246
- g_isHCG = true;
1247
- } else if (g_isHCG && cg_mode == GAIN_MODE_LCG) {
1788
+ IMX464->isHCG = true;
1789
+ } else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
12481790 gain_switch = 0x00 | 0x100;
1249
- g_isHCG = false;
1791
+ IMX464->isHCG = false;
12501792 }
12511793 ret = imx464_write_reg(client,
12521794 IMX464_GROUP_HOLD_REG,
....@@ -1428,12 +1970,12 @@
14281970 //3 stagger
14291971 cg_mode = ae->long_cg_mode;
14301972 }
1431
- if (!g_isHCG && cg_mode == GAIN_MODE_HCG) {
1973
+ if (!IMX464->isHCG && cg_mode == GAIN_MODE_HCG) {
14321974 gain_switch = 0x01 | 0x100;
1433
- g_isHCG = true;
1434
- } else if (g_isHCG && cg_mode == GAIN_MODE_LCG) {
1975
+ IMX464->isHCG = true;
1976
+ } else if (IMX464->isHCG && cg_mode == GAIN_MODE_LCG) {
14351977 gain_switch = 0x00 | 0x100;
1436
- g_isHCG = false;
1978
+ IMX464->isHCG = false;
14371979 }
14381980
14391981 dev_dbg(&client->dev,
....@@ -1670,12 +2212,12 @@
16702212 int cur_cg = *cg;
16712213 u32 gain_switch = 0;
16722214
1673
- if (g_isHCG && cur_cg == GAIN_MODE_LCG) {
2215
+ if (IMX464->isHCG && cur_cg == GAIN_MODE_LCG) {
16742216 gain_switch = 0x00 | 0x100;
1675
- g_isHCG = false;
1676
- } else if (!g_isHCG && cur_cg == GAIN_MODE_HCG) {
2217
+ IMX464->isHCG = false;
2218
+ } else if (!IMX464->isHCG && cur_cg == GAIN_MODE_HCG) {
16772219 gain_switch = 0x01 | 0x100;
1678
- g_isHCG = true;
2220
+ IMX464->isHCG = true;
16792221 }
16802222 ret = imx464_write_reg(client,
16812223 IMX464_GROUP_HOLD_REG,
....@@ -1743,12 +2285,26 @@
17432285 }
17442286 #endif
17452287
2288
+static int IMX464_get_channel_info(struct IMX464 *IMX464, struct rkmodule_channel_info *ch_info)
2289
+{
2290
+ if (ch_info->index >= PAD_MAX)
2291
+ return -EINVAL;
2292
+ ch_info->vc = IMX464->cur_mode->vc[ch_info->index];
2293
+ ch_info->width = IMX464->cur_mode->width;
2294
+ ch_info->height = IMX464->cur_mode->height;
2295
+ ch_info->bus_fmt = IMX464->cur_mode->bus_fmt;
2296
+ return 0;
2297
+}
2298
+
17462299 static long IMX464_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
17472300 {
17482301 struct IMX464 *IMX464 = to_IMX464(sd);
17492302 struct rkmodule_hdr_cfg *hdr;
2303
+ struct rkmodule_channel_info *ch_info;
17502304 u32 i, h, w, stream;
17512305 long ret = 0;
2306
+ u64 pixel_rate = 0;
2307
+ u32 *sync_mode = NULL;
17522308
17532309 switch (cmd) {
17542310 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1770,10 +2326,10 @@
17702326 w = IMX464->cur_mode->width;
17712327 h = IMX464->cur_mode->height;
17722328 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];
2329
+ if (w == IMX464->support_modes[i].width &&
2330
+ h == IMX464->support_modes[i].height &&
2331
+ IMX464->support_modes[i].hdr_mode == hdr->hdr_mode) {
2332
+ IMX464->cur_mode = &IMX464->support_modes[i];
17772333 break;
17782334 }
17792335 }
....@@ -1790,16 +2346,13 @@
17902346 IMX464_VTS_MAX - IMX464->cur_mode->height,
17912347 1, h);
17922348 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
- }
2349
+ pixel_rate = (u32)link_freq_menu_items[IMX464->cur_mode->mipi_freq_idx] /
2350
+ IMX464->cur_mode->bpp * 2 *
2351
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
2352
+ __v4l2_ctrl_s_ctrl_int64(IMX464->pixel_rate,
2353
+ pixel_rate);
2354
+ __v4l2_ctrl_s_ctrl(IMX464->link_freq,
2355
+ IMX464->cur_mode->mipi_freq_idx);
18032356 }
18042357 break;
18052358 case RKMODULE_SET_CONVERSION_GAIN:
....@@ -1809,16 +2362,25 @@
18092362
18102363 stream = *((u32 *)arg);
18112364
1812
- if (stream) {
2365
+ if (stream)
18132366 ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
18142367 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 {
2368
+ else
18192369 ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
18202370 IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
1821
- }
2371
+
2372
+ break;
2373
+ case RKMODULE_GET_CHANNEL_INFO:
2374
+ ch_info = (struct rkmodule_channel_info *)arg;
2375
+ ret = IMX464_get_channel_info(IMX464, ch_info);
2376
+ break;
2377
+ case RKMODULE_GET_SYNC_MODE:
2378
+ sync_mode = (u32 *)arg;
2379
+ *sync_mode = IMX464->sync_mode;
2380
+ break;
2381
+ case RKMODULE_SET_SYNC_MODE:
2382
+ sync_mode = (u32 *)arg;
2383
+ IMX464->sync_mode = *sync_mode;
18222384 break;
18232385 default:
18242386 ret = -ENOIOCTLCMD;
....@@ -1837,9 +2399,11 @@
18372399 struct rkmodule_awb_cfg *cfg;
18382400 struct rkmodule_hdr_cfg *hdr;
18392401 struct preisp_hdrae_exp_s *hdrae;
2402
+ struct rkmodule_channel_info *ch_info;
18402403 long ret;
18412404 u32 cg = 0;
18422405 u32 stream;
2406
+ u32 sync_mode;
18432407
18442408 switch (cmd) {
18452409 case RKMODULE_GET_MODULE_INFO:
....@@ -1850,8 +2414,11 @@
18502414 }
18512415
18522416 ret = IMX464_ioctl(sd, cmd, inf);
1853
- if (!ret)
2417
+ if (!ret) {
18542418 ret = copy_to_user(up, inf, sizeof(*inf));
2419
+ if (ret)
2420
+ ret = -EFAULT;
2421
+ }
18552422 kfree(inf);
18562423 break;
18572424 case RKMODULE_AWB_CFG:
....@@ -1864,6 +2431,8 @@
18642431 ret = copy_from_user(cfg, up, sizeof(*cfg));
18652432 if (!ret)
18662433 ret = IMX464_ioctl(sd, cmd, cfg);
2434
+ else
2435
+ ret = -EFAULT;
18672436 kfree(cfg);
18682437 break;
18692438 case RKMODULE_GET_HDR_CFG:
....@@ -1874,8 +2443,11 @@
18742443 }
18752444
18762445 ret = IMX464_ioctl(sd, cmd, hdr);
1877
- if (!ret)
2446
+ if (!ret) {
18782447 ret = copy_to_user(up, hdr, sizeof(*hdr));
2448
+ if (ret)
2449
+ ret = -EFAULT;
2450
+ }
18792451 kfree(hdr);
18802452 break;
18812453 case RKMODULE_SET_HDR_CFG:
....@@ -1888,6 +2460,8 @@
18882460 ret = copy_from_user(hdr, up, sizeof(*hdr));
18892461 if (!ret)
18902462 ret = IMX464_ioctl(sd, cmd, hdr);
2463
+ else
2464
+ ret = -EFAULT;
18912465 kfree(hdr);
18922466 break;
18932467 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1900,18 +2474,54 @@
19002474 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
19012475 if (!ret)
19022476 ret = IMX464_ioctl(sd, cmd, hdrae);
2477
+ else
2478
+ ret = -EFAULT;
19032479 kfree(hdrae);
19042480 break;
19052481 case RKMODULE_SET_CONVERSION_GAIN:
19062482 ret = copy_from_user(&cg, up, sizeof(cg));
19072483 if (!ret)
19082484 ret = IMX464_ioctl(sd, cmd, &cg);
2485
+ else
2486
+ ret = -EFAULT;
19092487 break;
19102488 case RKMODULE_SET_QUICK_STREAM:
19112489 ret = copy_from_user(&stream, up, sizeof(u32));
19122490 if (!ret)
19132491 ret = IMX464_ioctl(sd, cmd, &stream);
2492
+ else
2493
+ ret = -EFAULT;
19142494
2495
+ break;
2496
+ case RKMODULE_GET_CHANNEL_INFO:
2497
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2498
+ if (!ch_info) {
2499
+ ret = -ENOMEM;
2500
+ return ret;
2501
+ }
2502
+
2503
+ ret = IMX464_ioctl(sd, cmd, ch_info);
2504
+ if (!ret) {
2505
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2506
+ if (ret)
2507
+ ret = -EFAULT;
2508
+ }
2509
+ kfree(ch_info);
2510
+ break;
2511
+ case RKMODULE_GET_SYNC_MODE:
2512
+ ret = IMX464_ioctl(sd, cmd, &sync_mode);
2513
+ if (!ret) {
2514
+ ret = copy_to_user(up, &sync_mode, sizeof(u32));
2515
+ if (ret)
2516
+ ret = -EFAULT;
2517
+ }
2518
+ break;
2519
+ case RKMODULE_SET_SYNC_MODE:
2520
+ ret = copy_from_user(&sync_mode, up, sizeof(u32));
2521
+ if (!ret)
2522
+ ret = IMX464_ioctl(sd, cmd, &sync_mode);
2523
+ else
2524
+ ret = -EFAULT;
19152525 break;
19162526 default:
19172527 ret = -ENOIOCTLCMD;
....@@ -1922,17 +2532,20 @@
19222532 }
19232533 #endif
19242534
1925
-static int IMX464_init_conversion_gain(struct IMX464 *IMX464)
2535
+static int IMX464_init_conversion_gain(struct IMX464 *IMX464, bool isHCG)
19262536 {
1927
- int ret = 0;
19282537 struct i2c_client *client = IMX464->client;
2538
+ int ret = 0;
2539
+ u32 val = 0;
19292540
2541
+ if (isHCG)
2542
+ val = 0x01;
2543
+ else
2544
+ val = 0;
19302545 ret = imx464_write_reg(client,
19312546 IMX464_GAIN_SWITCH_REG,
19322547 IMX464_REG_VALUE_08BIT,
1933
- 0X00);
1934
- if (!ret)
1935
- g_isHCG = false;
2548
+ val);
19362549 return ret;
19372550 }
19382551
....@@ -1943,7 +2556,7 @@
19432556 ret = IMX464_write_array(IMX464->client, IMX464->cur_mode->reg_list);
19442557 if (ret)
19452558 return ret;
1946
- ret = IMX464_init_conversion_gain(IMX464);
2559
+ ret = IMX464_init_conversion_gain(IMX464, IMX464->isHCG);
19472560 if (ret)
19482561 return ret;
19492562 /* In case these controls are set before streaming */
....@@ -1959,18 +2572,43 @@
19592572 return ret;
19602573 }
19612574 }
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);
2575
+
2576
+ if (IMX464->sync_mode == EXTERNAL_MASTER_MODE) {
2577
+ ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_start_regs);
2578
+ v4l2_err(&IMX464->subdev, "cur externam master mode\n");
2579
+ } else if (IMX464->sync_mode == INTERNAL_MASTER_MODE) {
2580
+ ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_start_regs);
2581
+ v4l2_err(&IMX464->subdev, "cur intertal master\n");
2582
+ } else if (IMX464->sync_mode == SLAVE_MODE) {
2583
+ ret |= IMX464_write_array(IMX464->client, IMX464_slave_start_regs);
2584
+ v4l2_err(&IMX464->subdev, "cur slave mode\n");
2585
+ }
2586
+ if (IMX464->sync_mode == NO_SYNC_MODE) {
2587
+ ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2588
+ IMX464_REG_VALUE_08BIT, IMX464_MODE_STREAMING);
2589
+ usleep_range(30000, 40000);
2590
+ ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2591
+ IMX464_REG_VALUE_08BIT, 0);
2592
+ } else {
2593
+ ret |= imx464_write_reg(IMX464->client, IMX464_REG_MARSTER_MODE,
2594
+ IMX464_REG_VALUE_08BIT, 0);
2595
+ }
2596
+ return ret;
19672597 }
19682598
19692599 static int __IMX464_stop_stream(struct IMX464 *IMX464)
19702600 {
2601
+ int ret = 0;
2602
+
19712603 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);
2604
+ ret = imx464_write_reg(IMX464->client, IMX464_REG_CTRL_MODE,
2605
+ IMX464_REG_VALUE_08BIT, IMX464_MODE_SW_STANDBY);
2606
+
2607
+ if (IMX464->sync_mode == EXTERNAL_MASTER_MODE)
2608
+ ret |= IMX464_write_array(IMX464->client, IMX464_external_sync_master_stop_regs);
2609
+ else if (IMX464->sync_mode == INTERNAL_MASTER_MODE)
2610
+ ret |= IMX464_write_array(IMX464->client, IMX464_interal_sync_master_stop_regs);
2611
+ return ret;
19742612 }
19752613
19762614 static int IMX464_s_stream(struct v4l2_subdev *sd, int on)
....@@ -2059,7 +2697,6 @@
20592697 int ret;
20602698 u32 delay_us;
20612699 struct device *dev = &IMX464->client->dev;
2062
- unsigned long mclk = 0;
20632700
20642701 if (!IS_ERR_OR_NULL(IMX464->pins_default)) {
20652702 ret = pinctrl_select_state(IMX464->pinctrl,
....@@ -2067,15 +2704,14 @@
20672704 if (ret < 0)
20682705 dev_err(dev, "could not set pins\n");
20692706 }
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);
2707
+
2708
+ ret = clk_set_rate(IMX464->xvclk, IMX464->cur_mode->mclk);
20752709 if (ret < 0)
20762710 dev_warn(dev, "Failed to set xvclk rate\n");
2077
- if (clk_get_rate(IMX464->xvclk) != mclk)
2078
- dev_warn(dev, "xvclk mismatched\n");
2711
+ if (clk_get_rate(IMX464->xvclk) != IMX464->cur_mode->mclk)
2712
+ dev_warn(dev, "xvclk mismatched, %lu\n", clk_get_rate(IMX464->xvclk));
2713
+ else
2714
+ IMX464->cur_mclk = IMX464->cur_mode->mclk;
20792715 ret = clk_prepare_enable(IMX464->xvclk);
20802716 if (ret < 0) {
20812717 dev_err(dev, "Failed to enable xvclk\n");
....@@ -2089,7 +2725,7 @@
20892725 dev_err(dev, "Failed to enable regulators\n");
20902726 goto disable_clk;
20912727 }
2092
-
2728
+ usleep_range(15000, 16000);
20932729 if (!IS_ERR(IMX464->reset_gpio))
20942730 gpiod_set_value_cansleep(IMX464->reset_gpio, 1);
20952731
....@@ -2126,6 +2762,7 @@
21262762 dev_err(dev, "could not set pins\n");
21272763 }
21282764 regulator_bulk_disable(IMX464_NUM_SUPPLIES, IMX464->supplies);
2765
+ usleep_range(15000, 16000);
21292766 }
21302767
21312768 static int IMX464_runtime_resume(struct device *dev)
....@@ -2154,7 +2791,7 @@
21542791 struct IMX464 *IMX464 = to_IMX464(sd);
21552792 struct v4l2_mbus_framefmt *try_fmt =
21562793 v4l2_subdev_get_try_format(sd, fh->pad, 0);
2157
- const struct IMX464_mode *def_mode = &supported_modes[0];
2794
+ const struct IMX464_mode *def_mode = &IMX464->support_modes[0];
21582795
21592796 mutex_lock(&IMX464->mutex);
21602797 /* Initialize try_fmt */
....@@ -2179,16 +2816,16 @@
21792816 if (fie->index >= IMX464->cfg_num)
21802817 return -EINVAL;
21812818
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;
2819
+ fie->code = IMX464->support_modes[fie->index].bus_fmt;
2820
+ fie->width = IMX464->support_modes[fie->index].width;
2821
+ fie->height = IMX464->support_modes[fie->index].height;
2822
+ fie->interval = IMX464->support_modes[fie->index].max_fps;
2823
+ fie->reserved[0] = IMX464->support_modes[fie->index].hdr_mode;
21872824 return 0;
21882825 }
21892826
21902827 #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
2191
-#define DST_WIDTH 2688
2828
+#define DST_WIDTH 2560
21922829 #define DST_HEIGHT 1520
21932830
21942831 /*
....@@ -2266,7 +2903,7 @@
22662903 u32 vts = 0;
22672904 int ret = 0;
22682905 u32 shr0 = 0;
2269
- //u32 flip = 0;
2906
+ u32 flip = 0;
22702907
22712908 /* Propagate change of current control to all related controls */
22722909 switch (ctrl->id) {
....@@ -2298,7 +2935,7 @@
22982935 ret |= imx464_write_reg(IMX464->client, IMX464_LF_EXPO_REG_H,
22992936 IMX464_REG_VALUE_08BIT,
23002937 IMX464_FETCH_EXP_H(shr0));
2301
- dev_err(&client->dev, "set exposure 0x%x\n",
2938
+ dev_dbg(&client->dev, "set exposure 0x%x\n",
23022939 ctrl->val);
23032940 }
23042941 break;
....@@ -2310,7 +2947,7 @@
23102947 ret |= imx464_write_reg(IMX464->client, IMX464_LF_GAIN_REG_L,
23112948 IMX464_REG_VALUE_08BIT,
23122949 IMX464_FETCH_GAIN_L(ctrl->val));
2313
- dev_err(&client->dev, "set analog gain 0x%x\n",
2950
+ dev_dbg(&client->dev, "set analog gain 0x%x\n",
23142951 ctrl->val);
23152952 }
23162953 break;
....@@ -2338,12 +2975,67 @@
23382975 IMX464_REG_VALUE_08BIT,
23392976 IMX464_FETCH_VTS_H(vts));
23402977
2341
- dev_err(&client->dev, "set vts 0x%x\n",
2342
- vts);
2978
+ dev_dbg(&client->dev, "set vts 0x%x\n", vts);
23432979 break;
23442980 case V4L2_CID_HFLIP:
2981
+ ret = imx464_write_reg(client,
2982
+ IMX464_GROUP_HOLD_REG,
2983
+ IMX464_REG_VALUE_08BIT,
2984
+ IMX464_GROUP_HOLD_START);
2985
+ ret |= imx464_write_reg(IMX464->client, IMX464_HREVERSE_REG,
2986
+ IMX464_REG_VALUE_08BIT, !!ctrl->val);
2987
+ ret |= imx464_write_reg(client,
2988
+ IMX464_GROUP_HOLD_REG,
2989
+ IMX464_REG_VALUE_08BIT,
2990
+ IMX464_GROUP_HOLD_END);
23452991 break;
23462992 case V4L2_CID_VFLIP:
2993
+ flip = ctrl->val;
2994
+ ret = imx464_write_reg(client,
2995
+ IMX464_GROUP_HOLD_REG,
2996
+ IMX464_REG_VALUE_08BIT,
2997
+ IMX464_GROUP_HOLD_START);
2998
+ ret |= imx464_write_reg(IMX464->client, IMX464_VREVERSE_REG,
2999
+ IMX464_REG_VALUE_08BIT, !!flip);
3000
+ if (flip) {
3001
+ ret |= imx464_write_reg(IMX464->client, 0x3074,
3002
+ IMX464_REG_VALUE_08BIT, 0x40);
3003
+ ret |= imx464_write_reg(IMX464->client, 0x3075,
3004
+ IMX464_REG_VALUE_08BIT, 0x06);
3005
+ ret |= imx464_write_reg(IMX464->client, 0x3080,
3006
+ IMX464_REG_VALUE_08BIT, 0xff);
3007
+ ret |= imx464_write_reg(IMX464->client, 0x30ad,
3008
+ IMX464_REG_VALUE_08BIT, 0x7e);
3009
+ ret |= imx464_write_reg(IMX464->client, 0x30b6,
3010
+ IMX464_REG_VALUE_08BIT, 0xff);
3011
+ ret |= imx464_write_reg(IMX464->client, 0x30b7,
3012
+ IMX464_REG_VALUE_08BIT, 0x01);
3013
+ ret |= imx464_write_reg(IMX464->client, 0x30d8,
3014
+ IMX464_REG_VALUE_08BIT, 0x45);
3015
+ ret |= imx464_write_reg(IMX464->client, 0x3114,
3016
+ IMX464_REG_VALUE_08BIT, 0x01);
3017
+ } else {
3018
+ ret |= imx464_write_reg(IMX464->client, 0x3074,
3019
+ IMX464_REG_VALUE_08BIT, 0x3c);
3020
+ ret |= imx464_write_reg(IMX464->client, 0x3075,
3021
+ IMX464_REG_VALUE_08BIT, 0x00);
3022
+ ret |= imx464_write_reg(IMX464->client, 0x3080,
3023
+ IMX464_REG_VALUE_08BIT, 0x01);
3024
+ ret |= imx464_write_reg(IMX464->client, 0x30ad,
3025
+ IMX464_REG_VALUE_08BIT, 0x02);
3026
+ ret |= imx464_write_reg(IMX464->client, 0x30b6,
3027
+ IMX464_REG_VALUE_08BIT, 0x00);
3028
+ ret |= imx464_write_reg(IMX464->client, 0x30b7,
3029
+ IMX464_REG_VALUE_08BIT, 0x00);
3030
+ ret |= imx464_write_reg(IMX464->client, 0x30d8,
3031
+ IMX464_REG_VALUE_08BIT, 0x44);
3032
+ ret |= imx464_write_reg(IMX464->client, 0x3114,
3033
+ IMX464_REG_VALUE_08BIT, 0x02);
3034
+ }
3035
+ ret |= imx464_write_reg(client,
3036
+ IMX464_GROUP_HOLD_REG,
3037
+ IMX464_REG_VALUE_08BIT,
3038
+ IMX464_GROUP_HOLD_END);
23473039 break;
23483040 default:
23493041 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
....@@ -2366,6 +3058,7 @@
23663058 struct v4l2_ctrl_handler *handler;
23673059 s64 exposure_max, vblank_def;
23683060 u32 h_blank;
3061
+ u64 pixel_rate = 0;
23693062 int ret;
23703063
23713064 handler = &IMX464->ctrl_handler;
....@@ -2378,28 +3071,13 @@
23783071 IMX464->link_freq = v4l2_ctrl_new_int_menu(handler,
23793072 NULL, V4L2_CID_LINK_FREQ,
23803073 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
- }
23983074 __v4l2_ctrl_s_ctrl(IMX464->link_freq,
2399
- IMX464->cur_link_freq);
3075
+ IMX464->cur_mode->mipi_freq_idx);
3076
+ pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] / mode->bpp * 2 *
3077
+ IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes;
24003078 IMX464->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
24013079 V4L2_CID_PIXEL_RATE, 0, IMX464_10BIT_HDR2_PIXEL_RATE,
2402
- 1, IMX464->cur_pixel_rate);
3080
+ 1, pixel_rate);
24033081
24043082 h_blank = mode->hts_def - mode->width;
24053083 IMX464->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
....@@ -2436,6 +3114,7 @@
24363114
24373115 IMX464->subdev.ctrl_handler = handler;
24383116 IMX464->has_init_exp = false;
3117
+ IMX464->isHCG = false;
24393118
24403119 return 0;
24413120
....@@ -2483,9 +3162,12 @@
24833162 struct device_node *node = dev->of_node;
24843163 struct IMX464 *IMX464;
24853164 struct v4l2_subdev *sd;
3165
+ struct device_node *endpoint;
24863166 char facing[2];
24873167 int ret;
24883168 u32 i, hdr_mode = 0;
3169
+ const char *sync_mode_name = NULL;
3170
+
24893171
24903172 dev_info(dev, "driver version: %02x.%02x.%02x",
24913173 DRIVER_VERSION >> 16,
....@@ -2509,6 +3191,20 @@
25093191 return -EINVAL;
25103192 }
25113193
3194
+ ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
3195
+ &sync_mode_name);
3196
+ if (ret) {
3197
+ IMX464->sync_mode = NO_SYNC_MODE;
3198
+ dev_err(dev, "could not get sync mode!\n");
3199
+ } else {
3200
+ if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0)
3201
+ IMX464->sync_mode = EXTERNAL_MASTER_MODE;
3202
+ else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0)
3203
+ IMX464->sync_mode = INTERNAL_MASTER_MODE;
3204
+ else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0)
3205
+ IMX464->sync_mode = SLAVE_MODE;
3206
+ }
3207
+
25123208 ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
25133209 &hdr_mode);
25143210 if (ret) {
....@@ -2516,15 +3212,32 @@
25163212 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
25173213 }
25183214 IMX464->client = client;
3215
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
3216
+ if (!endpoint) {
3217
+ dev_err(dev, "Failed to get endpoint\n");
3218
+ return -EINVAL;
3219
+ }
3220
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
3221
+ &IMX464->bus_cfg);
3222
+ if (ret) {
3223
+ dev_err(dev, "Failed to get bus cfg\n");
3224
+ return ret;
3225
+ }
3226
+ if (IMX464->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
3227
+ IMX464->support_modes = supported_modes;
3228
+ IMX464->cfg_num = ARRAY_SIZE(supported_modes);
3229
+ } else {
3230
+ IMX464->support_modes = supported_modes_2lane;
3231
+ IMX464->cfg_num = ARRAY_SIZE(supported_modes_2lane);
3232
+ }
25193233
2520
- IMX464->cfg_num = ARRAY_SIZE(supported_modes);
25213234 for (i = 0; i < IMX464->cfg_num; i++) {
2522
- if (hdr_mode == supported_modes[i].hdr_mode) {
2523
- IMX464->cur_mode = &supported_modes[i];
3235
+ if (hdr_mode == IMX464->support_modes[i].hdr_mode) {
3236
+ IMX464->cur_mode = &IMX464->support_modes[i];
25243237 break;
25253238 }
25263239 }
2527
- IMX464->cur_mode = &supported_modes[0];
3240
+ IMX464->cur_mode = &IMX464->support_modes[0];
25283241 IMX464->xvclk = devm_clk_get(dev, "xvclk");
25293242 if (IS_ERR(IMX464->xvclk)) {
25303243 dev_err(dev, "Failed to get xvclk\n");
....@@ -2610,7 +3323,6 @@
26103323 pm_runtime_enable(dev);
26113324 pm_runtime_idle(dev);
26123325
2613
- g_isHCG = false;
26143326 #ifdef USED_SYS_DEBUG
26153327 add_sysfs_interfaces(dev);
26163328 #endif
....@@ -2655,6 +3367,7 @@
26553367 #if IS_ENABLED(CONFIG_OF)
26563368 static const struct of_device_id IMX464_of_match[] = {
26573369 { .compatible = "sony,IMX464" },
3370
+ { .compatible = "sony,imx464" },
26583371 {},
26593372 };
26603373 MODULE_DEVICE_TABLE(of, IMX464_of_match);
....@@ -2662,6 +3375,7 @@
26623375
26633376 static const struct i2c_device_id IMX464_match_id[] = {
26643377 { "sony,IMX464", 0 },
3378
+ { "sony,imx464", 0 },
26653379 { },
26663380 };
26673381