diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2015-03-04 04:48:00 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-03-23 15:01:15 -0400 |
commit | 17bef885249db5db921ac8cf6e23938a91a6cd7b (patch) | |
tree | 23f58ecb46904cc3fbe4f5f4fbbe53a6dc4c9735 | |
parent | d3e4bd8e10cd70d35a59854dcdcd7280c5ed240c (diff) |
[media] v4l2-subdev: add support for the new enum_frame_interval 'which' field
Support the new 'which' field in the enum_frame_interval ops. Most drivers do not
need to be changed since they always returns the same enumeration regardless
of the 'which' field.
Tested for ov7670 and marvell-ccic on a OLPC XO-1 laptop.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Jonathan Corbet <corbet@lwn.net>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r-- | drivers/media/i2c/ov7670.c | 37 | ||||
-rw-r--r-- | drivers/media/platform/marvell-ccic/mcam-core.c | 48 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/soc_camera.c | 30 | ||||
-rw-r--r-- | drivers/media/platform/via-camera.c | 15 |
4 files changed, 101 insertions, 29 deletions
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 957927f7a353..b9847527eb5a 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c | |||
@@ -1069,29 +1069,35 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | |||
1069 | 1069 | ||
1070 | static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; | 1070 | static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; |
1071 | 1071 | ||
1072 | static int ov7670_enum_frameintervals(struct v4l2_subdev *sd, | 1072 | static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, |
1073 | struct v4l2_frmivalenum *interval) | 1073 | struct v4l2_subdev_pad_config *cfg, |
1074 | struct v4l2_subdev_frame_interval_enum *fie) | ||
1074 | { | 1075 | { |
1075 | if (interval->index >= ARRAY_SIZE(ov7670_frame_rates)) | 1076 | if (fie->pad) |
1076 | return -EINVAL; | 1077 | return -EINVAL; |
1077 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | 1078 | if (fie->index >= ARRAY_SIZE(ov7670_frame_rates)) |
1078 | interval->discrete.numerator = 1; | 1079 | return -EINVAL; |
1079 | interval->discrete.denominator = ov7670_frame_rates[interval->index]; | 1080 | fie->interval.numerator = 1; |
1081 | fie->interval.denominator = ov7670_frame_rates[fie->index]; | ||
1080 | return 0; | 1082 | return 0; |
1081 | } | 1083 | } |
1082 | 1084 | ||
1083 | /* | 1085 | /* |
1084 | * Frame size enumeration | 1086 | * Frame size enumeration |
1085 | */ | 1087 | */ |
1086 | static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | 1088 | static int ov7670_enum_frame_size(struct v4l2_subdev *sd, |
1087 | struct v4l2_frmsizeenum *fsize) | 1089 | struct v4l2_subdev_pad_config *cfg, |
1090 | struct v4l2_subdev_frame_size_enum *fse) | ||
1088 | { | 1091 | { |
1089 | struct ov7670_info *info = to_state(sd); | 1092 | struct ov7670_info *info = to_state(sd); |
1090 | int i; | 1093 | int i; |
1091 | int num_valid = -1; | 1094 | int num_valid = -1; |
1092 | __u32 index = fsize->index; | 1095 | __u32 index = fse->index; |
1093 | unsigned int n_win_sizes = info->devtype->n_win_sizes; | 1096 | unsigned int n_win_sizes = info->devtype->n_win_sizes; |
1094 | 1097 | ||
1098 | if (fse->pad) | ||
1099 | return -EINVAL; | ||
1100 | |||
1095 | /* | 1101 | /* |
1096 | * If a minimum width/height was requested, filter out the capture | 1102 | * If a minimum width/height was requested, filter out the capture |
1097 | * windows that fall outside that. | 1103 | * windows that fall outside that. |
@@ -1103,9 +1109,8 @@ static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | |||
1103 | if (info->min_height && win->height < info->min_height) | 1109 | if (info->min_height && win->height < info->min_height) |
1104 | continue; | 1110 | continue; |
1105 | if (index == ++num_valid) { | 1111 | if (index == ++num_valid) { |
1106 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | 1112 | fse->min_width = fse->max_width = win->width; |
1107 | fsize->discrete.width = win->width; | 1113 | fse->min_height = fse->max_height = win->height; |
1108 | fsize->discrete.height = win->height; | ||
1109 | return 0; | 1114 | return 0; |
1110 | } | 1115 | } |
1111 | } | 1116 | } |
@@ -1485,13 +1490,17 @@ static const struct v4l2_subdev_video_ops ov7670_video_ops = { | |||
1485 | .s_mbus_fmt = ov7670_s_mbus_fmt, | 1490 | .s_mbus_fmt = ov7670_s_mbus_fmt, |
1486 | .s_parm = ov7670_s_parm, | 1491 | .s_parm = ov7670_s_parm, |
1487 | .g_parm = ov7670_g_parm, | 1492 | .g_parm = ov7670_g_parm, |
1488 | .enum_frameintervals = ov7670_enum_frameintervals, | 1493 | }; |
1489 | .enum_framesizes = ov7670_enum_framesizes, | 1494 | |
1495 | static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { | ||
1496 | .enum_frame_interval = ov7670_enum_frame_interval, | ||
1497 | .enum_frame_size = ov7670_enum_frame_size, | ||
1490 | }; | 1498 | }; |
1491 | 1499 | ||
1492 | static const struct v4l2_subdev_ops ov7670_ops = { | 1500 | static const struct v4l2_subdev_ops ov7670_ops = { |
1493 | .core = &ov7670_core_ops, | 1501 | .core = &ov7670_core_ops, |
1494 | .video = &ov7670_video_ops, | 1502 | .video = &ov7670_video_ops, |
1503 | .pad = &ov7670_pad_ops, | ||
1495 | }; | 1504 | }; |
1496 | 1505 | ||
1497 | /* ----------------------------------------------------------------------- */ | 1506 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index dd5b1415f974..9c64b5d01c6a 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
@@ -1568,24 +1568,64 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv, | |||
1568 | struct v4l2_frmsizeenum *sizes) | 1568 | struct v4l2_frmsizeenum *sizes) |
1569 | { | 1569 | { |
1570 | struct mcam_camera *cam = priv; | 1570 | struct mcam_camera *cam = priv; |
1571 | struct mcam_format_struct *f; | ||
1572 | struct v4l2_subdev_frame_size_enum fse = { | ||
1573 | .index = sizes->index, | ||
1574 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1575 | }; | ||
1571 | int ret; | 1576 | int ret; |
1572 | 1577 | ||
1578 | f = mcam_find_format(sizes->pixel_format); | ||
1579 | if (f->pixelformat != sizes->pixel_format) | ||
1580 | return -EINVAL; | ||
1581 | fse.code = f->mbus_code; | ||
1573 | mutex_lock(&cam->s_mutex); | 1582 | mutex_lock(&cam->s_mutex); |
1574 | ret = sensor_call(cam, video, enum_framesizes, sizes); | 1583 | ret = sensor_call(cam, pad, enum_frame_size, NULL, &fse); |
1575 | mutex_unlock(&cam->s_mutex); | 1584 | mutex_unlock(&cam->s_mutex); |
1576 | return ret; | 1585 | if (ret) |
1586 | return ret; | ||
1587 | if (fse.min_width == fse.max_width && | ||
1588 | fse.min_height == fse.max_height) { | ||
1589 | sizes->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1590 | sizes->discrete.width = fse.min_width; | ||
1591 | sizes->discrete.height = fse.min_height; | ||
1592 | return 0; | ||
1593 | } | ||
1594 | sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
1595 | sizes->stepwise.min_width = fse.min_width; | ||
1596 | sizes->stepwise.max_width = fse.max_width; | ||
1597 | sizes->stepwise.min_height = fse.min_height; | ||
1598 | sizes->stepwise.max_height = fse.max_height; | ||
1599 | sizes->stepwise.step_width = 1; | ||
1600 | sizes->stepwise.step_height = 1; | ||
1601 | return 0; | ||
1577 | } | 1602 | } |
1578 | 1603 | ||
1579 | static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, | 1604 | static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, |
1580 | struct v4l2_frmivalenum *interval) | 1605 | struct v4l2_frmivalenum *interval) |
1581 | { | 1606 | { |
1582 | struct mcam_camera *cam = priv; | 1607 | struct mcam_camera *cam = priv; |
1608 | struct mcam_format_struct *f; | ||
1609 | struct v4l2_subdev_frame_interval_enum fie = { | ||
1610 | .index = interval->index, | ||
1611 | .width = interval->width, | ||
1612 | .height = interval->height, | ||
1613 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1614 | }; | ||
1583 | int ret; | 1615 | int ret; |
1584 | 1616 | ||
1617 | f = mcam_find_format(interval->pixel_format); | ||
1618 | if (f->pixelformat != interval->pixel_format) | ||
1619 | return -EINVAL; | ||
1620 | fie.code = f->mbus_code; | ||
1585 | mutex_lock(&cam->s_mutex); | 1621 | mutex_lock(&cam->s_mutex); |
1586 | ret = sensor_call(cam, video, enum_frameintervals, interval); | 1622 | ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); |
1587 | mutex_unlock(&cam->s_mutex); | 1623 | mutex_unlock(&cam->s_mutex); |
1588 | return ret; | 1624 | if (ret) |
1625 | return ret; | ||
1626 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1627 | interval->discrete = fie.interval; | ||
1628 | return 0; | ||
1589 | } | 1629 | } |
1590 | 1630 | ||
1591 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1631 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index cee7b56f8404..1ed0a0bc8d44 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
@@ -1888,22 +1888,34 @@ static int default_enum_framesizes(struct soc_camera_device *icd, | |||
1888 | int ret; | 1888 | int ret; |
1889 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1889 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1890 | const struct soc_camera_format_xlate *xlate; | 1890 | const struct soc_camera_format_xlate *xlate; |
1891 | __u32 pixfmt = fsize->pixel_format; | 1891 | struct v4l2_subdev_frame_size_enum fse = { |
1892 | struct v4l2_frmsizeenum fsize_mbus = *fsize; | 1892 | .index = fsize->index, |
1893 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1894 | }; | ||
1893 | 1895 | ||
1894 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1896 | xlate = soc_camera_xlate_by_fourcc(icd, fsize->pixel_format); |
1895 | if (!xlate) | 1897 | if (!xlate) |
1896 | return -EINVAL; | 1898 | return -EINVAL; |
1897 | /* map xlate-code to pixel_format, sensor only handle xlate-code*/ | 1899 | fse.code = xlate->code; |
1898 | fsize_mbus.pixel_format = xlate->code; | ||
1899 | 1900 | ||
1900 | ret = v4l2_subdev_call(sd, video, enum_framesizes, &fsize_mbus); | 1901 | ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse); |
1901 | if (ret < 0) | 1902 | if (ret < 0) |
1902 | return ret; | 1903 | return ret; |
1903 | 1904 | ||
1904 | *fsize = fsize_mbus; | 1905 | if (fse.min_width == fse.max_width && |
1905 | fsize->pixel_format = pixfmt; | 1906 | fse.min_height == fse.max_height) { |
1906 | 1907 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | |
1908 | fsize->discrete.width = fse.min_width; | ||
1909 | fsize->discrete.height = fse.min_height; | ||
1910 | return 0; | ||
1911 | } | ||
1912 | fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
1913 | fsize->stepwise.min_width = fse.min_width; | ||
1914 | fsize->stepwise.max_width = fse.max_width; | ||
1915 | fsize->stepwise.min_height = fse.min_height; | ||
1916 | fsize->stepwise.max_height = fse.max_height; | ||
1917 | fsize->stepwise.step_width = 1; | ||
1918 | fsize->stepwise.step_height = 1; | ||
1907 | return 0; | 1919 | return 0; |
1908 | } | 1920 | } |
1909 | 1921 | ||
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 86989d86abfa..678ed9f353cb 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c | |||
@@ -1147,12 +1147,23 @@ static int viacam_enum_frameintervals(struct file *filp, void *priv, | |||
1147 | struct v4l2_frmivalenum *interval) | 1147 | struct v4l2_frmivalenum *interval) |
1148 | { | 1148 | { |
1149 | struct via_camera *cam = priv; | 1149 | struct via_camera *cam = priv; |
1150 | struct v4l2_subdev_frame_interval_enum fie = { | ||
1151 | .index = interval->index, | ||
1152 | .code = cam->mbus_code, | ||
1153 | .width = cam->sensor_format.width, | ||
1154 | .height = cam->sensor_format.height, | ||
1155 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1156 | }; | ||
1150 | int ret; | 1157 | int ret; |
1151 | 1158 | ||
1152 | mutex_lock(&cam->lock); | 1159 | mutex_lock(&cam->lock); |
1153 | ret = sensor_call(cam, video, enum_frameintervals, interval); | 1160 | ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); |
1154 | mutex_unlock(&cam->lock); | 1161 | mutex_unlock(&cam->lock); |
1155 | return ret; | 1162 | if (ret) |
1163 | return ret; | ||
1164 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1165 | interval->discrete = fie.interval; | ||
1166 | return 0; | ||
1156 | } | 1167 | } |
1157 | 1168 | ||
1158 | 1169 | ||