OSDN Git Service

media: ov5640: Add 60 fps support
authorMaxime Ripard <maxime.ripard@bootlin.com>
Mon, 3 Dec 2018 08:44:26 +0000 (03:44 -0500)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Wed, 5 Dec 2018 11:50:49 +0000 (06:50 -0500)
Now that we have everything in place to compute the clock rate at runtime,
we can enable the 60fps framerate for the mode we tested it with.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Tested-by: Adam Ford <aford173@gmail.com> #imx6dq
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/i2c/ov5640.c

index 93fa072..6391ea4 100644 (file)
@@ -111,6 +111,7 @@ enum ov5640_mode_id {
 enum ov5640_frame_rate {
        OV5640_15_FPS = 0,
        OV5640_30_FPS,
+       OV5640_60_FPS,
        OV5640_NUM_FRAMERATES,
 };
 
@@ -139,6 +140,7 @@ MODULE_PARM_DESC(virtual_channel,
 static const int ov5640_framerates[] = {
        [OV5640_15_FPS] = 15,
        [OV5640_30_FPS] = 30,
+       [OV5640_60_FPS] = 60,
 };
 
 /* regulator supplies */
@@ -1562,6 +1564,11 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
            (!nearest && (mode->hact != width || mode->vact != height)))
                return NULL;
 
+       /* Only 640x480 can operate at 60fps (for now) */
+       if (fr == OV5640_60_FPS &&
+           !(mode->hact == 640 && mode->vact == 480))
+               return NULL;
+
        return mode;
 }
 
@@ -2057,12 +2064,13 @@ static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
        int i;
 
        minfps = ov5640_framerates[OV5640_15_FPS];
-       maxfps = ov5640_framerates[OV5640_30_FPS];
+       maxfps = ov5640_framerates[OV5640_60_FPS];
 
        if (fi->numerator == 0) {
                fi->denominator = maxfps;
                fi->numerator = 1;
-               return OV5640_30_FPS;
+               rate = OV5640_60_FPS;
+               goto find_mode;
        }
 
        fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
@@ -2081,6 +2089,7 @@ static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
        fi->numerator = 1;
        fi->denominator = best_fps;
 
+find_mode:
        mode = ov5640_find_mode(sensor, rate, width, height, false);
        return mode ? rate : -EINVAL;
 }
@@ -2699,8 +2708,11 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
 
        frame_rate = ov5640_try_frame_interval(sensor, &fi->interval,
                                               mode->hact, mode->vact);
-       if (frame_rate < 0)
-               frame_rate = OV5640_15_FPS;
+       if (frame_rate < 0) {
+               /* Always return a valid frame interval value */
+               fi->interval = sensor->frame_interval;
+               goto out;
+       }
 
        mode = ov5640_find_mode(sensor, frame_rate, mode->hact,
                                mode->vact, true);