summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/media/i2c/soc_camera
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/media/i2c/soc_camera')
-rw-r--r--kernel/drivers/media/i2c/soc_camera/imx074.c66
-rw-r--r--kernel/drivers/media/i2c/soc_camera/mt9m001.c43
-rw-r--r--kernel/drivers/media/i2c/soc_camera/mt9m111.c57
-rw-r--r--kernel/drivers/media/i2c/soc_camera/mt9t031.c74
-rw-r--r--kernel/drivers/media/i2c/soc_camera/mt9t112.c49
-rw-r--r--kernel/drivers/media/i2c/soc_camera/mt9v022.c43
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov2640.c62
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov5642.c60
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov6650.c43
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov772x.c41
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov9640.c32
-rw-r--r--kernel/drivers/media/i2c/soc_camera/ov9740.c35
-rw-r--r--kernel/drivers/media/i2c/soc_camera/rj54n1cb0c.c66
-rw-r--r--kernel/drivers/media/i2c/soc_camera/tw9910.c76
14 files changed, 463 insertions, 284 deletions
diff --git a/kernel/drivers/media/i2c/soc_camera/imx074.c b/kernel/drivers/media/i2c/soc_camera/imx074.c
index ec89cfa92..f68c2352c 100644
--- a/kernel/drivers/media/i2c/soc_camera/imx074.c
+++ b/kernel/drivers/media/i2c/soc_camera/imx074.c
@@ -153,14 +153,24 @@ static int reg_read(struct i2c_client *client, const u16 addr)
return buf[0] & 0xff; /* no sign-extension */
}
-static int imx074_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int imx074_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
const struct imx074_datafmt *fmt = imx074_find_datafmt(mf->code);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct imx074 *priv = to_imx074(client);
+
+ if (format->pad)
+ return -EINVAL;
dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
if (!fmt) {
+ /* MIPI CSI could have changed the format, double-check */
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
mf->code = imx074_colour_fmts[0].code;
mf->colorspace = imx074_colour_fmts[0].colorspace;
}
@@ -169,36 +179,27 @@ static int imx074_try_fmt(struct v4l2_subdev *sd,
mf->height = IMX074_HEIGHT;
mf->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static int imx074_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct imx074 *priv = to_imx074(client);
-
- dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
-
- /* MIPI CSI could have changed the format, double-check */
- if (!imx074_find_datafmt(mf->code))
- return -EINVAL;
-
- imx074_try_fmt(sd, mf);
-
- priv->fmt = imx074_find_datafmt(mf->code);
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ priv->fmt = imx074_find_datafmt(mf->code);
+ else
+ cfg->try_fmt = *mf;
return 0;
}
-static int imx074_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int imx074_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct imx074 *priv = to_imx074(client);
const struct imx074_datafmt *fmt = priv->fmt;
+ if (format->pad)
+ return -EINVAL;
+
mf->code = fmt->code;
mf->colorspace = fmt->colorspace;
mf->width = IMX074_WIDTH;
@@ -235,13 +236,15 @@ static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int imx074_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts))
+ if (code->pad ||
+ (unsigned int)code->index >= ARRAY_SIZE(imx074_colour_fmts))
return -EINVAL;
- *code = imx074_colour_fmts[index].code;
+ code->code = imx074_colour_fmts[code->index].code;
return 0;
}
@@ -275,10 +278,6 @@ static int imx074_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
.s_stream = imx074_s_stream,
- .s_mbus_fmt = imx074_s_fmt,
- .g_mbus_fmt = imx074_g_fmt,
- .try_mbus_fmt = imx074_try_fmt,
- .enum_mbus_fmt = imx074_enum_fmt,
.g_crop = imx074_g_crop,
.cropcap = imx074_cropcap,
.g_mbus_config = imx074_g_mbus_config,
@@ -288,9 +287,16 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
.s_power = imx074_s_power,
};
+static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = {
+ .enum_mbus_code = imx074_enum_mbus_code,
+ .get_fmt = imx074_get_fmt,
+ .set_fmt = imx074_set_fmt,
+};
+
static struct v4l2_subdev_ops imx074_subdev_ops = {
.core = &imx074_subdev_core_ops,
.video = &imx074_subdev_video_ops,
+ .pad = &imx074_subdev_pad_ops,
};
static int imx074_video_probe(struct i2c_client *client)
diff --git a/kernel/drivers/media/i2c/soc_camera/mt9m001.c b/kernel/drivers/media/i2c/soc_camera/mt9m001.c
index 2e9a53502..4fbdd1e9f 100644
--- a/kernel/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/kernel/drivers/media/i2c/soc_camera/mt9m001.c
@@ -205,7 +205,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
/*
* The caller provides a supported format, as verified per
- * call to .try_mbus_fmt()
+ * call to .set_fmt(FORMAT_TRY).
*/
if (!ret)
ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
@@ -250,11 +250,16 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9m001_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m001_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
+ struct v4l2_mbus_framefmt *mf = &format->format;
+
+ if (format->pad)
+ return -EINVAL;
mf->width = mt9m001->rect.width;
mf->height = mt9m001->rect.height;
@@ -293,13 +298,18 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int mt9m001_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m001_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
const struct mt9m001_datafmt *fmt;
+ if (format->pad)
+ return -EINVAL;
+
v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
MT9M001_MAX_WIDTH, 1,
&mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
@@ -317,6 +327,9 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd,
mf->colorspace = fmt->colorspace;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return mt9m001_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
@@ -562,16 +575,17 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
.s_power = mt9m001_s_power,
};
-static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
- if (index >= mt9m001->num_fmts)
+ if (code->pad || code->index >= mt9m001->num_fmts)
return -EINVAL;
- *code = mt9m001->fmts[index].code;
+ code->code = mt9m001->fmts[code->index].code;
return 0;
}
@@ -611,13 +625,9 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
.s_stream = mt9m001_s_stream,
- .s_mbus_fmt = mt9m001_s_fmt,
- .g_mbus_fmt = mt9m001_g_fmt,
- .try_mbus_fmt = mt9m001_try_fmt,
.s_crop = mt9m001_s_crop,
.g_crop = mt9m001_g_crop,
.cropcap = mt9m001_cropcap,
- .enum_mbus_fmt = mt9m001_enum_fmt,
.g_mbus_config = mt9m001_g_mbus_config,
.s_mbus_config = mt9m001_s_mbus_config,
};
@@ -626,10 +636,17 @@ static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
.g_skip_top_lines = mt9m001_g_skip_top_lines,
};
+static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
+ .enum_mbus_code = mt9m001_enum_mbus_code,
+ .get_fmt = mt9m001_get_fmt,
+ .set_fmt = mt9m001_set_fmt,
+};
+
static struct v4l2_subdev_ops mt9m001_subdev_ops = {
.core = &mt9m001_subdev_core_ops,
.video = &mt9m001_subdev_video_ops,
.sensor = &mt9m001_subdev_sensor_ops,
+ .pad = &mt9m001_subdev_pad_ops,
};
static int mt9m001_probe(struct i2c_client *client,
diff --git a/kernel/drivers/media/i2c/soc_camera/mt9m111.c b/kernel/drivers/media/i2c/soc_camera/mt9m111.c
index 441e0fda2..6dfaead6a 100644
--- a/kernel/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/kernel/drivers/media/i2c/soc_camera/mt9m111.c
@@ -447,11 +447,16 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9m111_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m111_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = mt9m111->width;
mf->height = mt9m111->height;
mf->code = mt9m111->fmt->code;
@@ -531,14 +536,20 @@ static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111,
return ret;
}
-static int mt9m111_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9m111_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
const struct mt9m111_datafmt *fmt;
struct v4l2_rect *rect = &mt9m111->rect;
bool bayer;
+ int ret;
+
+ if (format->pad)
+ return -EINVAL;
fmt = mt9m111_find_datafmt(mt9m111, mf->code);
@@ -572,20 +583,10 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd,
mf->code = fmt->code;
mf->colorspace = fmt->colorspace;
- return 0;
-}
-
-static int mt9m111_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- const struct mt9m111_datafmt *fmt;
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- struct v4l2_rect *rect = &mt9m111->rect;
- int ret;
-
- mt9m111_try_fmt(sd, mf);
- fmt = mt9m111_find_datafmt(mt9m111, mf->code);
- /* try_fmt() guarantees fmt != NULL && fmt->code == mf->code */
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ cfg->try_fmt = *mf;
+ return 0;
+ }
ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code);
if (!ret)
@@ -839,13 +840,14 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
#endif
};
-static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(mt9m111_colour_fmts))
+ if (code->pad || code->index >= ARRAY_SIZE(mt9m111_colour_fmts))
return -EINVAL;
- *code = mt9m111_colour_fmts[index].code;
+ code->code = mt9m111_colour_fmts[code->index].code;
return 0;
}
@@ -865,19 +867,22 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
}
static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
- .s_mbus_fmt = mt9m111_s_fmt,
- .g_mbus_fmt = mt9m111_g_fmt,
- .try_mbus_fmt = mt9m111_try_fmt,
.s_crop = mt9m111_s_crop,
.g_crop = mt9m111_g_crop,
.cropcap = mt9m111_cropcap,
- .enum_mbus_fmt = mt9m111_enum_fmt,
.g_mbus_config = mt9m111_g_mbus_config,
};
+static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
+ .enum_mbus_code = mt9m111_enum_mbus_code,
+ .get_fmt = mt9m111_get_fmt,
+ .set_fmt = mt9m111_set_fmt,
+};
+
static struct v4l2_subdev_ops mt9m111_subdev_ops = {
.core = &mt9m111_subdev_core_ops,
.video = &mt9m111_subdev_video_ops,
+ .pad = &mt9m111_subdev_pad_ops,
};
/*
diff --git a/kernel/drivers/media/i2c/soc_camera/mt9t031.c b/kernel/drivers/media/i2c/soc_camera/mt9t031.c
index 35d9c8d25..3b6eeed2e 100644
--- a/kernel/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/kernel/drivers/media/i2c/soc_camera/mt9t031.c
@@ -264,7 +264,7 @@ static int mt9t031_set_params(struct i2c_client *client,
/*
* The caller provides a supported format, as guaranteed by
- * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap()
+ * .set_fmt(FORMAT_TRY), soc_camera_s_crop() and soc_camera_cropcap()
*/
if (ret >= 0)
ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
@@ -337,12 +337,17 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9t031_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t031_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = mt9t031->rect.width / mt9t031->xskip;
mf->height = mt9t031->rect.height / mt9t031->yskip;
mf->code = MEDIA_BUS_FMT_SBGGR10_1X10;
@@ -352,16 +357,36 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int mt9t031_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+/*
+ * If a user window larger than sensor window is requested, we'll increase the
+ * sensor window.
+ */
+static int mt9t031_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
u16 xskip, yskip;
struct v4l2_rect rect = mt9t031->rect;
+ if (format->pad)
+ return -EINVAL;
+
+ mf->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
+ v4l_bound_align_image(
+ &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
+ &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ cfg->try_fmt = *mf;
+ return 0;
+ }
+
/*
- * try_fmt has put width and height within limits.
+ * Width and height are within limits.
* S_FMT: use binning and skipping for scaling
*/
xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
@@ -374,23 +399,6 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
return mt9t031_set_params(client, &rect, xskip, yskip);
}
-/*
- * If a user window larger than sensor window is requested, we'll increase the
- * sensor window.
- */
-static int mt9t031_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- v4l_bound_align_image(
- &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1,
- &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0);
-
- mf->code = MEDIA_BUS_FMT_SBGGR10_1X10;
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9t031_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -672,13 +680,14 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
#endif
};
-static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int mt9t031_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index)
+ if (code->pad || code->index)
return -EINVAL;
- *code = MEDIA_BUS_FMT_SBGGR10_1X10;
+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
return 0;
}
@@ -712,13 +721,9 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
.s_stream = mt9t031_s_stream,
- .s_mbus_fmt = mt9t031_s_fmt,
- .g_mbus_fmt = mt9t031_g_fmt,
- .try_mbus_fmt = mt9t031_try_fmt,
.s_crop = mt9t031_s_crop,
.g_crop = mt9t031_g_crop,
.cropcap = mt9t031_cropcap,
- .enum_mbus_fmt = mt9t031_enum_fmt,
.g_mbus_config = mt9t031_g_mbus_config,
.s_mbus_config = mt9t031_s_mbus_config,
};
@@ -727,10 +732,17 @@ static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
.g_skip_top_lines = mt9t031_g_skip_top_lines,
};
+static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = {
+ .enum_mbus_code = mt9t031_enum_mbus_code,
+ .get_fmt = mt9t031_get_fmt,
+ .set_fmt = mt9t031_set_fmt,
+};
+
static struct v4l2_subdev_ops mt9t031_subdev_ops = {
.core = &mt9t031_subdev_core_ops,
.video = &mt9t031_subdev_video_ops,
.sensor = &mt9t031_subdev_sensor_ops,
+ .pad = &mt9t031_subdev_pad_ops,
};
static int mt9t031_probe(struct i2c_client *client,
diff --git a/kernel/drivers/media/i2c/soc_camera/mt9t112.c b/kernel/drivers/media/i2c/soc_camera/mt9t112.c
index 64f08365e..2f35d31ca 100644
--- a/kernel/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/kernel/drivers/media/i2c/soc_camera/mt9t112.c
@@ -104,22 +104,22 @@ struct mt9t112_priv {
static const struct mt9t112_format mt9t112_cfmts[] = {
{
.code = MEDIA_BUS_FMT_UYVY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 0,
}, {
.code = MEDIA_BUS_FMT_VYUY8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 1,
}, {
.code = MEDIA_BUS_FMT_YUYV8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 2,
}, {
.code = MEDIA_BUS_FMT_YVYU8_2X8,
- .colorspace = V4L2_COLORSPACE_JPEG,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 3,
}, {
@@ -904,12 +904,17 @@ static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return mt9t112_set_params(priv, rect, priv->format->code);
}
-static int mt9t112_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t112_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = priv->frame.width;
mf->height = priv->frame.height;
mf->colorspace = priv->format->colorspace;
@@ -940,14 +945,19 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int mt9t112_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9t112_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
unsigned int top, left;
int i;
+ if (format->pad)
+ return -EINVAL;
+
for (i = 0; i < priv->num_formats; i++)
if (mt9t112_cfmts[i].code == mf->code)
break;
@@ -963,19 +973,23 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd,
mf->field = V4L2_FIELD_NONE;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return mt9t112_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
-static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
- if (index >= priv->num_formats)
+ if (code->pad || code->index >= priv->num_formats)
return -EINVAL;
- *code = mt9t112_cfmts[index].code;
+ code->code = mt9t112_cfmts[code->index].code;
return 0;
}
@@ -1010,23 +1024,26 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
.s_stream = mt9t112_s_stream,
- .g_mbus_fmt = mt9t112_g_fmt,
- .s_mbus_fmt = mt9t112_s_fmt,
- .try_mbus_fmt = mt9t112_try_fmt,
.cropcap = mt9t112_cropcap,
.g_crop = mt9t112_g_crop,
.s_crop = mt9t112_s_crop,
- .enum_mbus_fmt = mt9t112_enum_fmt,
.g_mbus_config = mt9t112_g_mbus_config,
.s_mbus_config = mt9t112_s_mbus_config,
};
+static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = {
+ .enum_mbus_code = mt9t112_enum_mbus_code,
+ .get_fmt = mt9t112_get_fmt,
+ .set_fmt = mt9t112_set_fmt,
+};
+
/************************************************************************
i2c driver
************************************************************************/
static struct v4l2_subdev_ops mt9t112_subdev_ops = {
.core = &mt9t112_subdev_core_ops,
.video = &mt9t112_subdev_video_ops,
+ .pad = &mt9t112_subdev_pad_ops,
};
static int mt9t112_camera_probe(struct i2c_client *client)
diff --git a/kernel/drivers/media/i2c/soc_camera/mt9v022.c b/kernel/drivers/media/i2c/soc_camera/mt9v022.c
index a246d4d64..f31377408 100644
--- a/kernel/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/kernel/drivers/media/i2c/soc_camera/mt9v022.c
@@ -375,12 +375,17 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int mt9v022_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9v022_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = mt9v022->rect.width;
mf->height = mt9v022->rect.height;
mf->code = mt9v022->fmt->code;
@@ -407,7 +412,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
/*
* The caller provides a supported format, as verified per call to
- * .try_mbus_fmt(), datawidth is from our supported format list
+ * .set_fmt(FORMAT_TRY), datawidth is from our supported format list
*/
switch (mf->code) {
case MEDIA_BUS_FMT_Y8_1X8:
@@ -437,15 +442,20 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int mt9v022_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int mt9v022_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
const struct mt9v022_datafmt *fmt;
int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
mf->code == MEDIA_BUS_FMT_SBGGR10_1X10;
+ if (format->pad)
+ return -EINVAL;
+
v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
MT9V022_MAX_WIDTH, align,
&mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
@@ -460,6 +470,9 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd,
mf->colorspace = fmt->colorspace;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return mt9v022_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
@@ -758,16 +771,17 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
.s_power = mt9v022_s_power,
};
-static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
- if (index >= mt9v022->num_fmts)
+ if (code->pad || code->index >= mt9v022->num_fmts)
return -EINVAL;
- *code = mt9v022->fmts[index].code;
+ code->code = mt9v022->fmts[code->index].code;
return 0;
}
@@ -839,13 +853,9 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
.s_stream = mt9v022_s_stream,
- .s_mbus_fmt = mt9v022_s_fmt,
- .g_mbus_fmt = mt9v022_g_fmt,
- .try_mbus_fmt = mt9v022_try_fmt,
.s_crop = mt9v022_s_crop,
.g_crop = mt9v022_g_crop,
.cropcap = mt9v022_cropcap,
- .enum_mbus_fmt = mt9v022_enum_fmt,
.g_mbus_config = mt9v022_g_mbus_config,
.s_mbus_config = mt9v022_s_mbus_config,
};
@@ -854,10 +864,17 @@ static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
.g_skip_top_lines = mt9v022_g_skip_top_lines,
};
+static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
+ .enum_mbus_code = mt9v022_enum_mbus_code,
+ .get_fmt = mt9v022_get_fmt,
+ .set_fmt = mt9v022_set_fmt,
+};
+
static struct v4l2_subdev_ops mt9v022_subdev_ops = {
.core = &mt9v022_subdev_core_ops,
.video = &mt9v022_subdev_video_ops,
.sensor = &mt9v022_subdev_sensor_ops,
+ .pad = &mt9v022_subdev_pad_ops,
};
static int mt9v022_probe(struct i2c_client *client,
diff --git a/kernel/drivers/media/i2c/soc_camera/ov2640.c b/kernel/drivers/media/i2c/soc_camera/ov2640.c
index e3c907a97..9b4f5deec 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov2640.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov2640.c
@@ -845,12 +845,17 @@ err:
return ret;
}
-static int ov2640_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov2640_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov2640_priv *priv = to_ov2640(client);
+ if (format->pad)
+ return -EINVAL;
+
if (!priv->win) {
u32 width = SVGA_WIDTH, height = SVGA_HEIGHT;
priv->win = ov2640_select_win(&width, &height);
@@ -876,33 +881,16 @@ static int ov2640_g_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int ov2640_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov2640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
+ if (format->pad)
+ return -EINVAL;
- switch (mf->code) {
- case MEDIA_BUS_FMT_RGB565_2X8_BE:
- case MEDIA_BUS_FMT_RGB565_2X8_LE:
- mf->colorspace = V4L2_COLORSPACE_SRGB;
- break;
- default:
- mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
- case MEDIA_BUS_FMT_YUYV8_2X8:
- case MEDIA_BUS_FMT_UYVY8_2X8:
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- }
-
- ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
-
- return ret;
-}
-
-static int ov2640_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
/*
* select suitable win, but don't store it
*/
@@ -922,16 +910,21 @@ static int ov2640_try_fmt(struct v4l2_subdev *sd,
mf->colorspace = V4L2_COLORSPACE_JPEG;
}
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ov2640_set_params(client, &mf->width,
+ &mf->height, mf->code);
+ cfg->try_fmt = *mf;
return 0;
}
-static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov2640_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov2640_codes))
+ if (code->pad || code->index >= ARRAY_SIZE(ov2640_codes))
return -EINVAL;
- *code = ov2640_codes[index];
+ code->code = ov2640_codes[code->index];
return 0;
}
@@ -1031,18 +1024,21 @@ static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
.s_stream = ov2640_s_stream,
- .g_mbus_fmt = ov2640_g_fmt,
- .s_mbus_fmt = ov2640_s_fmt,
- .try_mbus_fmt = ov2640_try_fmt,
.cropcap = ov2640_cropcap,
.g_crop = ov2640_g_crop,
- .enum_mbus_fmt = ov2640_enum_fmt,
.g_mbus_config = ov2640_g_mbus_config,
};
+static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = {
+ .enum_mbus_code = ov2640_enum_mbus_code,
+ .get_fmt = ov2640_get_fmt,
+ .set_fmt = ov2640_set_fmt,
+};
+
static struct v4l2_subdev_ops ov2640_subdev_ops = {
.core = &ov2640_subdev_core_ops,
.video = &ov2640_subdev_video_ops,
+ .pad = &ov2640_subdev_pad_ops,
};
/* OF probe functions */
diff --git a/kernel/drivers/media/i2c/soc_camera/ov5642.c b/kernel/drivers/media/i2c/soc_camera/ov5642.c
index 93ae031bd..bab9ac0c1 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov5642.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov5642.c
@@ -786,50 +786,50 @@ static int ov5642_set_resolution(struct v4l2_subdev *sd)
return ret;
}
-static int ov5642_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov5642_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5642 *priv = to_ov5642(client);
const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = priv->crop_rect.width;
mf->height = priv->crop_rect.height;
if (!fmt) {
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
mf->code = ov5642_colour_fmts[0].code;
mf->colorspace = ov5642_colour_fmts[0].colorspace;
}
mf->field = V4L2_FIELD_NONE;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ priv->fmt = ov5642_find_datafmt(mf->code);
+ else
+ cfg->try_fmt = *mf;
return 0;
}
-static int ov5642_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5642 *priv = to_ov5642(client);
-
- /* MIPI CSI could have changed the format, double-check */
- if (!ov5642_find_datafmt(mf->code))
- return -EINVAL;
-
- ov5642_try_fmt(sd, mf);
- priv->fmt = ov5642_find_datafmt(mf->code);
-
- return 0;
-}
-
-static int ov5642_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov5642_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5642 *priv = to_ov5642(client);
const struct ov5642_datafmt *fmt = priv->fmt;
+ if (format->pad)
+ return -EINVAL;
+
mf->code = fmt->code;
mf->colorspace = fmt->colorspace;
mf->width = priv->crop_rect.width;
@@ -839,13 +839,14 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov5642_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov5642_colour_fmts))
+ if (code->pad || code->index >= ARRAY_SIZE(ov5642_colour_fmts))
return -EINVAL;
- *code = ov5642_colour_fmts[index].code;
+ code->code = ov5642_colour_fmts[code->index].code;
return 0;
}
@@ -939,16 +940,18 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
}
static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
- .s_mbus_fmt = ov5642_s_fmt,
- .g_mbus_fmt = ov5642_g_fmt,
- .try_mbus_fmt = ov5642_try_fmt,
- .enum_mbus_fmt = ov5642_enum_fmt,
.s_crop = ov5642_s_crop,
.g_crop = ov5642_g_crop,
.cropcap = ov5642_cropcap,
.g_mbus_config = ov5642_g_mbus_config,
};
+static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = {
+ .enum_mbus_code = ov5642_enum_mbus_code,
+ .get_fmt = ov5642_get_fmt,
+ .set_fmt = ov5642_set_fmt,
+};
+
static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
.s_power = ov5642_s_power,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -960,6 +963,7 @@ static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
static struct v4l2_subdev_ops ov5642_subdev_ops = {
.core = &ov5642_subdev_core_ops,
.video = &ov5642_subdev_video_ops,
+ .pad = &ov5642_subdev_pad_ops,
};
static int ov5642_video_probe(struct i2c_client *client)
diff --git a/kernel/drivers/media/i2c/soc_camera/ov6650.c b/kernel/drivers/media/i2c/soc_camera/ov6650.c
index f4eef2fa6..1f8af1ee8 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov6650.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov6650.c
@@ -499,12 +499,17 @@ static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int ov6650_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov6650_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = priv->rect.width >> priv->half_scale;
mf->height = priv->rect.height >> priv->half_scale;
mf->code = priv->code;
@@ -680,16 +685,20 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
mf->width = priv->rect.width >> half_scale;
mf->height = priv->rect.height >> half_scale;
}
-
return ret;
}
-static int ov6650_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov6650_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
+ if (format->pad)
+ return -EINVAL;
+
if (is_unscaled_ok(mf->width, mf->height, &priv->rect))
v4l_bound_align_image(&mf->width, 2, W_CIF, 1,
&mf->height, 2, H_CIF, 1, 0);
@@ -713,16 +722,21 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd,
break;
}
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ov6650_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
+
return 0;
}
-static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov6650_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov6650_codes))
+ if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes))
return -EINVAL;
- *code = ov6650_codes[index];
+ code->code = ov6650_codes[code->index];
return 0;
}
@@ -929,10 +943,6 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov6650_video_ops = {
.s_stream = ov6650_s_stream,
- .g_mbus_fmt = ov6650_g_fmt,
- .s_mbus_fmt = ov6650_s_fmt,
- .try_mbus_fmt = ov6650_try_fmt,
- .enum_mbus_fmt = ov6650_enum_fmt,
.cropcap = ov6650_cropcap,
.g_crop = ov6650_g_crop,
.s_crop = ov6650_s_crop,
@@ -942,9 +952,16 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = {
.s_mbus_config = ov6650_s_mbus_config,
};
+static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
+ .enum_mbus_code = ov6650_enum_mbus_code,
+ .get_fmt = ov6650_get_fmt,
+ .set_fmt = ov6650_set_fmt,
+};
+
static struct v4l2_subdev_ops ov6650_subdev_ops = {
.core = &ov6650_core_ops,
.video = &ov6650_video_ops,
+ .pad = &ov6650_pad_ops,
};
/*
diff --git a/kernel/drivers/media/i2c/soc_camera/ov772x.c b/kernel/drivers/media/i2c/soc_camera/ov772x.c
index 8daac88b3..f150a8bd9 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov772x.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov772x.c
@@ -876,11 +876,16 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int ov772x_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov772x_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct ov772x_priv *priv = to_ov772x(sd);
+ if (format->pad)
+ return -EINVAL;
+
mf->width = priv->win->rect.width;
mf->height = priv->win->rect.height;
mf->code = priv->cfmt->code;
@@ -915,12 +920,17 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
return 0;
}
-static int ov772x_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov772x_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
const struct ov772x_color_format *cfmt;
const struct ov772x_win_size *win;
+ if (format->pad)
+ return -EINVAL;
+
ov772x_select_params(mf, &cfmt, &win);
mf->code = cfmt->code;
@@ -929,6 +939,9 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd,
mf->field = V4L2_FIELD_NONE;
mf->colorspace = cfmt->colorspace;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ov772x_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
@@ -989,13 +1002,14 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
.s_power = ov772x_s_power,
};
-static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov772x_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov772x_cfmts))
+ if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts))
return -EINVAL;
- *code = ov772x_cfmts[index].code;
+ code->code = ov772x_cfmts[code->index].code;
return 0;
}
@@ -1016,18 +1030,21 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
.s_stream = ov772x_s_stream,
- .g_mbus_fmt = ov772x_g_fmt,
- .s_mbus_fmt = ov772x_s_fmt,
- .try_mbus_fmt = ov772x_try_fmt,
.cropcap = ov772x_cropcap,
.g_crop = ov772x_g_crop,
- .enum_mbus_fmt = ov772x_enum_fmt,
.g_mbus_config = ov772x_g_mbus_config,
};
+static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = {
+ .enum_mbus_code = ov772x_enum_mbus_code,
+ .get_fmt = ov772x_get_fmt,
+ .set_fmt = ov772x_set_fmt,
+};
+
static struct v4l2_subdev_ops ov772x_subdev_ops = {
.core = &ov772x_subdev_core_ops,
.video = &ov772x_subdev_video_ops,
+ .pad = &ov772x_subdev_pad_ops,
};
/*
diff --git a/kernel/drivers/media/i2c/soc_camera/ov9640.c b/kernel/drivers/media/i2c/soc_camera/ov9640.c
index aa93d2e88..8caae1c07 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov9640.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov9640.c
@@ -519,9 +519,15 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int ov9640_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov9640_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+
+ if (format->pad)
+ return -EINVAL;
+
ov9640_res_roundup(&mf->width, &mf->height);
mf->field = V4L2_FIELD_NONE;
@@ -537,16 +543,21 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd,
mf->colorspace = V4L2_COLORSPACE_JPEG;
}
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ov9640_s_fmt(sd, mf);
+
+ cfg->try_fmt = *mf;
return 0;
}
-static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov9640_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov9640_codes))
+ if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes))
return -EINVAL;
- *code = ov9640_codes[index];
+ code->code = ov9640_codes[code->index];
return 0;
}
@@ -656,17 +667,20 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov9640_video_ops = {
.s_stream = ov9640_s_stream,
- .s_mbus_fmt = ov9640_s_fmt,
- .try_mbus_fmt = ov9640_try_fmt,
- .enum_mbus_fmt = ov9640_enum_fmt,
.cropcap = ov9640_cropcap,
.g_crop = ov9640_g_crop,
.g_mbus_config = ov9640_g_mbus_config,
};
+static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
+ .enum_mbus_code = ov9640_enum_mbus_code,
+ .set_fmt = ov9640_set_fmt,
+};
+
static struct v4l2_subdev_ops ov9640_subdev_ops = {
.core = &ov9640_core_ops,
.video = &ov9640_video_ops,
+ .pad = &ov9640_pad_ops,
};
/*
diff --git a/kernel/drivers/media/i2c/soc_camera/ov9740.c b/kernel/drivers/media/i2c/soc_camera/ov9740.c
index 841dc5545..03a7fc731 100644
--- a/kernel/drivers/media/i2c/soc_camera/ov9740.c
+++ b/kernel/drivers/media/i2c/soc_camera/ov9740.c
@@ -704,25 +704,35 @@ static int ov9740_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int ov9740_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov9740_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
+
+ if (format->pad)
+ return -EINVAL;
+
ov9740_res_roundup(&mf->width, &mf->height);
mf->field = V4L2_FIELD_NONE;
mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
mf->colorspace = V4L2_COLORSPACE_SRGB;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ov9740_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
-static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int ov9740_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(ov9740_codes))
+ if (code->pad || code->index >= ARRAY_SIZE(ov9740_codes))
return -EINVAL;
- *code = ov9740_codes[index];
+ code->code = ov9740_codes[code->index];
return 0;
}
@@ -904,9 +914,6 @@ static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov9740_video_ops = {
.s_stream = ov9740_s_stream,
- .s_mbus_fmt = ov9740_s_fmt,
- .try_mbus_fmt = ov9740_try_fmt,
- .enum_mbus_fmt = ov9740_enum_fmt,
.cropcap = ov9740_cropcap,
.g_crop = ov9740_g_crop,
.g_mbus_config = ov9740_g_mbus_config,
@@ -920,9 +927,15 @@ static struct v4l2_subdev_core_ops ov9740_core_ops = {
#endif
};
+static const struct v4l2_subdev_pad_ops ov9740_pad_ops = {
+ .enum_mbus_code = ov9740_enum_mbus_code,
+ .set_fmt = ov9740_set_fmt,
+};
+
static struct v4l2_subdev_ops ov9740_subdev_ops = {
- .core = &ov9740_core_ops,
- .video = &ov9740_video_ops,
+ .core = &ov9740_core_ops,
+ .video = &ov9740_video_ops,
+ .pad = &ov9740_pad_ops,
};
static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
diff --git a/kernel/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/kernel/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index 1752428c4..c769cf663 100644
--- a/kernel/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/kernel/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -485,13 +485,14 @@ static int reg_write_multiple(struct i2c_client *client,
return 0;
}
-static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int rj54n1_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index >= ARRAY_SIZE(rj54n1_colour_fmts))
+ if (code->pad || code->index >= ARRAY_SIZE(rj54n1_colour_fmts))
return -EINVAL;
- *code = rj54n1_colour_fmts[index].code;
+ code->code = rj54n1_colour_fmts[code->index].code;
return 0;
}
@@ -597,12 +598,17 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int rj54n1_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int rj54n1_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
+ if (format->pad)
+ return -EINVAL;
+
mf->code = rj54n1->fmt->code;
mf->colorspace = rj54n1->fmt->colorspace;
mf->field = V4L2_FIELD_NONE;
@@ -959,17 +965,25 @@ static int rj54n1_reg_init(struct i2c_client *client)
return ret;
}
-static int rj54n1_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int rj54n1_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
const struct rj54n1_datafmt *fmt;
+ int output_w, output_h, max_w, max_h,
+ input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE ||
mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE ||
mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE ||
mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE;
+ int ret;
+
+ if (format->pad)
+ return -EINVAL;
dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
__func__, mf->code, mf->width, mf->height);
@@ -987,24 +1001,10 @@ static int rj54n1_try_fmt(struct v4l2_subdev *sd,
v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
&mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
- return 0;
-}
-
-static int rj54n1_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct rj54n1_datafmt *fmt;
- int output_w, output_h, max_w, max_h,
- input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
- int ret;
-
- /*
- * The host driver can call us without .try_fmt(), so, we have to take
- * care ourseleves
- */
- rj54n1_try_fmt(sd, mf);
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ cfg->try_fmt = *mf;
+ return 0;
+ }
/*
* Verify if the sensor has just been powered on. TODO: replace this
@@ -1020,9 +1020,6 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd,
return ret;
}
- dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
- __func__, mf->code, mf->width, mf->height);
-
/* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
switch (mf->code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
@@ -1249,10 +1246,6 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
.s_stream = rj54n1_s_stream,
- .s_mbus_fmt = rj54n1_s_fmt,
- .g_mbus_fmt = rj54n1_g_fmt,
- .try_mbus_fmt = rj54n1_try_fmt,
- .enum_mbus_fmt = rj54n1_enum_fmt,
.g_crop = rj54n1_g_crop,
.s_crop = rj54n1_s_crop,
.cropcap = rj54n1_cropcap,
@@ -1260,9 +1253,16 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
.s_mbus_config = rj54n1_s_mbus_config,
};
+static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = {
+ .enum_mbus_code = rj54n1_enum_mbus_code,
+ .get_fmt = rj54n1_get_fmt,
+ .set_fmt = rj54n1_set_fmt,
+};
+
static struct v4l2_subdev_ops rj54n1_subdev_ops = {
.core = &rj54n1_subdev_core_ops,
.video = &rj54n1_subdev_video_ops,
+ .pad = &rj54n1_subdev_pad_ops,
};
/*
diff --git a/kernel/drivers/media/i2c/soc_camera/tw9910.c b/kernel/drivers/media/i2c/soc_camera/tw9910.c
index 9b853215d..e939c24bf 100644
--- a/kernel/drivers/media/i2c/soc_camera/tw9910.c
+++ b/kernel/drivers/media/i2c/soc_camera/tw9910.c
@@ -510,13 +510,39 @@ static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
+ const unsigned hact = 720;
+ const unsigned hdelay = 15;
+ unsigned vact;
+ unsigned vdelay;
+ int ret;
if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
return -EINVAL;
priv->norm = norm;
+ if (norm & V4L2_STD_525_60) {
+ vact = 240;
+ vdelay = 18;
+ ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
+ } else {
+ vact = 288;
+ vdelay = 24;
+ ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
+ }
+ if (!ret)
+ ret = i2c_smbus_write_byte_data(client, CROP_HI,
+ ((vdelay >> 2) & 0xc0) |
+ ((vact >> 4) & 0x30) |
+ ((hdelay >> 6) & 0x0c) |
+ ((hact >> 8) & 0x03));
+ if (!ret)
+ ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
+ vdelay & 0xff);
+ if (!ret)
+ ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
+ vact & 0xff);
- return 0;
+ return ret;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -691,12 +717,17 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
return 0;
}
-static int tw9910_g_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int tw9910_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
+ if (format->pad)
+ return -EINVAL;
+
if (!priv->scale) {
priv->scale = tw9910_select_norm(priv->norm, 640, 480);
if (!priv->scale)
@@ -706,7 +737,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
mf->width = priv->scale->width;
mf->height = priv->scale->height;
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
mf->field = V4L2_FIELD_INTERLACED_BT;
return 0;
@@ -727,7 +758,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
return -EINVAL;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
ret = tw9910_set_frame(sd, &width, &height);
if (!ret) {
@@ -737,13 +768,18 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
return ret;
}
-static int tw9910_try_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int tw9910_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
{
+ struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
const struct tw9910_scale_ctrl *scale;
+ if (format->pad)
+ return -EINVAL;
+
if (V4L2_FIELD_ANY == mf->field) {
mf->field = V4L2_FIELD_INTERLACED_BT;
} else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
@@ -752,7 +788,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
}
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
/*
* select suitable norm
@@ -764,6 +800,9 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
mf->width = scale->width;
mf->height = scale->height;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return tw9910_s_fmt(sd, mf);
+ cfg->try_fmt = *mf;
return 0;
}
@@ -807,6 +846,7 @@ static int tw9910_video_probe(struct i2c_client *client)
"tw9910 Product ID %0x:%0x\n", id, priv->revision);
priv->norm = V4L2_STD_NTSC;
+ priv->scale = &tw9910_ntsc_scales[0];
done:
tw9910_s_power(&priv->subdev, 0);
@@ -821,13 +861,14 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
.s_power = tw9910_s_power,
};
-static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
- u32 *code)
+static int tw9910_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
{
- if (index)
+ if (code->pad || code->index)
return -EINVAL;
- *code = MEDIA_BUS_FMT_UYVY8_2X8;
+ code->code = MEDIA_BUS_FMT_UYVY8_2X8;
return 0;
}
@@ -880,20 +921,23 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
.s_std = tw9910_s_std,
.g_std = tw9910_g_std,
.s_stream = tw9910_s_stream,
- .g_mbus_fmt = tw9910_g_fmt,
- .s_mbus_fmt = tw9910_s_fmt,
- .try_mbus_fmt = tw9910_try_fmt,
.cropcap = tw9910_cropcap,
.g_crop = tw9910_g_crop,
- .enum_mbus_fmt = tw9910_enum_fmt,
.g_mbus_config = tw9910_g_mbus_config,
.s_mbus_config = tw9910_s_mbus_config,
.g_tvnorms = tw9910_g_tvnorms,
};
+static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
+ .enum_mbus_code = tw9910_enum_mbus_code,
+ .get_fmt = tw9910_get_fmt,
+ .set_fmt = tw9910_set_fmt,
+};
+
static struct v4l2_subdev_ops tw9910_subdev_ops = {
.core = &tw9910_subdev_core_ops,
.video = &tw9910_subdev_video_ops,
+ .pad = &tw9910_subdev_pad_ops,
};
/*