Commit 1c6a2b63 authored by Janusz Krzysztofik's avatar Janusz Krzysztofik Committed by Mauro Carvalho Chehab

media: ov6650: Fix some format attributes not under control

User arguments passed to .get/set_fmt() pad operation callbacks may
contain unsupported values.  The driver takes control over frame size
and pixel code as well as colorspace and field attributes but has never
cared for remainig format attributes, i.e., ycbcr_enc, quantization
and xfer_func, introduced by commit 11ff030c ("[media]
v4l2-mediabus: improve colorspace support").  Fix it.

Set up a static v4l2_mbus_framefmt structure with attributes
initialized to reasonable defaults and use it for updating content of
user provided arguments.  In case of V4L2_SUBDEV_FORMAT_ACTIVE,
postpone frame size update, now performed from inside ov6650_s_fmt()
helper, util the user argument is first updated in ov6650_set_fmt() with
default frame format content.  For V4L2_SUBDEV_FORMAT_TRY, don't copy
all attributes to pad config, only those handled by the driver, then
fill the response with the default frame format updated with resulting
pad config format code and frame size.

Fixes: 11ff030c ("[media] v4l2-mediabus: improve colorspace support")
Signed-off-by: default avatarJanusz Krzysztofik <jmkrzyszt@gmail.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 12500731
...@@ -212,6 +212,17 @@ static u32 ov6650_codes[] = { ...@@ -212,6 +212,17 @@ static u32 ov6650_codes[] = {
MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8,
}; };
static const struct v4l2_mbus_framefmt ov6650_def_fmt = {
.width = W_CIF,
.height = H_CIF,
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.colorspace = V4L2_COLORSPACE_SRGB,
.field = V4L2_FIELD_NONE,
.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
.quantization = V4L2_QUANTIZATION_DEFAULT,
.xfer_func = V4L2_XFER_FUNC_DEFAULT,
};
/* read a register */ /* read a register */
static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
{ {
...@@ -510,11 +521,13 @@ static int ov6650_get_fmt(struct v4l2_subdev *sd, ...@@ -510,11 +521,13 @@ static int ov6650_get_fmt(struct v4l2_subdev *sd,
if (format->pad) if (format->pad)
return -EINVAL; return -EINVAL;
/* initialize response with default media bus frame format */
*mf = ov6650_def_fmt;
/* update media bus format code and frame size */
mf->width = priv->rect.width >> priv->half_scale; mf->width = priv->rect.width >> priv->half_scale;
mf->height = priv->rect.height >> priv->half_scale; mf->height = priv->rect.height >> priv->half_scale;
mf->code = priv->code; mf->code = priv->code;
mf->colorspace = V4L2_COLORSPACE_SRGB;
mf->field = V4L2_FIELD_NONE;
return 0; return 0;
} }
...@@ -650,10 +663,6 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) ...@@ -650,10 +663,6 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
if (!ret) if (!ret)
ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask);
if (!ret) {
mf->width = priv->rect.width >> half_scale;
mf->height = priv->rect.height >> half_scale;
}
return ret; return ret;
} }
...@@ -672,9 +681,6 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd, ...@@ -672,9 +681,6 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
v4l_bound_align_image(&mf->width, 2, W_CIF, 1, v4l_bound_align_image(&mf->width, 2, W_CIF, 1,
&mf->height, 2, H_CIF, 1, 0); &mf->height, 2, H_CIF, 1, 0);
mf->field = V4L2_FIELD_NONE;
mf->colorspace = V4L2_COLORSPACE_SRGB;
switch (mf->code) { switch (mf->code) {
case MEDIA_BUS_FMT_Y10_1X10: case MEDIA_BUS_FMT_Y10_1X10:
mf->code = MEDIA_BUS_FMT_Y8_1X8; mf->code = MEDIA_BUS_FMT_Y8_1X8;
...@@ -692,10 +698,31 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd, ...@@ -692,10 +698,31 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
break; break;
} }
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
return ov6650_s_fmt(sd, mf); /* store media bus format code and frame size in pad config */
cfg->try_fmt = *mf; cfg->try_fmt.width = mf->width;
cfg->try_fmt.height = mf->height;
cfg->try_fmt.code = mf->code;
/* return default mbus frame format updated with pad config */
*mf = ov6650_def_fmt;
mf->width = cfg->try_fmt.width;
mf->height = cfg->try_fmt.height;
mf->code = cfg->try_fmt.code;
} else {
/* apply new media bus format code and frame size */
int ret = ov6650_s_fmt(sd, mf);
if (ret)
return ret;
/* return default format updated with active size and code */
*mf = ov6650_def_fmt;
mf->width = priv->rect.width >> priv->half_scale;
mf->height = priv->rect.height >> priv->half_scale;
mf->code = priv->code;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment