Skip to content

Commit 32f34cf

Browse files
vvarmanaushir
authored andcommitted
media: i2c: imx219: fix binning and rate_factor for 480p and 1232p
At a high FPS with RAW10, there is frame corruption for 480p because the rate_factor of 2 is used with the normal 2x2 bining [1]. This commit ties the rate_factor to the selected binning mode. For the 480p mode, analog 2x2 binning mode with a rate_factor of 2 is always used. For the 1232p mode the normal 2x2 binning mode is used for RAW10 while analog 2x2 binning mode is used for RAW8. [1] #5493 Signed-off-by: Vinay Varma <[email protected]> Signed-off-by: Dave Stevenson <[email protected]> Signed-off-by: Naushir Patuck <[email protected]> Reworked due to upstream changes
1 parent bf21a52 commit 32f34cf

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

drivers/media/i2c/imx219.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@
148148
#define IMX219_PIXEL_ARRAY_WIDTH 3280U
149149
#define IMX219_PIXEL_ARRAY_HEIGHT 2464U
150150

151+
enum binning_bit_depths {
152+
BINNING_IDX_8_BIT,
153+
BINNING_IDX_10_BIT,
154+
BINNING_IDX_MAX
155+
};
156+
151157
/* Mode : resolution and related config&values */
152158
struct imx219_mode {
153159
/* Frame width */
@@ -157,6 +163,9 @@ struct imx219_mode {
157163

158164
/* V-timing */
159165
unsigned int vts_def;
166+
167+
/* binning mode based on format code */
168+
unsigned int binning[BINNING_IDX_MAX];
160169
};
161170

162171
static const struct cci_reg_sequence imx219_common_regs[] = {
@@ -316,24 +325,40 @@ static const struct imx219_mode supported_modes[] = {
316325
.width = 3280,
317326
.height = 2464,
318327
.vts_def = 3526,
328+
.binning = {
329+
[BINNING_IDX_8_BIT] = 0,
330+
[BINNING_IDX_10_BIT] = 0,
331+
},
319332
},
320333
{
321334
/* 1080P 30fps cropped */
322335
.width = 1920,
323336
.height = 1080,
324337
.vts_def = 1763,
338+
.binning = {
339+
[BINNING_IDX_8_BIT] = 0,
340+
[BINNING_IDX_10_BIT] = 0,
341+
},
325342
},
326343
{
327344
/* 2x2 binned 60fps mode */
328345
.width = 1640,
329346
.height = 1232,
330347
.vts_def = 1763,
348+
.binning = {
349+
[BINNING_IDX_8_BIT] = IMX219_BINNING_X2_ANALOG,
350+
[BINNING_IDX_10_BIT] = IMX219_BINNING_X2,
351+
},
331352
},
332353
{
333354
/* 640x480 60fps mode */
334355
.width = 640,
335356
.height = 480,
336357
.vts_def = 1763,
358+
.binning = {
359+
[BINNING_IDX_8_BIT] = IMX219_BINNING_X2_ANALOG,
360+
[BINNING_IDX_10_BIT] = IMX219_BINNING_X2_ANALOG,
361+
},
337362
},
338363
};
339364

@@ -411,12 +436,33 @@ static unsigned int imx219_get_binning(struct imx219 *imx219, u8 *bin_h,
411436
const struct v4l2_mbus_framefmt *format =
412437
v4l2_subdev_state_get_format(state, 0);
413438
const struct v4l2_rect *crop = v4l2_subdev_state_get_crop(state, 0);
439+
unsigned int bin_mode = IMX219_BINNING_NONE;
440+
const struct imx219_mode *mode =
441+
v4l2_find_nearest_size(supported_modes,
442+
ARRAY_SIZE(supported_modes),
443+
width, height,
444+
format->width, format->height);
445+
switch (format->code) {
446+
case MEDIA_BUS_FMT_SRGGB8_1X8:
447+
case MEDIA_BUS_FMT_SGRBG8_1X8:
448+
case MEDIA_BUS_FMT_SGBRG8_1X8:
449+
case MEDIA_BUS_FMT_SBGGR8_1X8:
450+
bin_mode = mode->binning[BINNING_IDX_8_BIT];
451+
break;
452+
453+
case MEDIA_BUS_FMT_SRGGB10_1X10:
454+
case MEDIA_BUS_FMT_SGRBG10_1X10:
455+
case MEDIA_BUS_FMT_SGBRG10_1X10:
456+
case MEDIA_BUS_FMT_SBGGR10_1X10:
457+
bin_mode = mode->binning[BINNING_IDX_10_BIT];
458+
break;
459+
}
414460

415461
*bin_h = crop->width / format->width;
416462
*bin_v = crop->height / format->height;
417463

418464
if (*bin_h == 2 && *bin_v == 2)
419-
return IMX219_BINNING_X2_ANALOG;
465+
return bin_mode;
420466
else if (*bin_h == 2 || *bin_v == 2)
421467
/*
422468
* Don't use analog binning if only one dimension

0 commit comments

Comments
 (0)