diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2023-09-24 18:33:06 +0300 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2023-10-07 11:55:47 +0300 |
commit | 186aa9d472897bc5113eeb69c7ff6ed57c2263ee (patch) | |
tree | e71bdc02a7a6467ce0d68dc44a5a9f9c2cc27bd6 /drivers/media/i2c | |
parent | eef9c161d029ed08bff2bdbf8bcc4ae9e731be3f (diff) | |
download | linux-186aa9d472897bc5113eeb69c7ff6ed57c2263ee.tar.xz |
media: i2c: imx219: Separate horizontal and vertical binning
The IMX219 has distinct binning registers for the horizontal and
vertical directions. Calculate their value and write them separately.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/imx219.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 6bfdceaf5044..bf1c2a1dad95 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -90,10 +90,11 @@ #define IMX219_REG_ORIENTATION CCI_REG8(0x0172) /* Binning Mode */ -#define IMX219_REG_BINNING_MODE CCI_REG16(0x0174) -#define IMX219_BINNING_NONE 0x0000 -#define IMX219_BINNING_2X2 0x0101 -#define IMX219_BINNING_2X2_ANALOG 0x0303 +#define IMX219_REG_BINNING_MODE_H CCI_REG8(0x0174) +#define IMX219_REG_BINNING_MODE_V CCI_REG8(0x0175) +#define IMX219_BINNING_NONE 0x00 +#define IMX219_BINNING_X2 0x01 +#define IMX219_BINNING_X2_ANALOG 0x03 #define IMX219_REG_CSI_DATA_FORMAT_A CCI_REG16(0x018c) @@ -615,7 +616,7 @@ static int imx219_set_framefmt(struct imx219 *imx219, const struct v4l2_mbus_framefmt *format; const struct v4l2_rect *crop; unsigned int bpp; - u64 bin_mode; + u64 bin_h, bin_v; int ret = 0; format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); @@ -647,14 +648,28 @@ static int imx219_set_framefmt(struct imx219 *imx219, cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); - if (format->width == crop->width && format->height == crop->height) - bin_mode = IMX219_BINNING_NONE; - else if (bpp == 8) - bin_mode = IMX219_BINNING_2X2_ANALOG; - else - bin_mode = IMX219_BINNING_2X2; + switch (crop->width / format->width) { + case 1: + default: + bin_h = IMX219_BINNING_NONE; + break; + case 2: + bin_h = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; + break; + } + + switch (crop->height / format->height) { + case 1: + default: + bin_v = IMX219_BINNING_NONE; + break; + case 2: + bin_v = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; + break; + } - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, bin_mode, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, bin_h, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, bin_v, &ret); cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, format->width, &ret); |