1 From 7c876909bc0a6d23124689d5fca89657a4fcb5a5 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 5 Mar 2019 15:43:27 +0000
4 Subject: [PATCH] media: bcm2835-unicam: Add support for enum
5 framesizes and frameintervals
7 vidioc_enum_framesizes and vidioc_enum_frameintervals weren't implemented,
8 therefore clients couldn't enumerate the supported resolutions.
10 Implement them by forwarding on to the sensor driver.
12 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
14 .../media/platform/bcm2835/bcm2835-unicam.c | 94 +++++++++++++++++++
15 1 file changed, 94 insertions(+)
17 --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
18 +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
19 @@ -1406,6 +1406,84 @@ static int unicam_g_edid(struct file *fi
20 return v4l2_subdev_call(dev->sensor, pad, get_edid, edid);
23 +static int unicam_enum_framesizes(struct file *file, void *priv,
24 + struct v4l2_frmsizeenum *fsize)
26 + struct unicam_device *dev = video_drvdata(file);
27 + const struct unicam_fmt *fmt;
28 + struct v4l2_subdev_frame_size_enum fse;
31 + /* check for valid format */
32 + fmt = find_format_by_pix(dev, fsize->pixel_format);
34 + unicam_dbg(3, dev, "Invalid pixel code: %x\n",
35 + fsize->pixel_format);
39 + fse.index = fsize->index;
41 + fse.code = fmt->code;
43 + ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse);
47 + unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
48 + __func__, fse.index, fse.code, fse.min_width, fse.max_width,
49 + fse.min_height, fse.max_height);
51 + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
52 + fsize->discrete.width = fse.max_width;
53 + fsize->discrete.height = fse.max_height;
58 +static int unicam_enum_frameintervals(struct file *file, void *priv,
59 + struct v4l2_frmivalenum *fival)
61 + struct unicam_device *dev = video_drvdata(file);
62 + const struct unicam_fmt *fmt;
63 + struct v4l2_subdev_frame_interval_enum fie = {
64 + .index = fival->index,
65 + .width = fival->width,
66 + .height = fival->height,
67 + .which = V4L2_SUBDEV_FORMAT_ACTIVE,
71 + fmt = find_format_by_pix(dev, fival->pixel_format);
75 + fie.code = fmt->code;
76 + ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval,
81 + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
82 + fival->discrete = fie.interval;
87 +static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
89 + struct unicam_device *dev = video_drvdata(file);
91 + return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a);
94 +static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
96 + struct unicam_device *dev = video_drvdata(file);
98 + return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a);
101 static int unicam_g_dv_timings(struct file *file, void *priv,
102 struct v4l2_dv_timings *timings)
104 @@ -1613,6 +1691,12 @@ static const struct v4l2_ioctl_ops unica
105 .vidioc_g_edid = unicam_g_edid,
106 .vidioc_s_edid = unicam_s_edid,
108 + .vidioc_enum_framesizes = unicam_enum_framesizes,
109 + .vidioc_enum_frameintervals = unicam_enum_frameintervals,
111 + .vidioc_g_parm = unicam_g_parm,
112 + .vidioc_s_parm = unicam_s_parm,
114 .vidioc_s_dv_timings = unicam_s_dv_timings,
115 .vidioc_g_dv_timings = unicam_g_dv_timings,
116 .vidioc_query_dv_timings = unicam_query_dv_timings,
117 @@ -1850,6 +1934,16 @@ static int unicam_probe_complete(struct
118 v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_DV_TIMINGS);
119 v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERY_DV_TIMINGS);
121 + if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval))
122 + v4l2_disable_ioctl(&unicam->video_dev,
123 + VIDIOC_ENUM_FRAMEINTERVALS);
124 + if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval))
125 + v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_PARM);
126 + if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval))
127 + v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_PARM);
129 + if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size))
130 + v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_FRAMESIZES);
132 ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev);