media: s5p-g2d: convert g/s_crop to g/s_selection

Replace g/s_crop by g/s_selection and set the V4L2_FL_QUIRK_INVERTED_CROP
flag since this is one of the old drivers that predates the selection
API. Those old drivers allowed g_crop when it really shouldn't have since
g_crop returns a compose rectangle instead of a crop rectangle for the
CAPTURE stream, and vice versa for the OUTPUT stream.

Also drop the now unused vidioc_cropcap.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Hans Verkuil 2018-10-04 16:12:06 -04:00 committed by Mauro Carvalho Chehab
parent 158efdeebc
commit f72b9d8cfc
1 changed files with 64 additions and 38 deletions

View File

@ -89,7 +89,7 @@ static struct g2d_fmt *find_fmt(struct v4l2_format *f)
static struct g2d_frame *get_frame(struct g2d_ctx *ctx,
enum v4l2_buf_type type)
enum v4l2_buf_type type)
{
switch (type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@ -408,51 +408,76 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
static int vidioc_cropcap(struct file *file, void *priv,
struct v4l2_cropcap *cr)
{
struct g2d_ctx *ctx = priv;
struct g2d_frame *f;
f = get_frame(ctx, cr->type);
if (IS_ERR(f))
return PTR_ERR(f);
cr->bounds.left = 0;
cr->bounds.top = 0;
cr->bounds.width = f->width;
cr->bounds.height = f->height;
cr->defrect = cr->bounds;
return 0;
}
static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
static int vidioc_g_selection(struct file *file, void *prv,
struct v4l2_selection *s)
{
struct g2d_ctx *ctx = prv;
struct g2d_frame *f;
f = get_frame(ctx, cr->type);
f = get_frame(ctx, s->type);
if (IS_ERR(f))
return PTR_ERR(f);
cr->c.left = f->o_height;
cr->c.top = f->o_width;
cr->c.width = f->c_width;
cr->c.height = f->c_height;
switch (s->target) {
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
break;
case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
break;
default:
return -EINVAL;
}
switch (s->target) {
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_COMPOSE:
s->r.left = f->o_height;
s->r.top = f->o_width;
s->r.width = f->c_width;
s->r.height = f->c_height;
break;
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
s->r.left = 0;
s->r.top = 0;
s->r.width = f->width;
s->r.height = f->height;
break;
default:
return -EINVAL;
}
return 0;
}
static int vidioc_try_crop(struct file *file, void *prv, const struct v4l2_crop *cr)
static int vidioc_try_selection(struct file *file, void *prv,
const struct v4l2_selection *s)
{
struct g2d_ctx *ctx = prv;
struct g2d_dev *dev = ctx->dev;
struct g2d_frame *f;
f = get_frame(ctx, cr->type);
f = get_frame(ctx, s->type);
if (IS_ERR(f))
return PTR_ERR(f);
if (cr->c.top < 0 || cr->c.left < 0) {
if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (s->target != V4L2_SEL_TGT_COMPOSE)
return -EINVAL;
} else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
if (s->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
}
if (s->r.top < 0 || s->r.left < 0) {
v4l2_err(&dev->v4l2_dev,
"doesn't support negative values for top & left\n");
return -EINVAL;
@ -461,23 +486,24 @@ static int vidioc_try_crop(struct file *file, void *prv, const struct v4l2_crop
return 0;
}
static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *cr)
static int vidioc_s_selection(struct file *file, void *prv,
struct v4l2_selection *s)
{
struct g2d_ctx *ctx = prv;
struct g2d_frame *f;
int ret;
ret = vidioc_try_crop(file, prv, cr);
ret = vidioc_try_selection(file, prv, s);
if (ret)
return ret;
f = get_frame(ctx, cr->type);
f = get_frame(ctx, s->type);
if (IS_ERR(f))
return PTR_ERR(f);
f->c_width = cr->c.width;
f->c_height = cr->c.height;
f->o_width = cr->c.left;
f->o_height = cr->c.top;
f->c_width = s->r.width;
f->c_height = s->r.height;
f->o_width = s->r.left;
f->o_height = s->r.top;
f->bottom = f->o_height + f->c_height;
f->right = f->o_width + f->c_width;
return 0;
@ -585,9 +611,8 @@ static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
.vidioc_streamon = v4l2_m2m_ioctl_streamon,
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
.vidioc_g_crop = vidioc_g_crop,
.vidioc_s_crop = vidioc_s_crop,
.vidioc_cropcap = vidioc_cropcap,
.vidioc_g_selection = vidioc_g_selection,
.vidioc_s_selection = vidioc_s_selection,
};
static const struct video_device g2d_videodev = {
@ -680,6 +705,7 @@ static int g2d_probe(struct platform_device *pdev)
goto unreg_v4l2_dev;
}
*vfd = g2d_videodev;
set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
vfd->lock = &dev->mutex;
vfd->v4l2_dev = &dev->v4l2_dev;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);