summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@bootlin.com>2018-12-03 09:44:26 +0100
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-12-05 12:50:49 +0100
commite823fb165b763bf0e42bceb9ab45cb9f7589d871 (patch)
tree8998f9a2c8dc947550ff0d901dbc125ceeb0ab87 /drivers
parentmedia: ov5640: Make the FPS clamping / rounding more extendable (diff)
downloadlinux-e823fb165b763bf0e42bceb9ab45cb9f7589d871.tar.xz
linux-e823fb165b763bf0e42bceb9ab45cb9f7589d871.zip
media: ov5640: Add 60 fps support
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/i2c/ov5640.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 93fa072135ad..6391ea4f712c 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -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);