@@ -43,6 +43,9 @@ MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink");
43
43
44
44
#define IMX477_REG_ORIENTATION 0x101
45
45
46
+ #define IMX477_REG_CSI_DT_FMT_H 0x0112
47
+ #define IMX477_REG_CSI_DT_FMT_L 0x0113
48
+
46
49
#define IMX477_XCLK_FREQ 24000000
47
50
48
51
#define IMX477_DEFAULT_LINK_FREQ 450000000
@@ -86,6 +89,7 @@ MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink");
86
89
#define IMX477_DGTL_GAIN_DEFAULT 0x0100
87
90
#define IMX477_DGTL_GAIN_STEP 1
88
91
92
+ #define IMX477_REG_IOP_PXCK_DIV 0x0309
89
93
#define IMX477_REG_DIV_IOP_PX 0x030b
90
94
91
95
/* Test Pattern Control */
@@ -153,8 +157,11 @@ struct imx477_mode {
153
157
/* Frame height */
154
158
unsigned int height ;
155
159
156
- /* H-timing in pixels when at 450MHz link freq */
157
- unsigned int line_length_pix ;
160
+ /*
161
+ * H-timing in pixels when at 450MHz link freq
162
+ * Index 0 is for 12bpp. Index 1 is for 10bpp.
163
+ */
164
+ unsigned int line_length_pix [2 ];
158
165
159
166
/* Analog crop rectangle. */
160
167
struct v4l2_rect crop ;
@@ -529,8 +536,6 @@ static const struct imx477_reg mode_common_regs[] = {
529
536
530
537
/* 12 mpix 10fps */
531
538
static const struct imx477_reg mode_4056x3040_regs [] = {
532
- {0x0112 , 0x0c },
533
- {0x0113 , 0x0c },
534
539
{0x0344 , 0x00 },
535
540
{0x0345 , 0x00 },
536
541
{0x0346 , 0x00 },
@@ -585,7 +590,6 @@ static const struct imx477_reg mode_4056x3040_regs[] = {
585
590
{0x0305 , 0x04 },
586
591
{0x0306 , 0x01 },
587
592
{0x0307 , 0x5e },
588
- {0x0309 , 0x0c },
589
593
{0xe04c , 0x00 },
590
594
{0xe04d , 0x7f },
591
595
{0xe04e , 0x00 },
@@ -660,8 +664,6 @@ static const struct imx477_reg mode_4056x2160_regs[] = {
660
664
661
665
/* 2x2 binned. 40fps */
662
666
static const struct imx477_reg mode_2028x1520_regs [] = {
663
- {0x0112 , 0x0c },
664
- {0x0113 , 0x0c },
665
667
{0x0344 , 0x00 },
666
668
{0x0345 , 0x00 },
667
669
{0x0346 , 0x00 },
@@ -705,7 +707,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
705
707
{0x0305 , 0x04 },
706
708
{0x0306 , 0x01 },
707
709
{0x0307 , 0x5e },
708
- {0x0309 , 0x0c },
709
710
{0xe04c , 0x00 },
710
711
{0xe04d , 0x7f },
711
712
{0xe04e , 0x00 },
@@ -716,8 +717,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
716
717
717
718
/* 1080p cropped mode */
718
719
static const struct imx477_reg mode_2028x1080_regs [] = {
719
- {0x0112 , 0x0c },
720
- {0x0113 , 0x0c },
721
720
{0x0344 , 0x00 },
722
721
{0x0345 , 0x00 },
723
722
{0x0346 , 0x01 },
@@ -761,7 +760,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
761
760
{0x0305 , 0x04 },
762
761
{0x0306 , 0x01 },
763
762
{0x0307 , 0x5e },
764
- {0x0309 , 0x0c },
765
763
{0xe04c , 0x00 },
766
764
{0xe04d , 0x7f },
767
765
{0xe04e , 0x00 },
@@ -772,8 +770,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
772
770
773
771
/* 4x4 binned. 120fps */
774
772
static const struct imx477_reg mode_1332x990_regs [] = {
775
- {0x0112 , 0x0a },
776
- {0x0113 , 0x0a },
777
773
{0x420b , 0x01 },
778
774
{0x990c , 0x00 },
779
775
{0x990d , 0x08 },
@@ -841,7 +837,6 @@ static const struct imx477_reg mode_1332x990_regs[] = {
841
837
{0x0305 , 0x02 },
842
838
{0x0306 , 0x00 },
843
839
{0x0307 , 0xaf },
844
- {0x0309 , 0x0a },
845
840
{0xe04c , 0x00 },
846
841
{0xe04d , 0x5f },
847
842
{0xe04e , 0x00 },
@@ -851,12 +846,12 @@ static const struct imx477_reg mode_1332x990_regs[] = {
851
846
};
852
847
853
848
/* Mode configs */
854
- static const struct imx477_mode supported_modes_12bit [] = {
849
+ static const struct imx477_mode supported_modes [] = {
855
850
{
856
851
/* 12MPix 10fps mode */
857
852
.width = 4056 ,
858
853
.height = 3040 ,
859
- .line_length_pix = 24000 ,
854
+ .line_length_pix = { 24000 , 20000 } ,
860
855
.crop = {
861
856
.left = IMX477_PIXEL_ARRAY_LEFT ,
862
857
.top = IMX477_PIXEL_ARRAY_TOP ,
@@ -890,7 +885,7 @@ static const struct imx477_mode supported_modes_12bit[] = {
890
885
/* 2x2 binned 40fps mode */
891
886
.width = 2028 ,
892
887
.height = 1520 ,
893
- .line_length_pix = 12740 ,
888
+ .line_length_pix = { 12740 , 10616 } ,
894
889
.crop = {
895
890
.left = IMX477_PIXEL_ARRAY_LEFT ,
896
891
.top = IMX477_PIXEL_ARRAY_TOP ,
@@ -907,7 +902,7 @@ static const struct imx477_mode supported_modes_12bit[] = {
907
902
/* 1080p 50fps cropped mode */
908
903
.width = 2028 ,
909
904
.height = 1080 ,
910
- .line_length_pix = 12740 ,
905
+ .line_length_pix = { 12740 , 10616 } ,
911
906
.crop = {
912
907
.left = IMX477_PIXEL_ARRAY_LEFT ,
913
908
.top = IMX477_PIXEL_ARRAY_TOP + 440 ,
@@ -919,15 +914,12 @@ static const struct imx477_mode supported_modes_12bit[] = {
919
914
.num_of_regs = ARRAY_SIZE (mode_2028x1080_regs ),
920
915
.regs = mode_2028x1080_regs ,
921
916
},
922
- }
923
- };
924
-
925
- static const struct imx477_mode supported_modes_10bit [] = {
917
+ },
926
918
{
927
919
/* 120fps. 2x2 binned and cropped */
928
920
.width = 1332 ,
929
921
.height = 990 ,
930
- .line_length_pix = 6664 ,
922
+ .line_length_pix = { 7997 , 6664 } ,
931
923
.crop = {
932
924
/*
933
925
* FIXME: the analog crop rectangle is actually
@@ -1077,33 +1069,6 @@ static inline struct imx477 *to_imx477(struct v4l2_subdev *_sd)
1077
1069
return container_of (_sd , struct imx477 , sd );
1078
1070
}
1079
1071
1080
- static inline void get_mode_table (unsigned int code ,
1081
- const struct imx477_mode * * mode_list ,
1082
- unsigned int * num_modes )
1083
- {
1084
- switch (code ) {
1085
- /* 12-bit */
1086
- case MEDIA_BUS_FMT_SRGGB12_1X12 :
1087
- case MEDIA_BUS_FMT_SGRBG12_1X12 :
1088
- case MEDIA_BUS_FMT_SGBRG12_1X12 :
1089
- case MEDIA_BUS_FMT_SBGGR12_1X12 :
1090
- * mode_list = supported_modes_12bit ;
1091
- * num_modes = ARRAY_SIZE (supported_modes_12bit );
1092
- break ;
1093
- /* 10-bit */
1094
- case MEDIA_BUS_FMT_SRGGB10_1X10 :
1095
- case MEDIA_BUS_FMT_SGRBG10_1X10 :
1096
- case MEDIA_BUS_FMT_SGBRG10_1X10 :
1097
- case MEDIA_BUS_FMT_SBGGR10_1X10 :
1098
- * mode_list = supported_modes_10bit ;
1099
- * num_modes = ARRAY_SIZE (supported_modes_10bit );
1100
- break ;
1101
- default :
1102
- * mode_list = NULL ;
1103
- * num_modes = 0 ;
1104
- }
1105
- }
1106
-
1107
1072
/* Read registers up to 2 at a time */
1108
1073
static int imx477_read_reg (struct imx477 * imx477 , u16 reg , u32 len , u32 * val )
1109
1074
{
@@ -1199,7 +1164,7 @@ static u32 imx477_get_format_code(struct imx477 *imx477, u32 code)
1199
1164
static void imx477_set_default_format (struct imx477 * imx477 )
1200
1165
{
1201
1166
/* Set default mode to max resolution */
1202
- imx477 -> mode = & supported_modes_12bit [0 ];
1167
+ imx477 -> mode = & supported_modes [0 ];
1203
1168
imx477 -> fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12 ;
1204
1169
}
1205
1170
@@ -1215,8 +1180,8 @@ static int imx477_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1215
1180
mutex_lock (& imx477 -> mutex );
1216
1181
1217
1182
/* Initialize try_fmt for the image pad */
1218
- try_fmt_img -> width = supported_modes_12bit [0 ].width ;
1219
- try_fmt_img -> height = supported_modes_12bit [0 ].height ;
1183
+ try_fmt_img -> width = supported_modes [0 ].width ;
1184
+ try_fmt_img -> height = supported_modes [0 ].height ;
1220
1185
try_fmt_img -> code = imx477_get_format_code (imx477 ,
1221
1186
MEDIA_BUS_FMT_SRGGB12_1X12 );
1222
1187
try_fmt_img -> field = V4L2_FIELD_NONE ;
@@ -1394,20 +1359,15 @@ static int imx477_enum_frame_size(struct v4l2_subdev *sd,
1394
1359
return - EINVAL ;
1395
1360
1396
1361
if (fse -> pad == IMAGE_PAD ) {
1397
- const struct imx477_mode * mode_list ;
1398
- unsigned int num_modes ;
1399
-
1400
- get_mode_table (fse -> code , & mode_list , & num_modes );
1401
-
1402
- if (fse -> index >= num_modes )
1362
+ if (fse -> index >= ARRAY_SIZE (supported_modes ))
1403
1363
return - EINVAL ;
1404
1364
1405
1365
if (fse -> code != imx477_get_format_code (imx477 , fse -> code ))
1406
1366
return - EINVAL ;
1407
1367
1408
- fse -> min_width = mode_list [fse -> index ].width ;
1368
+ fse -> min_width = supported_modes [fse -> index ].width ;
1409
1369
fse -> max_width = fse -> min_width ;
1410
- fse -> min_height = mode_list [fse -> index ].height ;
1370
+ fse -> min_height = supported_modes [fse -> index ].height ;
1411
1371
fse -> max_height = fse -> min_height ;
1412
1372
} else {
1413
1373
if (fse -> code != MEDIA_BUS_FMT_SENSOR_DATA || fse -> index > 0 )
@@ -1485,7 +1445,7 @@ static int imx477_get_pad_format(struct v4l2_subdev *sd,
1485
1445
return 0 ;
1486
1446
}
1487
1447
1488
- static
1448
+ /* static
1489
1449
unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
1490
1450
unsigned int framerate_default)
1491
1451
{
@@ -1500,15 +1460,15 @@ unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
1500
1460
1501
1461
return max_t(unsigned int, frame_length, mode->height);
1502
1462
}
1503
-
1463
+ */
1504
1464
static void imx477_set_framing_limits (struct imx477 * imx477 )
1505
1465
{
1506
1466
unsigned int frm_length_default , hblank_min ;
1507
1467
const struct imx477_mode * mode = imx477 -> mode ;
1508
1468
unsigned int line_length_pix ;
1509
1469
1510
- frm_length_default =
1511
- imx477_get_frame_length (mode , mode -> framerate_default );
1470
+ // frm_length_default =
1471
+ // imx477_get_frame_length(mode, mode->framerate_default);
1512
1472
1513
1473
/* Default to no long exposure multiplier. */
1514
1474
imx477 -> long_exp_shift = 0 ;
@@ -1517,12 +1477,26 @@ static void imx477_set_framing_limits(struct imx477 *imx477)
1517
1477
__v4l2_ctrl_modify_range (imx477 -> vblank , 1 ,
1518
1478
((1 << IMX477_LONG_EXP_SHIFT_MAX ) *
1519
1479
IMX477_FRAME_LENGTH_MAX ) - mode -> height ,
1520
- IMX477_VBLANK_MIN , frm_length_default - mode -> height );
1480
+ IMX477_VBLANK_MIN , IMX477_VBLANK_MIN );
1521
1481
1522
1482
/* Setting this will adjust the exposure limits as well. */
1523
- __v4l2_ctrl_s_ctrl (imx477 -> vblank , frm_length_default - mode -> height );
1483
+ // __v4l2_ctrl_s_ctrl(imx477->vblank, frm_length_default - mode->height);
1524
1484
1525
- line_length_pix = mode -> line_length_pix ;
1485
+ switch (imx477 -> fmt_code ) {
1486
+ case MEDIA_BUS_FMT_SRGGB12_1X12 :
1487
+ case MEDIA_BUS_FMT_SGRBG12_1X12 :
1488
+ case MEDIA_BUS_FMT_SGBRG12_1X12 :
1489
+ case MEDIA_BUS_FMT_SBGGR12_1X12 :
1490
+ line_length_pix = mode -> line_length_pix [0 ];
1491
+ break ;
1492
+ /* 10-bit */
1493
+ case MEDIA_BUS_FMT_SRGGB10_1X10 :
1494
+ case MEDIA_BUS_FMT_SGRBG10_1X10 :
1495
+ case MEDIA_BUS_FMT_SGBRG10_1X10 :
1496
+ case MEDIA_BUS_FMT_SBGGR10_1X10 :
1497
+ line_length_pix = mode -> line_length_pix [1 ];
1498
+ break ;
1499
+ }
1526
1500
if (imx477 -> double_link_freq )
1527
1501
line_length_pix /= 2 ;
1528
1502
hblank_min = line_length_pix - mode -> width ;
@@ -1545,17 +1519,12 @@ static int imx477_set_pad_format(struct v4l2_subdev *sd,
1545
1519
mutex_lock (& imx477 -> mutex );
1546
1520
1547
1521
if (fmt -> pad == IMAGE_PAD ) {
1548
- const struct imx477_mode * mode_list ;
1549
- unsigned int num_modes ;
1550
-
1551
1522
/* Bayer order varies with flips */
1552
1523
fmt -> format .code = imx477_get_format_code (imx477 ,
1553
1524
fmt -> format .code );
1554
1525
1555
- get_mode_table (fmt -> format .code , & mode_list , & num_modes );
1556
-
1557
- mode = v4l2_find_nearest_size (mode_list ,
1558
- num_modes ,
1526
+ mode = v4l2_find_nearest_size (supported_modes ,
1527
+ ARRAY_SIZE (supported_modes ),
1559
1528
width , height ,
1560
1529
fmt -> format .width ,
1561
1530
fmt -> format .height );
@@ -1564,7 +1533,8 @@ static int imx477_set_pad_format(struct v4l2_subdev *sd,
1564
1533
framefmt = v4l2_subdev_get_try_format (sd , sd_state ,
1565
1534
fmt -> pad );
1566
1535
* framefmt = fmt -> format ;
1567
- } else if (imx477 -> mode != mode ) {
1536
+ } else if (imx477 -> mode != mode ||
1537
+ fmt -> format .code != imx477 -> fmt_code ) {
1568
1538
imx477 -> mode = mode ;
1569
1539
imx477 -> fmt_code = fmt -> format .code ;
1570
1540
imx477_set_framing_limits (imx477 );
@@ -1643,7 +1613,7 @@ static int imx477_start_streaming(struct imx477 *imx477)
1643
1613
struct i2c_client * client = v4l2_get_subdevdata (& imx477 -> sd );
1644
1614
const struct imx477_reg_list * reg_list ;
1645
1615
const struct imx477_reg_list * extra_regs ;
1646
- int ret , tm ;
1616
+ int ret , tm , val ;
1647
1617
1648
1618
if (!imx477 -> common_regs_written ) {
1649
1619
ret = imx477_write_regs (imx477 , mode_common_regs ,
@@ -1680,6 +1650,28 @@ static int imx477_start_streaming(struct imx477 *imx477)
1680
1650
return ret ;
1681
1651
}
1682
1652
1653
+ switch (imx477 -> fmt_code ) {
1654
+ case MEDIA_BUS_FMT_SRGGB12_1X12 :
1655
+ case MEDIA_BUS_FMT_SGRBG12_1X12 :
1656
+ case MEDIA_BUS_FMT_SGBRG12_1X12 :
1657
+ case MEDIA_BUS_FMT_SBGGR12_1X12 :
1658
+ val = 0x0c ;
1659
+ break ;
1660
+ /* 10-bit */
1661
+ case MEDIA_BUS_FMT_SRGGB10_1X10 :
1662
+ case MEDIA_BUS_FMT_SGRBG10_1X10 :
1663
+ case MEDIA_BUS_FMT_SGBRG10_1X10 :
1664
+ case MEDIA_BUS_FMT_SBGGR10_1X10 :
1665
+ val = 0x0a ;
1666
+ break ;
1667
+ }
1668
+ imx477_write_reg (imx477 , IMX477_REG_CSI_DT_FMT_H ,
1669
+ IMX477_REG_VALUE_08BIT , val );
1670
+ imx477_write_reg (imx477 , IMX477_REG_CSI_DT_FMT_L ,
1671
+ IMX477_REG_VALUE_08BIT , val );
1672
+ imx477_write_reg (imx477 , IMX477_REG_IOP_PXCK_DIV ,
1673
+ IMX477_REG_VALUE_08BIT , val );
1674
+
1683
1675
/* Set on-sensor DPC. */
1684
1676
imx477_write_reg (imx477 , 0x0b05 , IMX477_REG_VALUE_08BIT , !!dpc_enable );
1685
1677
imx477_write_reg (imx477 , 0x0b06 , IMX477_REG_VALUE_08BIT , !!dpc_enable );
0 commit comments