From b9576234a604a0c90a1afe0cb75c0905b4da0663 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Mon, 5 Nov 2012 16:29:18 +0800 Subject: ENGR00231307 csi/camera: add some ioctls added ioctls are: VIDIOC_ENUM_FRAMEINTERVALS VIDIOC_ENUM_FRAMESIZES VIDIOC_ENUM_FMT VIDIOC_DBG_G_CHIP_IDENT Signed-off-by: Robby Cai --- drivers/media/video/mxc/capture/csi_v4l2_capture.c | 45 +++++++++++++++++- drivers/media/video/mxc/capture/ov5640.c | 54 +++++++++++++++++++++- drivers/media/video/mxc/capture/ov5642.c | 53 ++++++++++++++++++++- 3 files changed, 149 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c index 3756b00a844d..c3ec6e4e89d1 100644 --- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "mxc_v4l2_capture.h" #include "fsl_csi.h" @@ -1264,6 +1265,49 @@ static long csi_v4l_do_ioctl(struct file *file, retval = csi_streamoff(cam); break; } + case VIDIOC_ENUM_FMT: { + struct v4l2_fmtdesc *fmt = arg; + if (cam->sensor) + retval = vidioc_int_enum_fmt_cap(cam->sensor, fmt); + else { + pr_err("ERROR: v4l2 capture: slave not found!\n"); + retval = -ENODEV; + } + break; + } + case VIDIOC_ENUM_FRAMESIZES: { + struct v4l2_frmsizeenum *fsize = arg; + if (cam->sensor) + retval = vidioc_int_enum_framesizes(cam->sensor, fsize); + else { + pr_err("ERROR: v4l2 capture: slave not found!\n"); + retval = -ENODEV; + } + break; + } + case VIDIOC_ENUM_FRAMEINTERVALS: { + struct v4l2_frmivalenum *fival = arg; + if (cam->sensor) + retval = vidioc_int_enum_frameintervals(cam->sensor, + fival); + else { + pr_err("ERROR: v4l2 capture: slave not found!\n"); + retval = -ENODEV; + } + break; + } + case VIDIOC_DBG_G_CHIP_IDENT: { + struct v4l2_dbg_chip_ident *p = arg; + p->ident = V4L2_IDENT_NONE; + p->revision = 0; + if (cam->sensor) + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p); + else { + pr_err("ERROR: v4l2 capture: slave not found!\n"); + retval = -ENODEV; + } + break; + } case VIDIOC_S_CTRL: case VIDIOC_G_STD: @@ -1274,7 +1318,6 @@ static long csi_v4l_do_ioctl(struct file *file, case VIDIOC_CROPCAP: case VIDIOC_S_STD: case VIDIOC_G_CTRL: - case VIDIOC_ENUM_FMT: case VIDIOC_TRY_FMT: case VIDIOC_QUERYCTRL: case VIDIOC_ENUMINPUT: diff --git a/drivers/media/video/mxc/capture/ov5640.c b/drivers/media/video/mxc/capture/ov5640.c index f73e4f1eece0..2e67bfc390b8 100644 --- a/drivers/media/video/mxc/capture/ov5640.c +++ b/drivers/media/video/mxc/capture/ov5640.c @@ -60,6 +60,12 @@ enum ov5640_frame_rate { ov5640_30_fps }; + +static int ov5640_framerates[] = { + [ov5640_15_fps] = 15, + [ov5640_30_fps] = 30, +}; + struct reg_value { u16 u16RegAddr; u8 u8Val; @@ -1242,6 +1248,50 @@ static int ioctl_enum_framesizes(struct v4l2_int_device *s, return 0; } +/*! + * ioctl_enum_frameintervals - V4L2 sensor interface handler for + * VIDIOC_ENUM_FRAMEINTERVALS ioctl + * @s: pointer to standard V4L2 device structure + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure + * + * Return 0 if successful, otherwise -EINVAL. + */ +static int ioctl_enum_frameintervals(struct v4l2_int_device *s, + struct v4l2_frmivalenum *fival) +{ + int i, j, count; + + if (fival->index < 0 || fival->index > ov5640_mode_MAX) + return -EINVAL; + + if (fival->pixel_format == 0 || fival->width == 0 || fival->height == 0) { + pr_warning("Please assign pixelformat, width and height.\n"); + return -EINVAL; + } + + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + fival->discrete.numerator = 1; + + count = 0; + for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) { + for (j = 0; j < (ov5640_mode_MAX + 1); j++) { + if (fival->pixel_format == ov5640_data.pix.pixelformat + && fival->width == ov5640_mode_info_data[i][j].width + && fival->height == ov5640_mode_info_data[i][j].height + && ov5640_mode_info_data[i][j].init_data_ptr != NULL) { + count++; + } + if (fival->index == (count - 1)) { + fival->discrete.denominator = + ov5640_framerates[i]; + return 0; + } + } + } + + return -EINVAL; +} + /*! * ioctl_g_chip_ident - V4L2 sensor interface handler for * VIDIOC_DBG_G_CHIP_IDENT ioctl @@ -1279,7 +1329,7 @@ static int ioctl_init(struct v4l2_int_device *s) static int ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) { - if (fmt->index > ov5640_mode_MAX) + if (fmt->index > 0) /* only 1 pixelformat support so far */ return -EINVAL; fmt->pixelformat = ov5640_data.pix.pixelformat; @@ -1363,6 +1413,8 @@ static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = { {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *)ioctl_s_ctrl}, {vidioc_int_enum_framesizes_num, (v4l2_int_ioctl_func *)ioctl_enum_framesizes}, + {vidioc_int_enum_frameintervals_num, + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals}, {vidioc_int_g_chip_ident_num, (v4l2_int_ioctl_func *)ioctl_g_chip_ident}, }; diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c index 426438276908..5653a6b1c35a 100644 --- a/drivers/media/video/mxc/capture/ov5642.c +++ b/drivers/media/video/mxc/capture/ov5642.c @@ -65,6 +65,11 @@ enum ov5642_frame_rate { ov5642_30_fps }; +static int ov5642_framerates[] = { + [ov5642_15_fps] = 15, + [ov5642_30_fps] = 30, +}; + struct reg_value { u16 u16RegAddr; u8 u8Val; @@ -3738,6 +3743,50 @@ static int ioctl_enum_framesizes(struct v4l2_int_device *s, return 0; } +/*! + * ioctl_enum_frameintervals - V4L2 sensor interface handler for + * VIDIOC_ENUM_FRAMEINTERVALS ioctl + * @s: pointer to standard V4L2 device structure + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure + * + * Return 0 if successful, otherwise -EINVAL. + */ +static int ioctl_enum_frameintervals(struct v4l2_int_device *s, + struct v4l2_frmivalenum *fival) +{ + int i, j, count; + + if (fival->index < 0 || fival->index > ov5642_mode_MAX) + return -EINVAL; + + if (fival->pixel_format == 0 || fival->width == 0 || fival->height == 0) { + pr_warning("Please assign pixelformat, width and height.\n"); + return -EINVAL; + } + + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + fival->discrete.numerator = 1; + + count = 0; + for (i = 0; i < ARRAY_SIZE(ov5642_mode_info_data); i++) { + for (j = 0; j < (ov5642_mode_MAX + 1); j++) { + if (fival->pixel_format == ov5642_data.pix.pixelformat + && fival->width == ov5642_mode_info_data[i][j].width + && fival->height == ov5642_mode_info_data[i][j].height + && ov5642_mode_info_data[i][j].init_data_ptr != NULL) { + count++; + } + if (fival->index == (count - 1)) { + fival->discrete.denominator = + ov5642_framerates[i]; + return 0; + } + } + } + + return -EINVAL; +} + /*! * ioctl_g_chip_ident - V4L2 sensor interface handler for * VIDIOC_DBG_G_CHIP_IDENT ioctl @@ -3775,7 +3824,7 @@ static int ioctl_init(struct v4l2_int_device *s) static int ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) { - if (fmt->index > ov5642_mode_MAX) + if (fmt->index > 0) /* only 1 pixelformat support so far */ return -EINVAL; fmt->pixelformat = ov5642_data.pix.pixelformat; @@ -3894,6 +3943,8 @@ static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = { {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *)ioctl_s_ctrl}, {vidioc_int_enum_framesizes_num, (v4l2_int_ioctl_func *)ioctl_enum_framesizes}, + {vidioc_int_enum_frameintervals_num, + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals}, {vidioc_int_g_chip_ident_num, (v4l2_int_ioctl_func *)ioctl_g_chip_ident}, }; -- cgit v1.2.3