]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
drivers: camera: Mode selection logic
authorBhanu Murthy V <bmurthyv@nvidia.com>
Fri, 19 Aug 2016 00:08:21 +0000 (17:08 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Tue, 6 Jun 2017 23:48:25 +0000 (16:48 -0700)
Segregate mode selection logic into standard
and special types. Standard mode selection
will be based on pixel format and special type
selection will depend on sensor settings defined
by controls.

Bug 200214096
Bug 200227485

Change-Id: Ic020017ddf635aa5662370903efd660150d319be
Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com>
Reviewed-on: http://git-master/r/1204713
(cherry picked from commit f551889dd77b04b095cb4064eea33bf8151fa57a)
Reviewed-on: http://git-master/r/1483448
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Frank Chen <frankc@nvidia.com>
Tested-by: Frank Chen <frankc@nvidia.com>
Reviewed-by: Hu He <hhe@nvidia.com>
Reviewed-by: Shantanu Nath <snath@nvidia.com>
drivers/media/platform/tegra/camera/camera_common.c

index b84538e91eb2052eba3716300d4c74809578fd80..c0fabbd2ba0541a6553614cb102a23f0b54c2b6c 100644 (file)
@@ -30,6 +30,8 @@
        (has_s_op(master, op) ? \
         master->ops->op(master, __VA_ARGS__) : 0)
 
+#define HDR_ENABLE             0x1
+
 static const struct camera_common_colorfmt camera_common_color_fmts[] = {
        {
                MEDIA_BUS_FMT_SRGGB12_1X12,
@@ -406,6 +408,30 @@ int camera_common_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static void select_mode(struct camera_common_data *s_data,
+                       struct v4l2_mbus_framefmt *mf,
+                       unsigned int mode_type)
+{
+       int i;
+       const struct camera_common_frmfmt *frmfmt = s_data->frmfmt;
+       bool flag = 0;
+
+       for (i = 0; i < s_data->numfmts; i++) {
+               if (mode_type & HDR_ENABLE)
+                       flag = !frmfmt[i].hdr_en;
+               /* Add more flags for different controls as needed */
+
+               if (flag)
+                       continue;
+
+               if (mf->width == frmfmt[i].size.width &&
+                       mf->height == frmfmt[i].size.height) {
+                       s_data->mode = frmfmt[i].mode;
+                       break;
+               }
+       }
+}
+
 int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -413,7 +439,7 @@ int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
        struct tegra_channel *chan = v4l2_get_subdev_hostdata(sd);
        struct v4l2_control hdr_control;
        const struct camera_common_frmfmt *frmfmt = s_data->frmfmt;
-       int hdr_en;
+       unsigned int mode_type = 0;
        int err = 0;
        int i;
 
@@ -429,7 +455,8 @@ int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                return err;
        }
 
-       hdr_en = switch_ctrl_qmenu[hdr_control.value];
+       /* mode_type can be filled in sensor driver */
+       mode_type |= switch_ctrl_qmenu[hdr_control.value] ? HDR_ENABLE : 0;
 
        s_data->mode = s_data->def_mode;
        s_data->fmt_width = s_data->def_width;
@@ -444,10 +471,10 @@ int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                s_data->fmt_width = mf->width;
                s_data->fmt_height = mf->height;
        } else {
+               /* select mode based on format match first */
                for (i = 0; i < s_data->numfmts; i++) {
                        if (mf->width == frmfmt[i].size.width &&
-                               mf->height == frmfmt[i].size.height &&
-                               hdr_en == frmfmt[i].hdr_en) {
+                               mf->height == frmfmt[i].size.height) {
                                s_data->mode = frmfmt[i].mode;
                                s_data->fmt_width = mf->width;
                                s_data->fmt_height = mf->height;
@@ -461,12 +488,17 @@ int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                        dev_dbg(&client->dev,
                                "%s: invalid resolution supplied to set mode %d %d\n",
                                __func__, mf->width, mf->height);
+                       goto verify_code;
                }
+               /* update mode based on special mode types */
+               if (mode_type)
+                       select_mode(s_data, mf, mode_type);
        }
 
        if (!camera_common_verify_code(chan, mf->code))
                err = -EINVAL;
 
+verify_code:
        mf->field = V4L2_FIELD_NONE;
        mf->colorspace = V4L2_COLORSPACE_SRGB;
        mf->xfer_func = V4L2_XFER_FUNC_DEFAULT;