media: vim2m: add support for VIDIOC_ENUM_FRAMESIZES

As we do alignments for width, expose it via V4L2 API.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Mauro Carvalho Chehab 2019-02-26 16:03:45 -05:00
parent 77e05ef7d4
commit 9c9c396ce6
1 changed files with 29 additions and 9 deletions

View File

@ -50,7 +50,7 @@ MODULE_PARM_DESC(default_transtime, "default transaction time in ms");
#define MIN_H 32
#define MAX_W 640
#define MAX_H 480
#define DIM_ALIGN_MASK 1 /* 2-byte alignment */
#define WIDTH_ALIGN 2 /* 2-byte alignment */
/* Flags that indicate a format can be used for capture/output */
#define MEM2MEM_CAPTURE (1 << 0)
@ -145,14 +145,14 @@ enum {
#define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000)
#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001)
static struct vim2m_fmt *find_format(struct v4l2_format *f)
static struct vim2m_fmt *find_format(u32 fourcc)
{
struct vim2m_fmt *fmt;
unsigned int k;
for (k = 0; k < NUM_FORMATS; k++) {
fmt = &formats[k];
if (fmt->fourcc == f->fmt.pix.pixelformat)
if (fmt->fourcc == fourcc)
break;
}
@ -677,6 +677,25 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
return enum_fmt(f, MEM2MEM_OUTPUT);
}
static int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
if (fsize->index != 0)
return -EINVAL;
if (!find_format(fsize->pixel_format))
return -EINVAL;
fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
fsize->stepwise.min_width = MIN_W;
fsize->stepwise.min_height = MIN_H;
fsize->stepwise.max_width = MAX_W;
fsize->stepwise.max_height = MAX_H;
fsize->stepwise.step_width = WIDTH_ALIGN;
fsize->stepwise.step_height = 1;
return 0;
}
static int vidioc_g_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
{
struct vb2_queue *vq;
@ -728,7 +747,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
else if (f->fmt.pix.width > MAX_W)
f->fmt.pix.width = MAX_W;
f->fmt.pix.width &= ~DIM_ALIGN_MASK;
f->fmt.pix.width &= ~(WIDTH_ALIGN - 1);
f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.field = V4L2_FIELD_NONE;
@ -742,10 +761,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct vim2m_fmt *fmt;
struct vim2m_ctx *ctx = file2ctx(file);
fmt = find_format(f);
fmt = find_format(f->fmt.pix.pixelformat);
if (!fmt) {
f->fmt.pix.pixelformat = formats[0].fourcc;
fmt = find_format(f);
fmt = find_format(f->fmt.pix.pixelformat);
}
if (!(fmt->types & MEM2MEM_CAPTURE)) {
v4l2_err(&ctx->dev->v4l2_dev,
@ -767,10 +786,10 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
struct vim2m_fmt *fmt;
struct vim2m_ctx *ctx = file2ctx(file);
fmt = find_format(f);
fmt = find_format(f->fmt.pix.pixelformat);
if (!fmt) {
f->fmt.pix.pixelformat = formats[0].fourcc;
fmt = find_format(f);
fmt = find_format(f->fmt.pix.pixelformat);
}
if (!(fmt->types & MEM2MEM_OUTPUT)) {
v4l2_err(&ctx->dev->v4l2_dev,
@ -802,7 +821,7 @@ static int vidioc_s_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
return -EBUSY;
}
q_data->fmt = find_format(f);
q_data->fmt = find_format(f->fmt.pix.pixelformat);
q_data->width = f->fmt.pix.width;
q_data->height = f->fmt.pix.height;
q_data->sizeimage = q_data->width * q_data->height
@ -899,6 +918,7 @@ static const struct v4l2_ioctl_ops vim2m_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,