diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch b/target/linux/bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch new file mode 100644 index 0000000000..124117ce8b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.15/950-0706-media-i2c-imx219-Scale-the-pixel-clock-rate-for-the-.patch @@ -0,0 +1,129 @@ +From 055e3d70b0227e26d58b2efc4561eb21a3fbf640 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Tue, 8 Feb 2022 13:49:11 +0000 +Subject: [PATCH] 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 <naush@raspberrypi.com> +--- + drivers/media/i2c/imx219.c | 33 ++++++++++++++++++++++++++------- + 1 file changed, 26 insertions(+), 7 deletions(-) + +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -153,6 +153,9 @@ struct imx219_mode { + + /* Default register values */ + struct imx219_reg_list reg_list; ++ ++ /* Relative pixel clock rate factor for the mode. */ ++ unsigned int rate_factor; + }; + + /* +@@ -495,6 +498,7 @@ static const struct imx219_mode supporte + .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs), + .regs = mode_3280x2464_regs, + }, ++ .rate_factor = 1, + }, + { + /* 1080P 30fps cropped */ +@@ -511,6 +515,7 @@ static const struct imx219_mode supporte + .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs), + .regs = mode_1920_1080_regs, + }, ++ .rate_factor = 1, + }, + { + /* 2x2 binned 30fps mode */ +@@ -527,6 +532,7 @@ static const struct imx219_mode supporte + .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs), + .regs = mode_1640_1232_regs, + }, ++ .rate_factor = 1, + }, + { + /* 640x480 30fps mode */ +@@ -543,6 +549,11 @@ static const struct imx219_mode supporte + .num_of_regs = ARRAY_SIZE(mode_640_480_regs), + .regs = mode_640_480_regs, + }, ++ /* ++ * This mode uses a special 2x2 binning that doubles the ++ * the internal pixel clock rate. ++ */ ++ .rate_factor = 2, + }, + }; + +@@ -765,7 +776,8 @@ static int imx219_set_ctrl(struct v4l2_c + break; + case V4L2_CID_EXPOSURE: + ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ IMX219_REG_VALUE_16BIT, ++ ctrl->val / imx219->mode->rate_factor); + break; + case V4L2_CID_DIGITAL_GAIN: + ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, +@@ -785,7 +797,8 @@ static int imx219_set_ctrl(struct v4l2_c + case V4L2_CID_VBLANK: + ret = imx219_write_reg(imx219, IMX219_REG_VTS, + IMX219_REG_VALUE_16BIT, +- imx219->mode->height + ctrl->val); ++ (imx219->mode->height + ctrl->val) / ++ imx219->mode->rate_factor); + break; + case V4L2_CID_TEST_PATTERN_RED: + ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, +@@ -957,7 +970,7 @@ static int imx219_set_pad_format(struct + struct imx219 *imx219 = to_imx219(sd); + const struct imx219_mode *mode; + struct v4l2_mbus_framefmt *framefmt; +- int exposure_max, exposure_def, hblank; ++ int exposure_max, exposure_def, hblank, pixel_rate; + unsigned int i; + + if (fmt->pad >= NUM_PADS) +@@ -1018,6 +1031,12 @@ static int imx219_set_pad_format(struct + hblank = IMX219_PPL_DEFAULT - mode->width; + __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, + 1, hblank); ++ ++ /* Scale the pixel rate based on the mode specific factor */ ++ pixel_rate = ++ IMX219_PIXEL_RATE * imx219->mode->rate_factor; ++ __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate, ++ pixel_rate, 1, pixel_rate); + } + } else { + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +@@ -1362,7 +1381,7 @@ static int imx219_init_controls(struct i + struct v4l2_ctrl_handler *ctrl_hdlr; + unsigned int height = imx219->mode->height; + struct v4l2_fwnode_device_properties props; +- int exposure_max, exposure_def, hblank; ++ int exposure_max, exposure_def, hblank, pixel_rate; + int i, ret; + + ctrl_hdlr = &imx219->ctrl_handler; +@@ -1374,11 +1393,11 @@ static int imx219_init_controls(struct i + ctrl_hdlr->lock = &imx219->mutex; + + /* By default, PIXEL_RATE is read only */ ++ pixel_rate = IMX219_PIXEL_RATE * imx219->mode->rate_factor; + imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_PIXEL_RATE, +- IMX219_PIXEL_RATE, +- IMX219_PIXEL_RATE, 1, +- IMX219_PIXEL_RATE); ++ pixel_rate, pixel_rate, ++ 1, pixel_rate); + + imx219->link_freq = + v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, |