aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v011.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9v011.c')
-rw-r--r--drivers/media/video/mt9v011.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
index 241382f5ba21..f7b5279a7d5a 100644
--- a/drivers/media/video/mt9v011.c
+++ b/drivers/media/video/mt9v011.c
@@ -8,6 +8,7 @@
8#include <linux/i2c.h> 8#include <linux/i2c.h>
9#include <linux/videodev2.h> 9#include <linux/videodev2.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <asm/div64.h>
11#include <media/v4l2-device.h> 12#include <media/v4l2-device.h>
12#include "mt9v011.h" 13#include "mt9v011.h"
13#include <media/v4l2-i2c-drv.h> 14#include <media/v4l2-i2c-drv.h>
@@ -57,6 +58,7 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = {
57struct mt9v011 { 58struct mt9v011 {
58 struct v4l2_subdev sd; 59 struct v4l2_subdev sd;
59 unsigned width, height; 60 unsigned width, height;
61 unsigned xtal;
60 62
61 u16 global_gain, red_bal, blue_bal; 63 u16 global_gain, red_bal, blue_bal;
62}; 64};
@@ -131,7 +133,7 @@ static const struct i2c_reg_value mt9v011_init_default[] = {
131 { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, 133 { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
132 { R20_MT9V011_READ_MODE, 0x1000 }, 134 { R20_MT9V011_READ_MODE, 0x1000 },
133 135
134 { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */ 136 { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */
135}; 137};
136 138
137static void set_balance(struct v4l2_subdev *sd) 139static void set_balance(struct v4l2_subdev *sd)
@@ -154,6 +156,31 @@ static void set_balance(struct v4l2_subdev *sd)
154 mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); 156 mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
155} 157}
156 158
159static void calc_fps(struct v4l2_subdev *sd)
160{
161 struct mt9v011 *core = to_mt9v011(sd);
162 unsigned height, width, hblank, vblank, speed;
163 unsigned row_time, t_time;
164 u64 frames_per_ms;
165 unsigned tmp;
166
167 height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
168 width = mt9v011_read(sd, R04_MT9V011_WIDTH);
169 hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
170 vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
171 speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED);
172
173 row_time = (width + 113 + hblank) * (speed + 2);
174 t_time = row_time * (height + vblank + 1);
175
176 frames_per_ms = core->xtal * 1000l;
177 do_div(frames_per_ms, t_time);
178 tmp = frames_per_ms;
179
180 v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
181 tmp / 1000, tmp % 1000, t_time);
182}
183
157static void set_res(struct v4l2_subdev *sd) 184static void set_res(struct v4l2_subdev *sd)
158{ 185{
159 struct mt9v011 *core = to_mt9v011(sd); 186 struct mt9v011 *core = to_mt9v011(sd);
@@ -179,6 +206,8 @@ static void set_res(struct v4l2_subdev *sd)
179 mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); 206 mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
180 mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); 207 mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
181 mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); 208 mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
209
210 calc_fps(sd);
182}; 211};
183 212
184static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) 213static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
@@ -413,6 +442,7 @@ static int mt9v011_probe(struct i2c_client *c,
413 core->global_gain = 0x0024; 442 core->global_gain = 0x0024;
414 core->width = 640; 443 core->width = 640;
415 core->height = 480; 444 core->height = 480;
445 core->xtal = 27000000; /* Hz */
416 446
417 v4l_info(c, "chip found @ 0x%02x (%s)\n", 447 v4l_info(c, "chip found @ 0x%02x (%s)\n",
418 c->addr << 1, c->adapter->name); 448 c->addr << 1, c->adapter->name);