[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>
This commit is contained in:
Hans Verkuil authored and Mauro Carvalho Chehab committed 2016-08-24 09:46:09 -03:00
1 parent 65d9e14a65
commit 10d5509c8d
28 files changed
+751 -680

No files matched your search

+17 -11
View File
@@ -124,21 +124,27 @@ static int ak881x_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int ak881x_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 ak881x *ak881x = to_ak881x(client);
a->bounds.left = 0;
a->bounds.top = 0;
a->bounds.width = 720;
a->bounds.height = ak881x->lines;
a->defrect = a->bounds;
a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
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 = 0;
sel->r.top = 0;
sel->r.width = 720;
sel->r.height = ak881x->lines;
return 0;
default:
return -EINVAL;
}
}
static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
@@ -207,13 +213,13 @@ static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
};
static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
.cropcap = ak881x_cropcap,
.s_std_output = ak881x_s_std_output,
.s_stream = ak881x_s_stream,
};
static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = {
.enum_mbus_code = ak881x_enum_mbus_code,
.get_selection = ak881x_get_selection,
.set_fmt = ak881x_fill_fmt,
.get_fmt = ak881x_fill_fmt,
};
+18 -24
View File
@@ -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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
rect->top = 0;
rect->left = 0;
rect->width = IMX074_WIDTH;
rect->height = IMX074_HEIGHT;
sel->r.left = 0;
sel->r.top = 0;
sel->r.width = IMX074_WIDTH;
sel->r.height = IMX074_HEIGHT;
return 0;
}
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;
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,
};
+38 -32
View File
@@ -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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
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;
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,
};
+30 -27
View File
@@ -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);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
a->c = mt9m111->rect;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
return 0;
}
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,
};
+30 -24
View File
@@ -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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
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;
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,
};
+34 -26
View File
@@ -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,
};
+37 -31
View File
@@ -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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
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;
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,
};
+18 -23
View File
@@ -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)
static int ov2640_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 = UXGA_WIDTH;
a->c.height = UXGA_HEIGHT;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return 0;
}
static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
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;
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,
};
+28 -25
View File
@@ -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,
};
+37 -37
View File
@@ -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,
};
+21 -23
View File
@@ -851,29 +851,28 @@ ov772x_set_fmt_error:
return ret;
}
static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int ov772x_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 = VGA_WIDTH;
a->c.height = VGA_HEIGHT;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return 0;
}
static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
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;
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,
};
+18 -23
View File
@@ -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)
static int ov9640_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 = W_SXGA;
a->c.height = H_SXGA;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return 0;
}
static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
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;
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,
};
+18 -23
View File
@@ -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)
static int ov9740_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 = 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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return 0;
}
static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
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;
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,
};
+29 -23
View File
@@ -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;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
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;
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,
};
+16 -33
View File
@@ -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 (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;
sel->r.left = 0;
sel->r.top = 0;
if (priv->norm & V4L2_STD_NTSC) {
a->c.width = 640;
a->c.height = 480;
sel->r.width = 640;
sel->r.height = 480;
} else {
a->c.width = 768;
a->c.height = 576;
sel->r.width = 768;
sel->r.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);
a->bounds.left = 0;
a->bounds.top = 0;
if (priv->norm & V4L2_STD_NTSC) {
a->bounds.width = 640;
a->bounds.height = 480;
} else {
a->bounds.width = 768;
a->bounds.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,
};
+38 -41
View File
@@ -871,19 +871,22 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
return 0;
}
static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
static int tvp5150_set_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel)
{
struct v4l2_rect rect = a->c;
struct tvp5150 *decoder = to_tvp5150(sd);
struct v4l2_rect rect = sel->r;
v4l2_std_id std;
unsigned int hmax;
int hmax;
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n",
__func__, rect.left, rect.top, rect.width, rect.height);
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
/* tvp5150 has some special limits */
rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
rect.width = clamp_t(unsigned int, rect.width,
@@ -924,44 +927,39 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
return 0;
}
static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int tvp5150_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel)
{
struct tvp5150 *decoder = to_tvp5150(sd);
a->c = decoder->rect;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
return 0;
}
static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
struct tvp5150 *decoder = to_tvp5150(sd);
struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
v4l2_std_id std;
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
a->bounds.left = 0;
a->bounds.top = 0;
a->bounds.width = TVP5150_H_MAX;
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 = TVP5150_H_MAX;
/* Calculate height based on current standard */
if (decoder->norm == V4L2_STD_ALL)
std = tvp5150_read_std(sd);
else
std = decoder->norm;
if (std & V4L2_STD_525_60)
a->bounds.height = TVP5150_V_MAX_525_60;
else
a->bounds.height = TVP5150_V_MAX_OTHERS;
a->defrect = a->bounds;
a->pixelaspect.numerator = 1;
a->pixelaspect.denominator = 1;
return 0;
/* Calculate height based on current standard */
if (decoder->norm == V4L2_STD_ALL)
std = tvp5150_read_std(sd);
else
std = decoder->norm;
if (std & V4L2_STD_525_60)
sel->r.height = TVP5150_V_MAX_525_60;
else
sel->r.height = TVP5150_V_MAX_OTHERS;
return 0;
case V4L2_SEL_TGT_CROP:
sel->r = decoder->rect;
return 0;
default:
return -EINVAL;
}
}
static int tvp5150_g_mbus_config(struct v4l2_subdev *sd,
@@ -1233,9 +1231,6 @@ static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
.s_std = tvp5150_s_std,
.s_stream = tvp5150_s_stream,
.s_routing = tvp5150_s_routing,
.s_crop = tvp5150_s_crop,
.g_crop = tvp5150_g_crop,
.cropcap = tvp5150_cropcap,
.g_mbus_config = tvp5150_g_mbus_config,
};
@@ -1251,6 +1246,8 @@ static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
.enum_frame_size = tvp5150_enum_frame_size,
.set_fmt = tvp5150_fill_fmt,
.get_fmt = tvp5150_fill_fmt,
.get_selection = tvp5150_get_selection,
.set_selection = tvp5150_set_selection,
};
static const struct v4l2_subdev_ops tvp5150_ops = {
+57 -31
View File
@@ -772,40 +772,45 @@ isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
}
static int
isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
{
struct isp_video *video = video_drvdata(file);
struct v4l2_subdev *subdev;
int ret;
subdev = isp_video_remote_subdev(video, NULL);
if (subdev == NULL)
return -EINVAL;
mutex_lock(&video->mutex);
ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
mutex_unlock(&video->mutex);
return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
}
static int
isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
isp_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel)
{
struct isp_video *video = video_drvdata(file);
struct v4l2_subdev_format format;
struct v4l2_subdev *subdev;
struct v4l2_subdev_selection sdsel = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.target = sel->target,
};
u32 pad;
int ret;
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_CROP_DEFAULT:
if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
break;
case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
break;
default:
return -EINVAL;
}
subdev = isp_video_remote_subdev(video, &pad);
if (subdev == NULL)
return -EINVAL;
/* Try the get crop operation first and fallback to get format if not
/* Try the get selection operation first and fallback to get format if not
* implemented.
*/
ret = v4l2_subdev_call(subdev, video, g_crop, crop);
sdsel.pad = pad;
ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel);
if (!ret)
sel->r = sdsel.r;
if (ret != -ENOIOCTLCMD)
return ret;
@@ -815,28 +820,50 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
if (ret < 0)
return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
crop->c.left = 0;
crop->c.top = 0;
crop->c.width = format.format.width;
crop->c.height = format.format.height;
sel->r.left = 0;
sel->r.top = 0;
sel->r.width = format.format.width;
sel->r.height = format.format.height;
return 0;
}
static int
isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
isp_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel)
{
struct isp_video *video = video_drvdata(file);
struct v4l2_subdev *subdev;
struct v4l2_subdev_selection sdsel = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.target = sel->target,
.flags = sel->flags,
.r = sel->r,
};
u32 pad;
int ret;
subdev = isp_video_remote_subdev(video, NULL);
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
break;
case V4L2_SEL_TGT_COMPOSE:
if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
break;
default:
return -EINVAL;
}
subdev = isp_video_remote_subdev(video, &pad);
if (subdev == NULL)
return -EINVAL;
sdsel.pad = pad;
mutex_lock(&video->mutex);
ret = v4l2_subdev_call(subdev, video, s_crop, crop);
ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel);
mutex_unlock(&video->mutex);
if (!ret)
sel->r = sdsel.r;
return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
}
@@ -1252,9 +1279,8 @@ static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
.vidioc_g_fmt_vid_out = isp_video_get_format,
.vidioc_s_fmt_vid_out = isp_video_set_format,
.vidioc_try_fmt_vid_out = isp_video_try_format,
.vidioc_cropcap = isp_video_cropcap,
.vidioc_g_crop = isp_video_get_crop,
.vidioc_s_crop = isp_video_set_crop,
.vidioc_g_selection = isp_video_get_selection,
.vidioc_s_selection = isp_video_set_selection,
.vidioc_g_parm = isp_video_get_param,
.vidioc_s_parm = isp_video_set_param,
.vidioc_reqbufs = isp_video_reqbufs,
+9 -6
View File
@@ -937,7 +937,10 @@ static int sh_vou_s_selection(struct file *file, void *fh,
{
struct v4l2_rect *rect = &sel->r;
struct sh_vou_device *vou_dev = video_drvdata(file);
struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
struct v4l2_subdev_selection sd_sel = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.target = V4L2_SEL_TGT_COMPOSE,
};
struct v4l2_pix_format *pix = &vou_dev->pix;
struct sh_vou_geometry geo;
struct v4l2_subdev_format format = {
@@ -978,14 +981,14 @@ static int sh_vou_s_selection(struct file *file, void *fh,
geo.in_height = pix->height;
/* Configure the encoder one-to-one, position at 0, ignore errors */
sd_crop.c.width = geo.output.width;
sd_crop.c.height = geo.output.height;
sd_sel.r.width = geo.output.width;
sd_sel.r.height = geo.output.height;
/*
* We first issue a S_CROP, so that the subsequent S_FMT delivers the
* We first issue a S_SELECTION, so that the subsequent S_FMT delivers the
* final encoder configuration.
*/
v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
s_crop, &sd_crop);
v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad,
set_selection, NULL, &sd_sel);
format.format.width = geo.output.width;
format.format.height = geo.output.height;
ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad,
+12 -5
View File
@@ -1280,10 +1280,10 @@ static int pxa_camera_check_frame(u32 width, u32 height)
(width & 0x01);
}
static int pxa_camera_set_crop(struct soc_camera_device *icd,
const struct v4l2_crop *a)
static int pxa_camera_set_selection(struct soc_camera_device *icd,
struct v4l2_selection *sel)
{
const struct v4l2_rect *rect = &a->c;
const struct v4l2_rect *rect = &sel->r;
struct device *dev = icd->parent;
struct soc_camera_host *ici = to_soc_camera_host(dev);
struct pxa_camera_dev *pcdev = ici->priv;
@@ -1298,13 +1298,19 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
struct v4l2_mbus_framefmt *mf = &fmt.format;
struct pxa_cam *cam = icd->host_priv;
u32 fourcc = icd->current_fmt->host_fmt->fourcc;
struct v4l2_subdev_selection sdsel = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.target = sel->target,
.flags = sel->flags,
.r = sel->r,
};
int ret;
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
icd->sense = &sense;
ret = v4l2_subdev_call(sd, video, s_crop, a);
ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel);
icd->sense = NULL;
@@ -1313,6 +1319,7 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
rect->width, rect->height, rect->left, rect->top);
return ret;
}
sel->r = sdsel.r;
ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
if (ret < 0)
@@ -1592,7 +1599,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.remove = pxa_camera_remove_device,
.clock_start = pxa_camera_clock_start,
.clock_stop = pxa_camera_clock_stop,
.set_crop = pxa_camera_set_crop,
.set_selection = pxa_camera_set_selection,
.get_formats = pxa_camera_get_formats,
.put_formats = pxa_camera_put_formats,
.set_fmt = pxa_camera_set_fmt,
+14 -16
View File
@@ -515,7 +515,7 @@ struct rcar_vin_cam {
unsigned int out_width;
unsigned int out_height;
/*
* User window from S_CROP / G_CROP, produced by client cropping and
* User window from S_SELECTION / G_SELECTION, produced by client cropping and
* scaling, VIN scaling and VIN cropping, mapped back onto the client
* input window
*/
@@ -1471,16 +1471,15 @@ static void rcar_vin_put_formats(struct soc_camera_device *icd)
icd->host_priv = NULL;
}
static int rcar_vin_set_crop(struct soc_camera_device *icd,
const struct v4l2_crop *a)
static int rcar_vin_set_selection(struct soc_camera_device *icd,
struct v4l2_selection *sel)
{
struct v4l2_crop a_writable = *a;
const struct v4l2_rect *rect = &a_writable.c;
const struct v4l2_rect *rect = &sel->r;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct rcar_vin_priv *priv = ici->priv;
struct v4l2_crop cam_crop;
struct v4l2_selection cam_sel;
struct rcar_vin_cam *cam = icd->host_priv;
struct v4l2_rect *cam_rect = &cam_crop.c;
struct v4l2_rect *cam_rect = &cam_sel.r;
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->parent;
struct v4l2_subdev_format fmt = {
@@ -1490,15 +1489,15 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd,
u32 vnmc;
int ret, i;
dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height,
rect->left, rect->top);
/* During camera cropping its output window can change too, stop VIN */
capture_stop_preserve(priv, &vnmc);
dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
/* Apply iterative camera S_CROP for new input window. */
ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
/* Apply iterative camera S_SELECTION for new input window. */
ret = soc_camera_client_s_selection(sd, sel, &cam_sel,
&cam->rect, &cam->subrect);
if (ret < 0)
return ret;
@@ -1551,13 +1550,12 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd,
return ret;
}
static int rcar_vin_get_crop(struct soc_camera_device *icd,
struct v4l2_crop *a)
static int rcar_vin_get_selection(struct soc_camera_device *icd,
struct v4l2_selection *sel)
{
struct rcar_vin_cam *cam = icd->host_priv;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a->c = cam->subrect;
sel->r = cam->subrect;
return 0;
}
@@ -1824,8 +1822,8 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
.remove = rcar_vin_remove_device,
.get_formats = rcar_vin_get_formats,
.put_formats = rcar_vin_put_formats,
.get_crop = rcar_vin_get_crop,
.set_crop = rcar_vin_set_crop,
.get_selection = rcar_vin_get_selection,
.set_selection = rcar_vin_set_selection,
.try_fmt = rcar_vin_try_fmt,
.set_fmt = rcar_vin_set_fmt,
.poll = rcar_vin_poll,
Loaded 20 of 28 files, more files were not shown because too many files have changed in this diff. Show more