@@ -43,6 +43,9 @@ MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink");
4343
4444#define IMX477_REG_ORIENTATION 0x101
4545
46+ #define IMX477_REG_CSI_DT_FMT_H 0x0112
47+ #define IMX477_REG_CSI_DT_FMT_L 0x0113
48+
4649#define IMX477_XCLK_FREQ 24000000
4750
4851#define IMX477_DEFAULT_LINK_FREQ 450000000
@@ -86,6 +89,7 @@ MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink");
8689#define IMX477_DGTL_GAIN_DEFAULT 0x0100
8790#define IMX477_DGTL_GAIN_STEP 1
8891
92+ #define IMX477_REG_IOP_PXCK_DIV 0x0309
8993#define IMX477_REG_DIV_IOP_PX 0x030b
9094
9195/* Test Pattern Control */
@@ -153,8 +157,11 @@ struct imx477_mode {
153157 /* Frame height */
154158 unsigned int height ;
155159
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 ];
158165
159166 /* Analog crop rectangle. */
160167 struct v4l2_rect crop ;
@@ -529,8 +536,6 @@ static const struct imx477_reg mode_common_regs[] = {
529536
530537/* 12 mpix 10fps */
531538static const struct imx477_reg mode_4056x3040_regs [] = {
532- {0x0112 , 0x0c },
533- {0x0113 , 0x0c },
534539 {0x0344 , 0x00 },
535540 {0x0345 , 0x00 },
536541 {0x0346 , 0x00 },
@@ -585,7 +590,6 @@ static const struct imx477_reg mode_4056x3040_regs[] = {
585590 {0x0305 , 0x04 },
586591 {0x0306 , 0x01 },
587592 {0x0307 , 0x5e },
588- {0x0309 , 0x0c },
589593 {0xe04c , 0x00 },
590594 {0xe04d , 0x7f },
591595 {0xe04e , 0x00 },
@@ -660,8 +664,6 @@ static const struct imx477_reg mode_4056x2160_regs[] = {
660664
661665/* 2x2 binned. 40fps */
662666static const struct imx477_reg mode_2028x1520_regs [] = {
663- {0x0112 , 0x0c },
664- {0x0113 , 0x0c },
665667 {0x0344 , 0x00 },
666668 {0x0345 , 0x00 },
667669 {0x0346 , 0x00 },
@@ -705,7 +707,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
705707 {0x0305 , 0x04 },
706708 {0x0306 , 0x01 },
707709 {0x0307 , 0x5e },
708- {0x0309 , 0x0c },
709710 {0xe04c , 0x00 },
710711 {0xe04d , 0x7f },
711712 {0xe04e , 0x00 },
@@ -716,8 +717,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
716717
717718/* 1080p cropped mode */
718719static const struct imx477_reg mode_2028x1080_regs [] = {
719- {0x0112 , 0x0c },
720- {0x0113 , 0x0c },
721720 {0x0344 , 0x00 },
722721 {0x0345 , 0x00 },
723722 {0x0346 , 0x01 },
@@ -761,7 +760,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
761760 {0x0305 , 0x04 },
762761 {0x0306 , 0x01 },
763762 {0x0307 , 0x5e },
764- {0x0309 , 0x0c },
765763 {0xe04c , 0x00 },
766764 {0xe04d , 0x7f },
767765 {0xe04e , 0x00 },
@@ -772,8 +770,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
772770
773771/* 4x4 binned. 120fps */
774772static const struct imx477_reg mode_1332x990_regs [] = {
775- {0x0112 , 0x0a },
776- {0x0113 , 0x0a },
777773 {0x420b , 0x01 },
778774 {0x990c , 0x00 },
779775 {0x990d , 0x08 },
@@ -841,7 +837,6 @@ static const struct imx477_reg mode_1332x990_regs[] = {
841837 {0x0305 , 0x02 },
842838 {0x0306 , 0x00 },
843839 {0x0307 , 0xaf },
844- {0x0309 , 0x0a },
845840 {0xe04c , 0x00 },
846841 {0xe04d , 0x5f },
847842 {0xe04e , 0x00 },
@@ -851,12 +846,12 @@ static const struct imx477_reg mode_1332x990_regs[] = {
851846};
852847
853848/* Mode configs */
854- static const struct imx477_mode supported_modes_12bit [] = {
849+ static const struct imx477_mode supported_modes [] = {
855850 {
856851 /* 12MPix 10fps mode */
857852 .width = 4056 ,
858853 .height = 3040 ,
859- .line_length_pix = 24000 ,
854+ .line_length_pix = { 24000 , 20000 } ,
860855 .crop = {
861856 .left = IMX477_PIXEL_ARRAY_LEFT ,
862857 .top = IMX477_PIXEL_ARRAY_TOP ,
@@ -890,7 +885,7 @@ static const struct imx477_mode supported_modes_12bit[] = {
890885 /* 2x2 binned 40fps mode */
891886 .width = 2028 ,
892887 .height = 1520 ,
893- .line_length_pix = 12740 ,
888+ .line_length_pix = { 12740 , 10616 } ,
894889 .crop = {
895890 .left = IMX477_PIXEL_ARRAY_LEFT ,
896891 .top = IMX477_PIXEL_ARRAY_TOP ,
@@ -907,7 +902,7 @@ static const struct imx477_mode supported_modes_12bit[] = {
907902 /* 1080p 50fps cropped mode */
908903 .width = 2028 ,
909904 .height = 1080 ,
910- .line_length_pix = 12740 ,
905+ .line_length_pix = { 12740 , 10616 } ,
911906 .crop = {
912907 .left = IMX477_PIXEL_ARRAY_LEFT ,
913908 .top = IMX477_PIXEL_ARRAY_TOP + 440 ,
@@ -919,15 +914,12 @@ static const struct imx477_mode supported_modes_12bit[] = {
919914 .num_of_regs = ARRAY_SIZE (mode_2028x1080_regs ),
920915 .regs = mode_2028x1080_regs ,
921916 },
922- }
923- };
924-
925- static const struct imx477_mode supported_modes_10bit [] = {
917+ },
926918 {
927919 /* 120fps. 2x2 binned and cropped */
928920 .width = 1332 ,
929921 .height = 990 ,
930- .line_length_pix = 6664 ,
922+ .line_length_pix = { 7997 , 6664 } ,
931923 .crop = {
932924 /*
933925 * FIXME: the analog crop rectangle is actually
@@ -1077,33 +1069,6 @@ static inline struct imx477 *to_imx477(struct v4l2_subdev *_sd)
10771069 return container_of (_sd , struct imx477 , sd );
10781070}
10791071
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-
11071072/* Read registers up to 2 at a time */
11081073static int imx477_read_reg (struct imx477 * imx477 , u16 reg , u32 len , u32 * val )
11091074{
@@ -1199,7 +1164,7 @@ static u32 imx477_get_format_code(struct imx477 *imx477, u32 code)
11991164static void imx477_set_default_format (struct imx477 * imx477 )
12001165{
12011166 /* Set default mode to max resolution */
1202- imx477 -> mode = & supported_modes_12bit [0 ];
1167+ imx477 -> mode = & supported_modes [0 ];
12031168 imx477 -> fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12 ;
12041169}
12051170
@@ -1215,8 +1180,8 @@ static int imx477_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
12151180 mutex_lock (& imx477 -> mutex );
12161181
12171182 /* 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 ;
12201185 try_fmt_img -> code = imx477_get_format_code (imx477 ,
12211186 MEDIA_BUS_FMT_SRGGB12_1X12 );
12221187 try_fmt_img -> field = V4L2_FIELD_NONE ;
@@ -1394,20 +1359,15 @@ static int imx477_enum_frame_size(struct v4l2_subdev *sd,
13941359 return - EINVAL ;
13951360
13961361 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 ))
14031363 return - EINVAL ;
14041364
14051365 if (fse -> code != imx477_get_format_code (imx477 , fse -> code ))
14061366 return - EINVAL ;
14071367
1408- fse -> min_width = mode_list [fse -> index ].width ;
1368+ fse -> min_width = supported_modes [fse -> index ].width ;
14091369 fse -> max_width = fse -> min_width ;
1410- fse -> min_height = mode_list [fse -> index ].height ;
1370+ fse -> min_height = supported_modes [fse -> index ].height ;
14111371 fse -> max_height = fse -> min_height ;
14121372 } else {
14131373 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,
14851445 return 0 ;
14861446}
14871447
1488- static
1448+ /* static
14891449unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
14901450 unsigned int framerate_default)
14911451{
@@ -1500,15 +1460,15 @@ unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
15001460
15011461 return max_t(unsigned int, frame_length, mode->height);
15021462}
1503-
1463+ */
15041464static void imx477_set_framing_limits (struct imx477 * imx477 )
15051465{
15061466 unsigned int frm_length_default , hblank_min ;
15071467 const struct imx477_mode * mode = imx477 -> mode ;
15081468 unsigned int line_length_pix ;
15091469
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);
15121472
15131473 /* Default to no long exposure multiplier. */
15141474 imx477 -> long_exp_shift = 0 ;
@@ -1517,12 +1477,26 @@ static void imx477_set_framing_limits(struct imx477 *imx477)
15171477 __v4l2_ctrl_modify_range (imx477 -> vblank , 1 ,
15181478 ((1 << IMX477_LONG_EXP_SHIFT_MAX ) *
15191479 IMX477_FRAME_LENGTH_MAX ) - mode -> height ,
1520- IMX477_VBLANK_MIN , frm_length_default - mode -> height );
1480+ IMX477_VBLANK_MIN , IMX477_VBLANK_MIN );
15211481
15221482 /* 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);
15241484
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+ }
15261500 if (imx477 -> double_link_freq )
15271501 line_length_pix /= 2 ;
15281502 hblank_min = line_length_pix - mode -> width ;
@@ -1545,17 +1519,12 @@ static int imx477_set_pad_format(struct v4l2_subdev *sd,
15451519 mutex_lock (& imx477 -> mutex );
15461520
15471521 if (fmt -> pad == IMAGE_PAD ) {
1548- const struct imx477_mode * mode_list ;
1549- unsigned int num_modes ;
1550-
15511522 /* Bayer order varies with flips */
15521523 fmt -> format .code = imx477_get_format_code (imx477 ,
15531524 fmt -> format .code );
15541525
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 ),
15591528 width , height ,
15601529 fmt -> format .width ,
15611530 fmt -> format .height );
@@ -1564,7 +1533,8 @@ static int imx477_set_pad_format(struct v4l2_subdev *sd,
15641533 framefmt = v4l2_subdev_get_try_format (sd , sd_state ,
15651534 fmt -> pad );
15661535 * framefmt = fmt -> format ;
1567- } else if (imx477 -> mode != mode ) {
1536+ } else if (imx477 -> mode != mode ||
1537+ fmt -> format .code != imx477 -> fmt_code ) {
15681538 imx477 -> mode = mode ;
15691539 imx477 -> fmt_code = fmt -> format .code ;
15701540 imx477_set_framing_limits (imx477 );
@@ -1643,7 +1613,7 @@ static int imx477_start_streaming(struct imx477 *imx477)
16431613 struct i2c_client * client = v4l2_get_subdevdata (& imx477 -> sd );
16441614 const struct imx477_reg_list * reg_list ;
16451615 const struct imx477_reg_list * extra_regs ;
1646- int ret , tm ;
1616+ int ret , tm , val ;
16471617
16481618 if (!imx477 -> common_regs_written ) {
16491619 ret = imx477_write_regs (imx477 , mode_common_regs ,
@@ -1680,6 +1650,28 @@ static int imx477_start_streaming(struct imx477 *imx477)
16801650 return ret ;
16811651 }
16821652
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+
16831675 /* Set on-sensor DPC. */
16841676 imx477_write_reg (imx477 , 0x0b05 , IMX477_REG_VALUE_08BIT , !!dpc_enable );
16851677 imx477_write_reg (imx477 , 0x0b06 , IMX477_REG_VALUE_08BIT , !!dpc_enable );
0 commit comments