@@ -153,6 +153,9 @@ struct imx219_mode {
153
153
154
154
/* Default register values */
155
155
struct imx219_reg_list reg_list ;
156
+
157
+ /* Relative pixel clock rate factor for the mode. */
158
+ unsigned int rate_factor ;
156
159
};
157
160
158
161
/*
@@ -495,6 +498,7 @@ static const struct imx219_mode supported_modes[] = {
495
498
.num_of_regs = ARRAY_SIZE (mode_3280x2464_regs ),
496
499
.regs = mode_3280x2464_regs ,
497
500
},
501
+ .rate_factor = 1 ,
498
502
},
499
503
{
500
504
/* 1080P 30fps cropped */
@@ -511,6 +515,7 @@ static const struct imx219_mode supported_modes[] = {
511
515
.num_of_regs = ARRAY_SIZE (mode_1920_1080_regs ),
512
516
.regs = mode_1920_1080_regs ,
513
517
},
518
+ .rate_factor = 1 ,
514
519
},
515
520
{
516
521
/* 2x2 binned 30fps mode */
@@ -527,6 +532,7 @@ static const struct imx219_mode supported_modes[] = {
527
532
.num_of_regs = ARRAY_SIZE (mode_1640_1232_regs ),
528
533
.regs = mode_1640_1232_regs ,
529
534
},
535
+ .rate_factor = 1 ,
530
536
},
531
537
{
532
538
/* 640x480 30fps mode */
@@ -543,6 +549,11 @@ static const struct imx219_mode supported_modes[] = {
543
549
.num_of_regs = ARRAY_SIZE (mode_640_480_regs ),
544
550
.regs = mode_640_480_regs ,
545
551
},
552
+ /*
553
+ * This mode uses a special 2x2 binning that doubles the
554
+ * the internal pixel clock rate.
555
+ */
556
+ .rate_factor = 2 ,
546
557
},
547
558
};
548
559
@@ -765,7 +776,8 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
765
776
break ;
766
777
case V4L2_CID_EXPOSURE :
767
778
ret = imx219_write_reg (imx219 , IMX219_REG_EXPOSURE ,
768
- IMX219_REG_VALUE_16BIT , ctrl -> val );
779
+ IMX219_REG_VALUE_16BIT ,
780
+ ctrl -> val / imx219 -> mode -> rate_factor );
769
781
break ;
770
782
case V4L2_CID_DIGITAL_GAIN :
771
783
ret = imx219_write_reg (imx219 , IMX219_REG_DIGITAL_GAIN ,
@@ -785,7 +797,8 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
785
797
case V4L2_CID_VBLANK :
786
798
ret = imx219_write_reg (imx219 , IMX219_REG_VTS ,
787
799
IMX219_REG_VALUE_16BIT ,
788
- imx219 -> mode -> height + ctrl -> val );
800
+ (imx219 -> mode -> height + ctrl -> val ) /
801
+ imx219 -> mode -> rate_factor );
789
802
break ;
790
803
case V4L2_CID_TEST_PATTERN_RED :
791
804
ret = imx219_write_reg (imx219 , IMX219_REG_TESTP_RED ,
@@ -957,7 +970,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
957
970
struct imx219 * imx219 = to_imx219 (sd );
958
971
const struct imx219_mode * mode ;
959
972
struct v4l2_mbus_framefmt * framefmt ;
960
- int exposure_max , exposure_def , hblank ;
973
+ int exposure_max , exposure_def , hblank , pixel_rate ;
961
974
unsigned int i ;
962
975
963
976
if (fmt -> pad >= NUM_PADS )
@@ -1018,6 +1031,12 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
1018
1031
hblank = IMX219_PPL_DEFAULT - mode -> width ;
1019
1032
__v4l2_ctrl_modify_range (imx219 -> hblank , hblank , hblank ,
1020
1033
1 , hblank );
1034
+
1035
+ /* Scale the pixel rate based on the mode specific factor */
1036
+ pixel_rate =
1037
+ IMX219_PIXEL_RATE * imx219 -> mode -> rate_factor ;
1038
+ __v4l2_ctrl_modify_range (imx219 -> pixel_rate , pixel_rate ,
1039
+ pixel_rate , 1 , pixel_rate );
1021
1040
}
1022
1041
} else {
1023
1042
if (fmt -> which == V4L2_SUBDEV_FORMAT_TRY ) {
@@ -1362,7 +1381,7 @@ static int imx219_init_controls(struct imx219 *imx219)
1362
1381
struct v4l2_ctrl_handler * ctrl_hdlr ;
1363
1382
unsigned int height = imx219 -> mode -> height ;
1364
1383
struct v4l2_fwnode_device_properties props ;
1365
- int exposure_max , exposure_def , hblank ;
1384
+ int exposure_max , exposure_def , hblank , pixel_rate ;
1366
1385
int i , ret ;
1367
1386
1368
1387
ctrl_hdlr = & imx219 -> ctrl_handler ;
@@ -1374,11 +1393,11 @@ static int imx219_init_controls(struct imx219 *imx219)
1374
1393
ctrl_hdlr -> lock = & imx219 -> mutex ;
1375
1394
1376
1395
/* By default, PIXEL_RATE is read only */
1396
+ pixel_rate = IMX219_PIXEL_RATE * imx219 -> mode -> rate_factor ;
1377
1397
imx219 -> pixel_rate = v4l2_ctrl_new_std (ctrl_hdlr , & imx219_ctrl_ops ,
1378
1398
V4L2_CID_PIXEL_RATE ,
1379
- IMX219_PIXEL_RATE ,
1380
- IMX219_PIXEL_RATE , 1 ,
1381
- IMX219_PIXEL_RATE );
1399
+ pixel_rate , pixel_rate ,
1400
+ 1 , pixel_rate );
1382
1401
1383
1402
imx219 -> link_freq =
1384
1403
v4l2_ctrl_new_int_menu (ctrl_hdlr , & imx219_ctrl_ops ,
0 commit comments