@@ -400,57 +400,42 @@ static u32 imx219_get_format_bpp(const struct v4l2_mbus_framefmt *format)
400400 }
401401}
402402
403- static unsigned int imx219_get_binning (struct v4l2_subdev_state * state ,
404- u8 * bin_h , u8 * bin_v )
403+ static void imx219_get_binning (struct v4l2_subdev_state * state , u8 * bin_h ,
404+ u8 * bin_v )
405405{
406406 const struct v4l2_mbus_framefmt * format =
407407 v4l2_subdev_state_get_format (state , 0 );
408- unsigned int bin_mode = IMX219_BINNING_NONE ;
409- const struct imx219_mode * mode =
410- v4l2_find_nearest_size (supported_modes ,
411- ARRAY_SIZE (supported_modes ),
412- width , height ,
413- format -> width , format -> height );
414- switch (format -> code ) {
415- case MEDIA_BUS_FMT_SRGGB8_1X8 :
416- case MEDIA_BUS_FMT_SGRBG8_1X8 :
417- case MEDIA_BUS_FMT_SGBRG8_1X8 :
418- case MEDIA_BUS_FMT_SBGGR8_1X8 :
419- bin_mode = mode -> binning [BINNING_IDX_8_BIT ];
420- break ;
421-
422- case MEDIA_BUS_FMT_SRGGB10_1X10 :
423- case MEDIA_BUS_FMT_SGRBG10_1X10 :
424- case MEDIA_BUS_FMT_SGBRG10_1X10 :
425- case MEDIA_BUS_FMT_SBGGR10_1X10 :
426- bin_mode = mode -> binning [BINNING_IDX_10_BIT ];
427- break ;
428- }
408+ const struct v4l2_rect * crop = v4l2_subdev_state_get_crop (state , 0 );
409+ u32 hbin = crop -> width / format -> width ;
410+ u32 vbin = crop -> height / format -> height ;
429411
430412 * bin_h = IMX219_BINNING_NONE ;
431413 * bin_v = IMX219_BINNING_NONE ;
432414
433- if (* bin_h == 2 && * bin_v == 2 )
434- return IMX219_BINNING_X2_ANALOG ;
435- else if (* bin_h == 2 || * bin_v == 2 )
436- /*
437- * Don't use analog binning if only one dimension
438- * is binned, as it crops the other dimension
439- */
440- return IMX219_BINNING_X2 ;
441- else
442- return IMX219_BINNING_NONE ;
415+ /*
416+ * Use analog binning only if both dimensions are binned, as it crops
417+ * the other dimension.
418+ */
419+ if (hbin == 2 && vbin == 2 ) {
420+ * bin_h = IMX219_BINNING_X2_ANALOG ;
421+ * bin_v = IMX219_BINNING_X2_ANALOG ;
422+
423+ return ;
424+ }
425+
426+ if (hbin == 2 )
427+ * bin_h = IMX219_BINNING_X2 ;
428+ if (vbin == 2 )
429+ * bin_v = IMX219_BINNING_X2 ;
443430}
444431
445432static inline u32 imx219_get_rate_factor (struct v4l2_subdev_state * state )
446433{
447434 u8 bin_h , bin_v ;
448- unsigned int binning = imx219_get_binning (state , & bin_h , & bin_v );
449435
450- if (binning == IMX219_BINNING_X2_ANALOG )
451- return 2 ;
436+ imx219_get_binning (state , & bin_h , & bin_v );
452437
453- return 1 ;
438+ return ( bin_h & bin_v ) == IMX219_BINNING_X2_ANALOG ? 2 : 1 ;
454439}
455440
456441/* -----------------------------------------------------------------------------
@@ -686,7 +671,6 @@ static int imx219_set_framefmt(struct imx219 *imx219,
686671{
687672 const struct v4l2_mbus_framefmt * format ;
688673 const struct v4l2_rect * crop ;
689- unsigned int binning ;
690674 u8 bin_h , bin_v ;
691675 u32 bpp ;
692676 int ret = 0 ;
@@ -704,11 +688,9 @@ static int imx219_set_framefmt(struct imx219 *imx219,
704688 cci_write (imx219 -> regmap , IMX219_REG_Y_ADD_END_A ,
705689 crop -> top - IMX219_PIXEL_ARRAY_TOP + crop -> height - 1 , & ret );
706690
707- binning = imx219_get_binning (state , & bin_h , & bin_v );
708- cci_write (imx219 -> regmap , IMX219_REG_BINNING_MODE_H ,
709- (bin_h == 2 ) ? binning : IMX219_BINNING_NONE , & ret );
710- cci_write (imx219 -> regmap , IMX219_REG_BINNING_MODE_V ,
711- (bin_v == 2 ) ? binning : IMX219_BINNING_NONE , & ret );
691+ imx219_get_binning (state , & bin_h , & bin_v );
692+ cci_write (imx219 -> regmap , IMX219_REG_BINNING_MODE_H , bin_h , & ret );
693+ cci_write (imx219 -> regmap , IMX219_REG_BINNING_MODE_V , bin_v , & ret );
712694
713695 cci_write (imx219 -> regmap , IMX219_REG_X_OUTPUT_SIZE ,
714696 format -> width , & ret );
0 commit comments