summaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/soc_camera
diff options
context:
space:
mode:
authorHans Verkuil2015-12-14 11:25:32 +0100
committerMauro Carvalho Chehab2016-08-24 14:46:09 +0200
commit10d5509c8d50a2c2f761a08a616530dced35e2d8 (patch)
treee3140b6d25f56cce9fa4a7df00e7e14bb762f54f /drivers/media/i2c/soc_camera
parent[media] media: adv7180: add power pin control (diff)
downloadkernel-qcow2-linux-10d5509c8d50a2c2f761a08a616530dced35e2d8.tar.gz
kernel-qcow2-linux-10d5509c8d50a2c2f761a08a616530dced35e2d8.tar.xz
kernel-qcow2-linux-10d5509c8d50a2c2f761a08a616530dced35e2d8.zip
[media] v4l2: remove g/s_crop from video ops
Replace all calls to g/s_crop by calls to the get/set_selection pad ops. Remove the old g/s_crop video ops since they are now no longer used. The cropcap video op is now only used to pass pixelaspect information, and is only needed if the pixelaspect is not 1:1. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/i2c/soc_camera')
-rw-r--r--drivers/media/i2c/soc_camera/imx074.c42
-rw-r--r--drivers/media/i2c/soc_camera/mt9m001.c70
-rw-r--r--drivers/media/i2c/soc_camera/mt9m111.c57
-rw-r--r--drivers/media/i2c/soc_camera/mt9t031.c54
-rw-r--r--drivers/media/i2c/soc_camera/mt9t112.c60
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c68
-rw-r--r--drivers/media/i2c/soc_camera/ov2640.c41
-rw-r--r--drivers/media/i2c/soc_camera/ov5642.c53
-rw-r--r--drivers/media/i2c/soc_camera/ov6650.c74
-rw-r--r--drivers/media/i2c/soc_camera/ov772x.c44
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.c41
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c41
-rw-r--r--drivers/media/i2c/soc_camera/rj54n1cb0c.c52
-rw-r--r--drivers/media/i2c/soc_camera/tw9910.c47
14 files changed, 371 insertions, 373 deletions
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index f68c2352c63c..05b55cfe8147 100644
--- a/drivers/media/i2c/soc_camera/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -209,31 +209,26 @@ static int imx074_get_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int imx074_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int imx074_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- struct v4l2_rect *rect = &a->c;
-
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- rect->top = 0;
- rect->left = 0;
- rect->width = IMX074_WIDTH;
- rect->height = IMX074_HEIGHT;
-
- return 0;
-}
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
-static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = IMX074_WIDTH;
- a->bounds.height = IMX074_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = IMX074_WIDTH;
+ sel->r.height = IMX074_HEIGHT;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int imx074_enum_mbus_code(struct v4l2_subdev *sd,
@@ -278,8 +273,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,
- .g_crop = imx074_g_crop,
- .cropcap = imx074_cropcap,
.g_mbus_config = imx074_g_mbus_config,
};
@@ -289,6 +282,7 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = {
.enum_mbus_code = imx074_enum_mbus_code,
+ .get_selection = imx074_get_selection,
.get_fmt = imx074_get_fmt,
.set_fmt = imx074_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index 69becc358659..3d6378d4491c 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -171,13 +171,19 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int mt9m001_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
- struct v4l2_rect rect = a->c;
- int ret;
+ struct v4l2_rect rect = sel->r;
const u16 hblank = 9, vblank = 25;
+ int ret;
+
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
if (mt9m001->fmts == mt9m001_colour_fmts)
/*
@@ -225,29 +231,30 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return ret;
}
-static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9m001_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
- a->c = mt9m001->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9M001_COLUMN_SKIP;
- a->bounds.top = MT9M001_ROW_SKIP;
- a->bounds.width = MT9M001_MAX_WIDTH;
- a->bounds.height = MT9M001_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = MT9M001_COLUMN_SKIP;
+ sel->r.top = MT9M001_ROW_SKIP;
+ sel->r.width = MT9M001_MAX_WIDTH;
+ sel->r.height = MT9M001_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = mt9m001->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int mt9m001_get_fmt(struct v4l2_subdev *sd,
@@ -275,18 +282,18 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd,
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
- struct v4l2_crop a = {
- .c = {
- .left = mt9m001->rect.left,
- .top = mt9m001->rect.top,
- .width = mf->width,
- .height = mf->height,
- },
+ struct v4l2_subdev_selection sel = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .target = V4L2_SEL_TGT_CROP,
+ .r.left = mt9m001->rect.left,
+ .r.top = mt9m001->rect.top,
+ .r.width = mf->width,
+ .r.height = mf->height,
};
int ret;
/* No support for scaling so far, just crop. TODO: use skipping */
- ret = mt9m001_s_crop(sd, &a);
+ ret = mt9m001_set_selection(sd, NULL, &sel);
if (!ret) {
mf->width = mt9m001->rect.width;
mf->height = mt9m001->rect.height;
@@ -625,9 +632,6 @@ 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_crop = mt9m001_s_crop,
- .g_crop = mt9m001_g_crop,
- .cropcap = mt9m001_cropcap,
.g_mbus_config = mt9m001_g_mbus_config,
.s_mbus_config = mt9m001_s_mbus_config,
};
@@ -638,6 +642,8 @@ static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
.enum_mbus_code = mt9m001_enum_mbus_code,
+ .get_selection = mt9m001_get_selection,
+ .set_selection = mt9m001_set_selection,
.get_fmt = mt9m001_get_fmt,
.set_fmt = mt9m001_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 6dfaead6aaa8..6c8d1123658c 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -383,14 +383,18 @@ static int mt9m111_reset(struct mt9m111 *mt9m111)
return ret;
}
-static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int mt9m111_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- struct v4l2_rect rect = a->c;
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct mt9m111 *mt9m111 = to_mt9m111(client);
+ struct v4l2_rect rect = sel->r;
int width, height;
int ret;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
@@ -421,30 +425,30 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return ret;
}
-static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9m111_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
- a->c = mt9m111->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct mt9m111 *mt9m111 = to_mt9m111(client);
-static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
- a->bounds.left = MT9M111_MIN_DARK_COLS;
- a->bounds.top = MT9M111_MIN_DARK_ROWS;
- a->bounds.width = MT9M111_MAX_WIDTH;
- a->bounds.height = MT9M111_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = MT9M111_MIN_DARK_COLS;
+ sel->r.top = MT9M111_MIN_DARK_ROWS;
+ sel->r.width = MT9M111_MAX_WIDTH;
+ sel->r.height = MT9M111_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = mt9m111->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int mt9m111_get_fmt(struct v4l2_subdev *sd,
@@ -867,14 +871,13 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
}
static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
- .s_crop = mt9m111_s_crop,
- .g_crop = mt9m111_g_crop,
- .cropcap = mt9m111_cropcap,
.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_selection = mt9m111_get_selection,
+ .set_selection = mt9m111_set_selection,
.get_fmt = mt9m111_get_fmt,
.set_fmt = mt9m111_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index 5c8e3ffe3b27..3aa5569065ad 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/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
- * .set_fmt(FORMAT_TRY), soc_camera_s_crop() and soc_camera_cropcap()
+ * .set_fmt(FORMAT_TRY), soc_camera_s_selection() and soc_camera_cropcap()
*/
if (ret >= 0)
ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
@@ -294,11 +294,17 @@ static int mt9t031_set_params(struct i2c_client *client,
return ret < 0 ? ret : 0;
}
-static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int mt9t031_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- struct v4l2_rect rect = a->c;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ struct v4l2_rect rect = sel->r;
+
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
rect.width = ALIGN(rect.width, 2);
rect.height = ALIGN(rect.height, 2);
@@ -312,29 +318,30 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
}
-static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9t031_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
- a->c = mt9t031->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9T031_COLUMN_SKIP;
- a->bounds.top = MT9T031_ROW_SKIP;
- a->bounds.width = MT9T031_MAX_WIDTH;
- a->bounds.height = MT9T031_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = MT9T031_COLUMN_SKIP;
+ sel->r.top = MT9T031_ROW_SKIP;
+ sel->r.width = MT9T031_MAX_WIDTH;
+ sel->r.height = MT9T031_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = mt9t031->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int mt9t031_get_fmt(struct v4l2_subdev *sd,
@@ -721,9 +728,6 @@ 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_crop = mt9t031_s_crop,
- .g_crop = mt9t031_g_crop,
- .cropcap = mt9t031_cropcap,
.g_mbus_config = mt9t031_g_mbus_config,
.s_mbus_config = mt9t031_s_mbus_config,
};
@@ -734,6 +738,8 @@ static const struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = {
.enum_mbus_code = mt9t031_enum_mbus_code,
+ .get_selection = mt9t031_get_selection,
+ .set_selection = mt9t031_set_selection,
.get_fmt = mt9t031_get_fmt,
.set_fmt = mt9t031_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index 6a1b2a9f9a09..2ef22241ec14 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -867,39 +867,48 @@ static int mt9t112_set_params(struct mt9t112_priv *priv,
return 0;
}
-static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = MAX_WIDTH;
- a->bounds.height = MAX_HEIGHT;
- a->defrect.left = 0;
- a->defrect.top = 0;
- a->defrect.width = VGA_WIDTH;
- a->defrect.height = VGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9t112_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
- a->c = priv->frame;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = MAX_WIDTH;
+ sel->r.height = MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = VGA_WIDTH;
+ sel->r.height = VGA_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = priv->frame;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
-static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int mt9t112_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
- const struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &sel->r;
+
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
return mt9t112_set_params(priv, rect, priv->format->code);
}
@@ -1024,15 +1033,14 @@ 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,
- .cropcap = mt9t112_cropcap,
- .g_crop = mt9t112_g_crop,
- .s_crop = mt9t112_s_crop,
.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_selection = mt9t112_get_selection,
+ .set_selection = mt9t112_set_selection,
.get_fmt = mt9t112_get_fmt,
.set_fmt = mt9t112_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 2721e583bfa0..6a14ab5e4f2d 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -276,14 +276,20 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int mt9v022_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct v4l2_rect rect = a->c;
+ struct v4l2_rect rect = sel->r;
int min_row, min_blank;
int ret;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
+
/* Bayer format - even size lengths */
if (mt9v022->fmts == mt9v022_colour_fmts) {
rect.width = ALIGN(rect.width, 2);
@@ -350,29 +356,30 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return 0;
}
-static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9v022_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
- a->c = mt9v022->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = MT9V022_COLUMN_SKIP;
- a->bounds.top = MT9V022_ROW_SKIP;
- a->bounds.width = MT9V022_MAX_WIDTH;
- a->bounds.height = MT9V022_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = MT9V022_COLUMN_SKIP;
+ sel->r.top = MT9V022_ROW_SKIP;
+ sel->r.width = MT9V022_MAX_WIDTH;
+ sel->r.height = MT9V022_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = mt9v022->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int mt9v022_get_fmt(struct v4l2_subdev *sd,
@@ -400,13 +407,13 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
- struct v4l2_crop a = {
- .c = {
- .left = mt9v022->rect.left,
- .top = mt9v022->rect.top,
- .width = mf->width,
- .height = mf->height,
- },
+ struct v4l2_subdev_selection sel = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .target = V4L2_SEL_TGT_CROP,
+ .r.left = mt9v022->rect.left,
+ .r.top = mt9v022->rect.top,
+ .r.width = mf->width,
+ .r.height = mf->height,
};
int ret;
@@ -430,7 +437,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
}
/* No support for scaling on this camera, just crop. */
- ret = mt9v022_s_crop(sd, &a);
+ ret = mt9v022_set_selection(sd, NULL, &sel);
if (!ret) {
mf->width = mt9v022->rect.width;
mf->height = mt9v022->rect.height;
@@ -853,9 +860,6 @@ 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_crop = mt9v022_s_crop,
- .g_crop = mt9v022_g_crop,
- .cropcap = mt9v022_cropcap,
.g_mbus_config = mt9v022_g_mbus_config,
.s_mbus_config = mt9v022_s_mbus_config,
};
@@ -866,6 +870,8 @@ static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
.enum_mbus_code = mt9v022_enum_mbus_code,
+ .get_selection = mt9v022_get_selection,
+ .set_selection = mt9v022_set_selection,
.get_fmt = mt9v022_get_fmt,
.set_fmt = mt9v022_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index 9b4f5deec748..56de18263359 100644
--- a/drivers/media/i2c/soc_camera/ov2640.c
+++ b/drivers/media/i2c/soc_camera/ov2640.c
@@ -928,29 +928,25 @@ static int ov2640_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
-static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = UXGA_WIDTH;
- a->c.height = UXGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+static int ov2640_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = UXGA_WIDTH;
- a->bounds.height = UXGA_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = UXGA_WIDTH;
+ sel->r.height = UXGA_HEIGHT;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int ov2640_video_probe(struct i2c_client *client)
@@ -1024,13 +1020,12 @@ 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,
- .cropcap = ov2640_cropcap,
- .g_crop = ov2640_g_crop,
.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_selection = ov2640_get_selection,
.get_fmt = ov2640_get_fmt,
.set_fmt = ov2640_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index bab9ac0c1764..3d185bd622a3 100644
--- a/drivers/media/i2c/soc_camera/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -850,13 +850,19 @@ static int ov5642_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
-static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int ov5642_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5642 *priv = to_ov5642(client);
- struct v4l2_rect rect = a->c;
+ struct v4l2_rect rect = sel->r;
int ret;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
+
v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1,
&rect.height, 32, OV5642_MAX_HEIGHT, 1, 0);
@@ -878,32 +884,30 @@ static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return ret;
}
-static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int ov5642_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5642 *priv = to_ov5642(client);
- struct v4l2_rect *rect = &a->c;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
- *rect = priv->crop_rect;
-
- return 0;
-}
-
-static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = OV5642_MAX_WIDTH;
- a->bounds.height = OV5642_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = OV5642_MAX_WIDTH;
+ sel->r.height = OV5642_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = priv->crop_rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
@@ -940,14 +944,13 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
}
static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
- .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_selection = ov5642_get_selection,
+ .set_selection = ov5642_set_selection,
.get_fmt = ov5642_get_fmt,
.set_fmt = ov5642_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 1f8af1ee8352..4bf2995e1cb8 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -432,25 +432,43 @@ static int ov6650_s_power(struct v4l2_subdev *sd, int on)
return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
-static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int ov6650_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->c = priv->rect;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = DEF_HSTRT << 1;
+ sel->r.top = DEF_VSTRT << 1;
+ sel->r.width = W_CIF;
+ sel->r.height = H_CIF;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = priv->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
-static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int ov6650_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
- struct v4l2_rect rect = a->c;
+ struct v4l2_rect rect = sel->r;
int ret;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
rect.left = ALIGN(rect.left, 2);
@@ -483,22 +501,6 @@ static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return ret;
}
-static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- a->bounds.left = DEF_HSTRT << 1;
- a->bounds.top = DEF_VSTRT << 1;
- a->bounds.width = W_CIF;
- a->bounds.height = H_CIF;
- a->defrect = a->bounds;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
static int ov6650_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *format)
@@ -549,16 +551,15 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
struct soc_camera_sense *sense = icd->sense;
struct ov6650 *priv = to_ov6650(client);
bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
- struct v4l2_crop a = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .c = {
- .left = priv->rect.left + (priv->rect.width >> 1) -
- (mf->width >> (1 - half_scale)),
- .top = priv->rect.top + (priv->rect.height >> 1) -
- (mf->height >> (1 - half_scale)),
- .width = mf->width << half_scale,
- .height = mf->height << half_scale,
- },
+ struct v4l2_subdev_selection sel = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .target = V4L2_SEL_TGT_CROP,
+ .r.left = priv->rect.left + (priv->rect.width >> 1) -
+ (mf->width >> (1 - half_scale)),
+ .r.top = priv->rect.top + (priv->rect.height >> 1) -
+ (mf->height >> (1 - half_scale)),
+ .r.width = mf->width << half_scale,
+ .r.height = mf->height << half_scale,
};
u32 code = mf->code;
unsigned long mclk, pclk;
@@ -672,7 +673,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n",
mclk / pclk, 10 * mclk % pclk / pclk);
- ret = ov6650_s_crop(sd, &a);
+ ret = ov6650_set_selection(sd, NULL, &sel);
if (!ret)
ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask);
if (!ret)
@@ -943,9 +944,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,
- .cropcap = ov6650_cropcap,
- .g_crop = ov6650_g_crop,
- .s_crop = ov6650_s_crop,
.g_parm = ov6650_g_parm,
.s_parm = ov6650_s_parm,
.g_mbus_config = ov6650_g_mbus_config,
@@ -954,6 +952,8 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = {
static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
.enum_mbus_code = ov6650_enum_mbus_code,
+ .get_selection = ov6650_get_selection,
+ .set_selection = ov6650_set_selection,
.get_fmt = ov6650_get_fmt,
.set_fmt = ov6650_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index a43410c1e254..7e68762b3a4b 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -851,29 +851,28 @@ ov772x_set_fmt_error:
return ret;
}
-static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = VGA_WIDTH;
- a->c.height = VGA_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+static int ov772x_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = OV772X_MAX_WIDTH;
- a->bounds.height = OV772X_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ sel->r.left = 0;
+ sel->r.top = 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.width = OV772X_MAX_WIDTH;
+ sel->r.height = OV772X_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r.width = VGA_WIDTH;
+ sel->r.height = VGA_HEIGHT;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int ov772x_get_fmt(struct v4l2_subdev *sd,
@@ -1030,13 +1029,12 @@ 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,
- .cropcap = ov772x_cropcap,
- .g_crop = ov772x_g_crop,
.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_selection = ov772x_get_selection,
.get_fmt = ov772x_get_fmt,
.set_fmt = ov772x_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 8caae1c07541..8c93c57af71c 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -561,29 +561,25 @@ static int ov9640_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
-static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
-{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = W_SXGA;
- a->c.height = H_SXGA;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+static int ov9640_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = W_SXGA;
- a->bounds.height = H_SXGA;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ sel->r.left = 0;
+ sel->r.top = 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ sel->r.width = W_SXGA;
+ sel->r.height = H_SXGA;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int ov9640_video_probe(struct i2c_client *client)
@@ -667,13 +663,12 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops ov9640_video_ops = {
.s_stream = ov9640_s_stream,
- .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,
+ .get_selection = ov9640_get_selection,
.set_fmt = ov9640_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index 03a7fc7316ae..0da632d7d33a 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -737,29 +737,25 @@ static int ov9740_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
-static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = 0;
- a->bounds.top = 0;
- a->bounds.width = OV9740_MAX_WIDTH;
- a->bounds.height = OV9740_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
- return 0;
-}
-
-static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int ov9740_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
- a->c.left = 0;
- a->c.top = 0;
- a->c.width = OV9740_MAX_WIDTH;
- a->c.height = OV9740_MAX_HEIGHT;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = OV9740_MAX_WIDTH;
+ sel->r.height = OV9740_MAX_HEIGHT;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
/* Set status of additional camera capabilities */
@@ -914,8 +910,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,
- .cropcap = ov9740_cropcap,
- .g_crop = ov9740_g_crop,
.g_mbus_config = ov9740_g_mbus_config,
};
@@ -929,6 +923,7 @@ static struct v4l2_subdev_core_ops ov9740_core_ops = {
static const struct v4l2_subdev_pad_ops ov9740_pad_ops = {
.enum_mbus_code = ov9740_enum_mbus_code,
+ .get_selection = ov9740_get_selection,
.set_fmt = ov9740_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index aa7bfbb4ad71..bc8ec59a3fbd 100644
--- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -538,15 +538,21 @@ static int rj54n1_commit(struct i2c_client *client)
static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
s32 *out_w, s32 *out_h);
-static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+static int rj54n1_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
- const struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &sel->r;
int dummy = 0, output_w, output_h,
input_w = rect->width, input_h = rect->height;
int ret;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+ sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
+
/* arbitrary minimum width and height, edges unimportant */
soc_camera_limit_side(&dummy, &input_w,
RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
@@ -573,29 +579,30 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return 0;
}
-static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int rj54n1_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
- a->c = rj54n1->rect;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- a->bounds.left = RJ54N1_COLUMN_SKIP;
- a->bounds.top = RJ54N1_ROW_SKIP;
- a->bounds.width = RJ54N1_MAX_WIDTH;
- a->bounds.height = RJ54N1_MAX_HEIGHT;
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
- return 0;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = RJ54N1_COLUMN_SKIP;
+ sel->r.top = RJ54N1_ROW_SKIP;
+ sel->r.width = RJ54N1_MAX_WIDTH;
+ sel->r.height = RJ54N1_MAX_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = rj54n1->rect;
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static int rj54n1_get_fmt(struct v4l2_subdev *sd,
@@ -1246,15 +1253,14 @@ 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,
- .g_crop = rj54n1_g_crop,
- .s_crop = rj54n1_s_crop,
- .cropcap = rj54n1_cropcap,
.g_mbus_config = rj54n1_g_mbus_config,
.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_selection = rj54n1_get_selection,
+ .set_selection = rj54n1_set_selection,
.get_fmt = rj54n1_get_fmt,
.set_fmt = rj54n1_set_fmt,
};
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index 06aff81787a7..4002c07f3857 100644
--- a/drivers/media/i2c/soc_camera/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -676,44 +676,28 @@ tw9910_set_fmt_error:
return ret;
}
-static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int tw9910_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
- a->c.left = 0;
- a->c.top = 0;
- if (priv->norm & V4L2_STD_NTSC) {
- a->c.width = 640;
- a->c.height = 480;
- } else {
- a->c.width = 768;
- a->c.height = 576;
- }
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- return 0;
-}
-
-static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+ /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */
+ if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
+ return -EINVAL;
- a->bounds.left = 0;
- a->bounds.top = 0;
+ sel->r.left = 0;
+ sel->r.top = 0;
if (priv->norm & V4L2_STD_NTSC) {
- a->bounds.width = 640;
- a->bounds.height = 480;
+ sel->r.width = 640;
+ sel->r.height = 480;
} else {
- a->bounds.width = 768;
- a->bounds.height = 576;
+ sel->r.width = 768;
+ sel->r.height = 576;
}
- a->defrect = a->bounds;
- a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- a->pixelaspect.numerator = 1;
- a->pixelaspect.denominator = 1;
-
return 0;
}
@@ -921,8 +905,6 @@ 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,
- .cropcap = tw9910_cropcap,
- .g_crop = tw9910_g_crop,
.g_mbus_config = tw9910_g_mbus_config,
.s_mbus_config = tw9910_s_mbus_config,
.g_tvnorms = tw9910_g_tvnorms,
@@ -930,6 +912,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
.enum_mbus_code = tw9910_enum_mbus_code,
+ .get_selection = tw9910_get_selection,
.get_fmt = tw9910_get_fmt,
.set_fmt = tw9910_set_fmt,
};