summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-14 02:38:18 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-07-14 02:38:18 -0300
commit3c16945bd290ac09d7aa8a70c69d8f359eb53a09 (patch)
tree1677b5e25c507b4e91bdc4e8d8c8fb27a037e46f
parent50d2769688b47965b7ef2a6b60eba8d80d5dc156 (diff)
downloadmediapointer-dvb-s2-3c16945bd290ac09d7aa8a70c69d8f359eb53a09.tar.gz
mediapointer-dvb-s2-3c16945bd290ac09d7aa8a70c69d8f359eb53a09.tar.bz2
mt9v011: add a function to calculate frames per second rate
From: Mauro Carvalho Chehab <mchehab@redhat.com> It is possible to adjust the fps rate by changing some register values. This is function of the connected Xtal at the camera sensor, being a 27 MHz cristal needed, in order to support 640x480 at 30 fps. For now, it will only calculate the values for fps. Later patches may introduce V4L2 ioctls, to allow frequency rate adjustments. Priority: normal Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--linux/drivers/media/video/mt9v011.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/linux/drivers/media/video/mt9v011.c b/linux/drivers/media/video/mt9v011.c
index 947a23ac0..43420d311 100644
--- a/linux/drivers/media/video/mt9v011.c
+++ b/linux/drivers/media/video/mt9v011.c
@@ -9,6 +9,7 @@
#include "compat.h"
#include <linux/videodev2.h>
#include <linux/delay.h>
+#include <asm/div64.h>
#include <media/v4l2-device.h>
#include "mt9v011.h"
#include <media/v4l2-i2c-drv.h>
@@ -67,6 +68,7 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = {
struct mt9v011 {
struct v4l2_subdev sd;
unsigned width, height;
+ unsigned xtal;
u16 global_gain, red_bal, blue_bal;
};
@@ -141,7 +143,7 @@ static const struct i2c_reg_value mt9v011_init_default[] = {
{ R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
{ R20_MT9V011_READ_MODE, 0x1000 },
- { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */
+ { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */
};
static void set_balance(struct v4l2_subdev *sd)
@@ -164,6 +166,31 @@ static void set_balance(struct v4l2_subdev *sd)
mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
}
+static void calc_fps(struct v4l2_subdev *sd)
+{
+ struct mt9v011 *core = to_mt9v011(sd);
+ unsigned height, width, hblank, vblank, speed;
+ unsigned row_time, t_time;
+ u64 frames_per_ms;
+ unsigned tmp;
+
+ height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
+ width = mt9v011_read(sd, R04_MT9V011_WIDTH);
+ hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
+ vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
+ speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);
+
+ row_time = (width + 113 + hblank) * (speed + 2);
+ t_time = row_time * (height + vblank + 1);
+
+ frames_per_ms = core->xtal * 1000l;
+ do_div(frames_per_ms, t_time);
+ tmp = frames_per_ms;
+
+ v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
+ tmp / 1000, tmp % 1000, t_time);
+}
+
static void set_res(struct v4l2_subdev *sd)
{
struct mt9v011 *core = to_mt9v011(sd);
@@ -189,6 +216,8 @@ static void set_res(struct v4l2_subdev *sd)
mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
+
+ calc_fps(sd);
};
static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
@@ -423,6 +452,7 @@ static int mt9v011_probe(struct i2c_client *c,
core->global_gain = 0x0024;
core->width = 640;
core->height = 480;
+ core->xtal = 27000000; /* Hz */
v4l_info(c, "chip found @ 0x%02x (%s)\n",
c->addr << 1, c->adapter->name);