@@ -174,9 +174,6 @@ struct imx355 {
174174 struct v4l2_ctrl * vflip ;
175175 struct v4l2_ctrl * hflip ;
176176
177- /* Current mode */
178- const struct imx355_mode * cur_mode ;
179-
180177 struct imx355_hwcfg * hwcfg ;
181178 const struct imx355_clk_params * clk_params ;
182179
@@ -606,6 +603,8 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
606603{
607604 struct imx355 * imx355 = container_of (ctrl -> handler ,
608605 struct imx355 , ctrl_handler );
606+ const struct v4l2_mbus_framefmt * format = NULL ;
607+ struct v4l2_subdev_state * state ;
609608 s64 max ;
610609 int ret ;
611610
@@ -616,7 +615,7 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
616615 switch (ctrl -> id ) {
617616 case V4L2_CID_VBLANK :
618617 /* Update max exposure while meeting expected vblanking */
619- max = imx355 -> cur_mode -> height + ctrl -> val - 10 ;
618+ max = format -> height + ctrl -> val - 10 ;
620619 __v4l2_ctrl_modify_range (imx355 -> exposure ,
621620 imx355 -> exposure -> minimum ,
622621 max , imx355 -> exposure -> step , max );
@@ -647,7 +646,7 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
647646 case V4L2_CID_VBLANK :
648647 /* Update FLL that meets expected vertical blanking */
649648 ret = cci_write (imx355 -> regmap , IMX355_REG_FLL ,
650- imx355 -> cur_mode -> height + ctrl -> val , NULL );
649+ format -> height + ctrl -> val , NULL );
651650 break ;
652651 case V4L2_CID_TEST_PATTERN :
653652 ret = cci_write (imx355 -> regmap , IMX355_REG_TEST_PATTERN ,
@@ -733,9 +732,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
733732 const struct imx355_mode * mode ;
734733 struct v4l2_mbus_framefmt * framefmt ;
735734 struct v4l2_rect * crop ;
736- s32 vblank_def ;
737735 s64 h_blank ;
738- u32 height ;
739736
740737 /*
741738 * Only one bayer order is supported.
@@ -760,16 +757,14 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
760757 crop -> top = mode -> crop .top ;
761758
762759 if (fmt -> which == V4L2_SUBDEV_FORMAT_ACTIVE ) {
763- imx355 -> cur_mode = mode ;
764760 /* Update limits and set FPS to default */
765- height = imx355 -> cur_mode -> height ;
766- vblank_def = imx355 -> cur_mode -> fll_def - height ;
767- height = IMX355_FLL_MAX - height ;
768761 __v4l2_ctrl_modify_range (imx355 -> vblank , IMX355_VBLANK_MIN ,
769- height , 1 , vblank_def );
770- __v4l2_ctrl_s_ctrl (imx355 -> vblank , vblank_def );
762+ IMX355_FLL_MAX - mode -> height , 1 ,
763+ mode -> fll_def - mode -> height );
764+ __v4l2_ctrl_s_ctrl (imx355 -> vblank , mode -> fll_def - mode -> height );
765+
766+ h_blank = mode -> llp - mode -> width ;
771767
772- h_blank = mode -> llp - imx355 -> cur_mode -> width ;
773768 /*
774769 * Currently hblank is not changeable.
775770 * So FPS control is done only by vblank.
@@ -821,35 +816,41 @@ static int imx355_entity_init_state(struct v4l2_subdev *subdev,
821816/* Start streaming */
822817static int imx355_start_streaming (struct imx355 * imx355 )
823818{
824- const struct imx355_reg_list * reg_list ;
819+ const struct v4l2_mbus_framefmt * fmt ;
820+ struct v4l2_subdev_state * state ;
825821 const struct imx355_mode * mode ;
826822 int lane_idx = imx355 -> hwcfg -> num_lanes == 4 ? 0 : 1 ;
823+ struct v4l2_rect * crop ;
827824 u8 binning_mode ;
828825 int ret = 0 ;
829826
830827 /* Global Setting */
831828 cci_multi_reg_write (imx355 -> regmap , imx355_global_regs ,
832829 ARRAY_SIZE (imx355_global_regs ), & ret );
833830
834- /* Apply default values of current mode */
835- mode = imx355 -> cur_mode ;
836- reg_list = & mode -> reg_list ;
837- cci_multi_reg_write (imx355 -> regmap , reg_list -> regs ,
838- reg_list -> num_of_regs , & ret );
831+ /* Apply values of current mode */
832+ state = v4l2_subdev_get_locked_active_state (& imx355 -> sd );
833+ fmt = v4l2_subdev_state_get_format (state , 0 );
834+ crop = v4l2_subdev_state_get_crop (state , 0 );
835+ mode = v4l2_find_nearest_size (supported_modes ,
836+ ARRAY_SIZE (supported_modes ),
837+ width , height , fmt -> width , fmt -> height );
838+ cci_multi_reg_write (imx355 -> regmap , mode -> reg_list .regs ,
839+ mode -> reg_list .num_of_regs , & ret );
839840
840841 /* Set readout crop and size registers */
841- cci_write (imx355 -> regmap , IMX355_REG_X_ADD_START , mode -> crop . left ,
842+ cci_write (imx355 -> regmap , IMX355_REG_X_ADD_START , crop -> left ,
842843 & ret );
843- cci_write (imx355 -> regmap , IMX355_REG_Y_ADD_START , mode -> crop . top , & ret );
844+ cci_write (imx355 -> regmap , IMX355_REG_Y_ADD_START , crop -> top , & ret );
844845 cci_write (imx355 -> regmap , IMX355_REG_X_ADD_END ,
845- mode -> crop . width + mode -> crop . left - 1 , & ret );
846+ crop -> width + crop -> left - 1 , & ret );
846847 cci_write (imx355 -> regmap , IMX355_REG_Y_ADD_END ,
847- mode -> crop . height + mode -> crop . top - 1 , & ret );
848- cci_write (imx355 -> regmap , IMX355_REG_X_OUT_SIZE , mode -> width , & ret );
849- cci_write (imx355 -> regmap , IMX355_REG_Y_OUT_SIZE , mode -> height , & ret );
848+ crop -> height + crop -> top - 1 , & ret );
849+ cci_write (imx355 -> regmap , IMX355_REG_X_OUT_SIZE , fmt -> width , & ret );
850+ cci_write (imx355 -> regmap , IMX355_REG_Y_OUT_SIZE , fmt -> height , & ret );
850851
851- binning_mode = ((mode -> crop . width / mode -> width ) << 4 ) |
852- (mode -> crop . height / mode -> height );
852+ binning_mode = ((crop -> width / fmt -> width ) << 4 ) |
853+ (crop -> height / fmt -> height );
853854 cci_write (imx355 -> regmap , IMX355_REG_BINNING_MODE ,
854855 binning_mode == 0x11 ? 0x00 : 0x01 , & ret );
855856 cci_write (imx355 -> regmap , IMX355_REG_BINNING_TYPE , binning_mode , & ret );
@@ -878,7 +879,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
878879
879880 /* set line length */
880881 cci_write (imx355 -> regmap , IMX355_REG_LLP ,
881- imx355 -> hblank -> val + imx355 -> cur_mode -> width , & ret );
882+ imx355 -> hblank -> val + fmt -> width , & ret );
882883
883884 /* Apply customized values from user */
884885 if (!ret )
@@ -1031,10 +1032,10 @@ static int imx355_init_controls(struct imx355 *imx355)
10311032{
10321033 struct v4l2_fwnode_device_properties props ;
10331034 struct v4l2_ctrl_handler * ctrl_hdlr ;
1035+ const struct imx355_mode * mode = & supported_modes [0 ];
10341036 s64 exposure_max ;
10351037 s64 vblank_def ;
10361038 s64 hblank ;
1037- const struct imx355_mode * mode ;
10381039 const s64 * link_freq_menu ;
10391040 s64 pixel_rate ;
10401041 u32 max ;
@@ -1062,7 +1063,6 @@ static int imx355_init_controls(struct imx355 *imx355)
10621063 pixel_rate , pixel_rate , 1 , pixel_rate );
10631064
10641065 /* Initialize vblank/hblank/exposure parameters based on current mode */
1065- mode = imx355 -> cur_mode ;
10661066 vblank_def = mode -> fll_def - mode -> height ;
10671067 imx355 -> vblank = v4l2_ctrl_new_std (ctrl_hdlr , & imx355_ctrl_ops ,
10681068 V4L2_CID_VBLANK , IMX355_VBLANK_MIN ,
@@ -1254,9 +1254,6 @@ static int imx355_probe(struct i2c_client *client)
12541254 goto error_power_off ;
12551255 }
12561256
1257- /* Set default mode to max resolution */
1258- imx355 -> cur_mode = & supported_modes [0 ];
1259-
12601257 ret = imx355_init_controls (imx355 );
12611258 if (ret ) {
12621259 dev_err (imx355 -> dev , "failed to init controls: %d" , ret );
0 commit comments