Skip to content

Commit 37814aa

Browse files
naushirpelwell
authored andcommitted
media: i2c: imx219: Scale the pixel clock rate for the 640x480 mode
The 640x480 mode uses a special binning mode for high framerate operation where the pixel rate is effectively doubled. Account for this when setting up the pixel clock rate, and applying the vblank and exposure controls. Signed-off-by: Naushir Patuck <[email protected]>
1 parent 82c86e3 commit 37814aa

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

drivers/media/i2c/imx219.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ struct imx219_mode {
153153

154154
/* Default register values */
155155
struct imx219_reg_list reg_list;
156+
157+
/* Relative pixel clock rate factor for the mode. */
158+
unsigned int rate_factor;
156159
};
157160

158161
/*
@@ -495,6 +498,7 @@ static const struct imx219_mode supported_modes[] = {
495498
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
496499
.regs = mode_3280x2464_regs,
497500
},
501+
.rate_factor = 1,
498502
},
499503
{
500504
/* 1080P 30fps cropped */
@@ -511,6 +515,7 @@ static const struct imx219_mode supported_modes[] = {
511515
.num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
512516
.regs = mode_1920_1080_regs,
513517
},
518+
.rate_factor = 1,
514519
},
515520
{
516521
/* 2x2 binned 30fps mode */
@@ -527,6 +532,7 @@ static const struct imx219_mode supported_modes[] = {
527532
.num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
528533
.regs = mode_1640_1232_regs,
529534
},
535+
.rate_factor = 1,
530536
},
531537
{
532538
/* 640x480 30fps mode */
@@ -543,6 +549,11 @@ static const struct imx219_mode supported_modes[] = {
543549
.num_of_regs = ARRAY_SIZE(mode_640_480_regs),
544550
.regs = mode_640_480_regs,
545551
},
552+
/*
553+
* This mode uses a special 2x2 binning that doubles the
554+
* the internal pixel clock rate.
555+
*/
556+
.rate_factor = 2,
546557
},
547558
};
548559

@@ -765,7 +776,8 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
765776
break;
766777
case V4L2_CID_EXPOSURE:
767778
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);
769781
break;
770782
case V4L2_CID_DIGITAL_GAIN:
771783
ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
@@ -785,7 +797,8 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
785797
case V4L2_CID_VBLANK:
786798
ret = imx219_write_reg(imx219, IMX219_REG_VTS,
787799
IMX219_REG_VALUE_16BIT,
788-
imx219->mode->height + ctrl->val);
800+
(imx219->mode->height + ctrl->val) /
801+
imx219->mode->rate_factor);
789802
break;
790803
case V4L2_CID_TEST_PATTERN_RED:
791804
ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
@@ -957,7 +970,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
957970
struct imx219 *imx219 = to_imx219(sd);
958971
const struct imx219_mode *mode;
959972
struct v4l2_mbus_framefmt *framefmt;
960-
int exposure_max, exposure_def, hblank;
973+
int exposure_max, exposure_def, hblank, pixel_rate;
961974
unsigned int i;
962975

963976
if (fmt->pad >= NUM_PADS)
@@ -1018,6 +1031,12 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
10181031
hblank = IMX219_PPL_DEFAULT - mode->width;
10191032
__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank,
10201033
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);
10211040
}
10221041
} else {
10231042
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
@@ -1362,7 +1381,7 @@ static int imx219_init_controls(struct imx219 *imx219)
13621381
struct v4l2_ctrl_handler *ctrl_hdlr;
13631382
unsigned int height = imx219->mode->height;
13641383
struct v4l2_fwnode_device_properties props;
1365-
int exposure_max, exposure_def, hblank;
1384+
int exposure_max, exposure_def, hblank, pixel_rate;
13661385
int i, ret;
13671386

13681387
ctrl_hdlr = &imx219->ctrl_handler;
@@ -1374,11 +1393,11 @@ static int imx219_init_controls(struct imx219 *imx219)
13741393
ctrl_hdlr->lock = &imx219->mutex;
13751394

13761395
/* By default, PIXEL_RATE is read only */
1396+
pixel_rate = IMX219_PIXEL_RATE * imx219->mode->rate_factor;
13771397
imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
13781398
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);
13821401

13831402
imx219->link_freq =
13841403
v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,

0 commit comments

Comments
 (0)