]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00231307 csi/camera: add some ioctls
authorRobby Cai <R63905@freescale.com>
Mon, 5 Nov 2012 08:29:18 +0000 (16:29 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:44 +0000 (08:35 +0200)
added ioctls are:
VIDIOC_ENUM_FRAMEINTERVALS
VIDIOC_ENUM_FRAMESIZES
VIDIOC_ENUM_FMT
VIDIOC_DBG_G_CHIP_IDENT

Signed-off-by: Robby Cai <R63905@freescale.com>
drivers/media/video/mxc/capture/csi_v4l2_capture.c
drivers/media/video/mxc/capture/ov5640.c
drivers/media/video/mxc/capture/ov5642.c

index 3756b00a844db4133b9457e67ad283e3491bf833..c3ec6e4e89d158058f725c682cfc99884d51de10 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/dma-mapping.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-int-device.h>
+#include <media/v4l2-chip-ident.h>
 #include <linux/mxcfb.h>
 #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:
index f73e4f1eece08c60aec2ed71a4596ab565d044b3..2e67bfc390b88ad97c739e2dccf0a894d6f77b01 100644 (file)
@@ -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},
 };
index 426438276908d924f7006c49c4f9b127800ae54d..5653a6b1c35a8929e09929249482dfeec446d35f 100644 (file)
@@ -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},
 };