Skip to content

Commit 042d997

Browse files
committed
media: i2c: imx415: Add support for 12bit readout
The sensor supports conversion and readout as either 10 or 12 bit data, but the driver only supported 10 bit mode. Add support for 12 bit conversion. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 8637b97 commit 042d997

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

drivers/media/i2c/imx415.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,16 @@ static const struct imx415_mode supported_modes[] = {
639639
},
640640
};
641641

642+
static const struct cci_reg_sequence imx415_10bit_readout[] = {
643+
{ IMX415_ADBIT, 0x00 },
644+
{ IMX415_MDBIT, 0x00 },
645+
};
646+
647+
static const struct cci_reg_sequence imx415_12bit_readout[] = {
648+
{ IMX415_ADBIT, 0x01 },
649+
{ IMX415_MDBIT, 0x01 },
650+
};
651+
642652
static const char *const imx415_test_pattern_menu[] = {
643653
"disabled",
644654
"solid black",
@@ -688,9 +698,6 @@ static const struct cci_reg_sequence imx415_init_table[] = {
688698
{ IMX415_WINMODE, 0x00 },
689699
{ IMX415_ADDMODE, 0x00 },
690700
{ IMX415_REVERSE, 0x00 },
691-
/* use RAW 10-bit mode */
692-
{ IMX415_ADBIT, 0x00 },
693-
{ IMX415_MDBIT, 0x00 },
694701
/* output VSYNC on XVS and low on XHS */
695702
{ IMX415_OUTSEL, 0x22 },
696703
{ IMX415_DRV, 0x00 },
@@ -999,6 +1006,7 @@ static int imx415_set_mode(struct imx415 *sensor, int mode)
9991006

10001007
static int imx415_setup(struct imx415 *sensor, struct v4l2_subdev_state *state)
10011008
{
1009+
struct v4l2_mbus_framefmt *format;
10021010
int ret;
10031011

10041012
ret = cci_multi_reg_write(sensor->regmap,
@@ -1008,6 +1016,24 @@ static int imx415_setup(struct imx415 *sensor, struct v4l2_subdev_state *state)
10081016
if (ret)
10091017
return ret;
10101018

1019+
format = v4l2_subdev_state_get_format(state, 0);
1020+
switch (format->code) {
1021+
case MEDIA_BUS_FMT_SGBRG10_1X10:
1022+
ret = cci_multi_reg_write(sensor->regmap,
1023+
imx415_10bit_readout,
1024+
ARRAY_SIZE(imx415_10bit_readout),
1025+
NULL);
1026+
break;
1027+
case MEDIA_BUS_FMT_SGBRG12_1X12:
1028+
ret = cci_multi_reg_write(sensor->regmap,
1029+
imx415_12bit_readout,
1030+
ARRAY_SIZE(imx415_12bit_readout),
1031+
NULL);
1032+
break;
1033+
}
1034+
if (ret)
1035+
return ret;
1036+
10111037
return imx415_set_mode(sensor, sensor->cur_mode);
10121038
}
10131039

@@ -1103,10 +1129,16 @@ static int imx415_enum_mbus_code(struct v4l2_subdev *sd,
11031129
struct v4l2_subdev_state *state,
11041130
struct v4l2_subdev_mbus_code_enum *code)
11051131
{
1106-
if (code->index != 0)
1132+
switch (code->index) {
1133+
default:
11071134
return -EINVAL;
1108-
1109-
code->code = MEDIA_BUS_FMT_SGBRG10_1X10;
1135+
case 0:
1136+
code->code = MEDIA_BUS_FMT_SGBRG10_1X10;
1137+
break;
1138+
case 1:
1139+
code->code = MEDIA_BUS_FMT_SGBRG12_1X12;
1140+
break;
1141+
}
11101142

11111143
return 0;
11121144
}
@@ -1119,7 +1151,8 @@ static int imx415_enum_frame_size(struct v4l2_subdev *sd,
11191151

11201152
format = v4l2_subdev_state_get_format(state, fse->pad);
11211153

1122-
if (fse->index > 0 || fse->code != format->code)
1154+
if (fse->index > 0 || (fse->code != MEDIA_BUS_FMT_SGBRG10_1X10 &&
1155+
fse->code != MEDIA_BUS_FMT_SGBRG12_1X12))
11231156
return -EINVAL;
11241157

11251158
fse->min_width = IMX415_PIXEL_ARRAY_WIDTH;
@@ -1139,7 +1172,14 @@ static int imx415_set_format(struct v4l2_subdev *sd,
11391172

11401173
format->width = fmt->format.width;
11411174
format->height = fmt->format.height;
1142-
format->code = MEDIA_BUS_FMT_SGBRG10_1X10;
1175+
switch (fmt->format.code) {
1176+
case MEDIA_BUS_FMT_SGBRG10_1X10:
1177+
case MEDIA_BUS_FMT_SGBRG12_1X12:
1178+
format->code = fmt->format.code;
1179+
break;
1180+
default:
1181+
format->code = MEDIA_BUS_FMT_SGBRG10_1X10;
1182+
}
11431183
format->field = V4L2_FIELD_NONE;
11441184
format->colorspace = V4L2_COLORSPACE_RAW;
11451185
format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;

0 commit comments

Comments
 (0)