Commit 69c80dc9 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] ov772x: Don't fail in s_fmt if the requested format isn't supported



Select a default format instead.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent ca9ef7fa
Loading
Loading
Loading
Loading
+43 −40
Original line number Diff line number Diff line
@@ -581,11 +581,6 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
		return 0;
	}

	if (!priv->win || !priv->cfmt) {
		dev_err(&client->dev, "norm or win select error\n");
		return -EPERM;
	}

	ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);

	dev_dbg(&client->dev, "format %d, win %s\n",
@@ -710,31 +705,33 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
	return win;
}

static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
			     enum v4l2_mbus_pixelcode code)
static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
				 const struct ov772x_color_format **cfmt,
				 const struct ov772x_win_size **win)
{
	struct ov772x_priv *priv = to_ov772x(client);
	int ret = -EINVAL;
	u8  val;
	int i;
	unsigned int i;

	/* Select a format. */
	*cfmt = &ov772x_cfmts[0];

	/*
	 * select format
	 */
	priv->cfmt = NULL;
	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
		if (code == ov772x_cfmts[i].code) {
			priv->cfmt = ov772x_cfmts + i;
		if (mf->code == ov772x_cfmts[i].code) {
			*cfmt = &ov772x_cfmts[i];
			break;
		}
	}
	if (!priv->cfmt)
		goto ov772x_set_fmt_error;

	/*
	 * select win
	 */
	priv->win = ov772x_select_win(*width, *height);
	/* Select a window size. */
	*win = ov772x_select_win(mf->width, mf->height);
}

static int ov772x_set_params(struct ov772x_priv *priv,
			     const struct ov772x_color_format *cfmt,
			     const struct ov772x_win_size *win)
{
	struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
	int ret;
	u8  val;

	/*
	 * reset hardware
@@ -791,14 +788,14 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
	/*
	 * set size format
	 */
	ret = ov772x_write_array(client, priv->win->regs);
	ret = ov772x_write_array(client, win->regs);
	if (ret < 0)
		goto ov772x_set_fmt_error;

	/*
	 * set DSP_CTRL3
	 */
	val = priv->cfmt->dsp3;
	val = cfmt->dsp3;
	if (val) {
		ret = ov772x_mask_set(client,
				      DSP_CTRL3, UV_MASK, val);
@@ -809,7 +806,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
	/*
	 * set COM3
	 */
	val = priv->cfmt->com3;
	val = cfmt->com3;
	if (priv->info->flags & OV772X_FLAG_VFLIP)
		val |= VFLIP_IMG;
	if (priv->info->flags & OV772X_FLAG_HFLIP)
@@ -827,7 +824,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
	/*
	 * set COM7
	 */
	val = priv->win->com7_bit | priv->cfmt->com7;
	val = win->com7_bit | cfmt->com7;
	ret = ov772x_mask_set(client,
			      COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
			      val);
@@ -846,16 +843,11 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
			goto ov772x_set_fmt_error;
	}

	*width = priv->win->width;
	*height = priv->win->height;

	return ret;

ov772x_set_fmt_error:

	ov772x_reset(client);
	priv->win = NULL;
	priv->cfmt = NULL;

	return ret;
}
@@ -899,18 +891,29 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd,
	return 0;
}

static int ov772x_s_fmt(struct v4l2_subdev *sd,
			struct v4l2_mbus_framefmt *mf)
static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
	int ret = ov772x_set_params(client, &mf->width, &mf->height,
				    mf->code);
	const struct ov772x_color_format *cfmt;
	const struct ov772x_win_size *win;
	int ret;

	if (!ret)
		mf->colorspace = priv->cfmt->colorspace;
	ov772x_select_params(mf, &cfmt, &win);

	ret = ov772x_set_params(priv, cfmt, win);
	if (ret < 0)
		return ret;

	priv->win = win;
	priv->cfmt = cfmt;

	mf->code = cfmt->code;
	mf->width = win->width;
	mf->height = win->height;
	mf->field = V4L2_FIELD_NONE;
	mf->colorspace = cfmt->colorspace;

	return 0;
}

static int ov772x_try_fmt(struct v4l2_subdev *sd,