@@ -53,7 +53,6 @@ MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink");
5353/* V_TIMING internal */
5454#define IMX477_REG_FRAME_LENGTH 0x0340
5555#define IMX477_FRAME_LENGTH_MAX 0xffdc
56- #define IMX477_VBLANK_MIN 4
5756
5857/* H_TIMING internal */
5958#define IMX477_REG_LINE_LENGTH 0x0342
@@ -158,8 +157,11 @@ struct imx477_mode {
158157 /* Analog crop rectangle. */
159158 struct v4l2_rect crop ;
160159
160+ /* Highest possible framerate. */
161+ struct v4l2_fract timeperframe_min ;
162+
161163 /* Default framerate. */
162- unsigned int framerate_default ;
164+ struct v4l2_fract timeperframe_default ;
163165
164166 /* Default register values */
165167 struct imx477_reg_list reg_list ;
@@ -867,7 +869,14 @@ static const struct imx477_mode supported_modes_12bit[] = {
867869 .width = 4056 ,
868870 .height = 3040 ,
869871 },
870- .framerate_default = 10 ,
872+ .timeperframe_min = {
873+ .numerator = 100 ,
874+ .denominator = 1000
875+ },
876+ .timeperframe_default = {
877+ .numerator = 100 ,
878+ .denominator = 1000
879+ },
871880 .reg_list = {
872881 .num_of_regs = ARRAY_SIZE (mode_4056x3040_regs ),
873882 .regs = mode_4056x3040_regs ,
@@ -884,7 +893,14 @@ static const struct imx477_mode supported_modes_12bit[] = {
884893 .width = 4056 ,
885894 .height = 3040 ,
886895 },
887- .framerate_default = 30 ,
896+ .timeperframe_min = {
897+ .numerator = 100 ,
898+ .denominator = 4000
899+ },
900+ .timeperframe_default = {
901+ .numerator = 100 ,
902+ .denominator = 3000
903+ },
888904 .reg_list = {
889905 .num_of_regs = ARRAY_SIZE (mode_2028x1520_regs ),
890906 .regs = mode_2028x1520_regs ,
@@ -901,7 +917,14 @@ static const struct imx477_mode supported_modes_12bit[] = {
901917 .width = 4056 ,
902918 .height = 2160 ,
903919 },
904- .framerate_default = 30 ,
920+ .timeperframe_min = {
921+ .numerator = 100 ,
922+ .denominator = 5000
923+ },
924+ .timeperframe_default = {
925+ .numerator = 100 ,
926+ .denominator = 3000
927+ },
905928 .reg_list = {
906929 .num_of_regs = ARRAY_SIZE (mode_2028x1080_regs ),
907930 .regs = mode_2028x1080_regs ,
@@ -929,7 +952,14 @@ static const struct imx477_mode supported_modes_10bit[] = {
929952 .width = 2664 ,
930953 .height = 1980 ,
931954 },
932- .framerate_default = 120 ,
955+ .timeperframe_min = {
956+ .numerator = 100 ,
957+ .denominator = 12000
958+ },
959+ .timeperframe_default = {
960+ .numerator = 100 ,
961+ .denominator = 12000
962+ },
933963 .reg_list = {
934964 .num_of_regs = ARRAY_SIZE (mode_1332x990_regs ),
935965 .regs = mode_1332x990_regs ,
@@ -1472,13 +1502,13 @@ static int imx477_get_pad_format(struct v4l2_subdev *sd,
14721502
14731503static
14741504unsigned int imx477_get_frame_length (const struct imx477_mode * mode ,
1475- unsigned int framerate_default )
1505+ const struct v4l2_fract * timeperframe )
14761506{
14771507 u64 frame_length ;
14781508
1479- frame_length = IMX477_PIXEL_RATE ;
1509+ frame_length = ( u64 ) timeperframe -> numerator * IMX477_PIXEL_RATE ;
14801510 do_div (frame_length ,
1481- (u64 )framerate_default * mode -> line_length_pix );
1511+ (u64 )timeperframe -> denominator * mode -> line_length_pix );
14821512
14831513 if (WARN_ON (frame_length > IMX477_FRAME_LENGTH_MAX ))
14841514 frame_length = IMX477_FRAME_LENGTH_MAX ;
@@ -1488,20 +1518,21 @@ unsigned int imx477_get_frame_length(const struct imx477_mode *mode,
14881518
14891519static void imx477_set_framing_limits (struct imx477 * imx477 )
14901520{
1491- unsigned int frm_length_default , hblank_min ;
1521+ unsigned int frm_length_min , frm_length_default , hblank_min ;
14921522 const struct imx477_mode * mode = imx477 -> mode ;
14931523
1524+ frm_length_min = imx477_get_frame_length (mode , & mode -> timeperframe_min );
14941525 frm_length_default =
1495- imx477_get_frame_length (mode , mode -> framerate_default );
1526+ imx477_get_frame_length (mode , & mode -> timeperframe_default );
14961527
14971528 /* Default to no long exposure multiplier. */
14981529 imx477 -> long_exp_shift = 0 ;
14991530
15001531 /* Update limits and set FPS to default */
1501- __v4l2_ctrl_modify_range (imx477 -> vblank , 1 ,
1532+ __v4l2_ctrl_modify_range (imx477 -> vblank , frm_length_min - mode -> height ,
15021533 ((1 << IMX477_LONG_EXP_SHIFT_MAX ) *
15031534 IMX477_FRAME_LENGTH_MAX ) - mode -> height ,
1504- IMX477_VBLANK_MIN , frm_length_default - mode -> height );
1535+ 1 , frm_length_default - mode -> height );
15051536
15061537 /* Setting this will adjust the exposure limits as well. */
15071538 __v4l2_ctrl_s_ctrl (imx477 -> vblank , frm_length_default - mode -> height );
0 commit comments