summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Ollonen <marko.ollonen@ixonos.com>2013-01-23 09:39:35 +0200
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-03-04 16:14:12 +0200
commit92fa5af276c04b2fa19d47f5fa5593d47adaec38 (patch)
tree16c8b5b65f83cbe80194bd850f6d514ddc3b48fb
parente7705822652e1b97326135b42aeba629326dfad8 (diff)
downloadkernel-mfld-blackbay-92fa5af276c04b2fa19d47f5fa5593d47adaec38.tar.gz
kernel-mfld-blackbay-92fa5af276c04b2fa19d47f5fa5593d47adaec38.tar.bz2
kernel-mfld-blackbay-92fa5af276c04b2fa19d47f5fa5593d47adaec38.zip
camera: exposure value query to mt9e013
-rw-r--r--drivers/media/video/mt9e013/mt9e013.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/drivers/media/video/mt9e013/mt9e013.c b/drivers/media/video/mt9e013/mt9e013.c
index c40c7627236..544d4577eb4 100644
--- a/drivers/media/video/mt9e013/mt9e013.c
+++ b/drivers/media/video/mt9e013/mt9e013.c
@@ -63,6 +63,11 @@
* (result is 0 if b == 0) */
#define divsave_rounded(a, b) (((b) != 0) ? (((a)+((b)>>1))/(b)) : (-1))
+/* TODO: this should not be a constant but should be set by a call to
+ * MSIC's driver to get the ext_clk that MSIC supllies to the sensor.
+ */
+static const int ext_clk_freq_mhz = 19200000;
+
static int
mt9e013_read_reg(struct i2c_client *client, u16 len, u16 reg, u16 *val)
{
@@ -1059,10 +1064,7 @@ mt9e013_get_intg_factor(struct i2c_client *client,
unsigned int op_pix_clk_div;
unsigned int op_sys_clk_div;
- /* TODO: this should not be a constant but should be set by a call to
- * MSIC's driver to get the ext_clk that MSIC supllies to the sensor.
- */
- const int ext_clk_freq_mhz = 19200000;
+
struct sensor_mode_data buf;
const struct mt9e013_reg *next = reglist;
int vt_pix_clk_freq_mhz;
@@ -1144,14 +1146,42 @@ mt9e013_get_intg_factor(struct i2c_client *client,
static int mt9e013_q_exposure(struct v4l2_subdev *sd, s32 *value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- u16 coarse;
+ unsigned int vt_pix_clk_div;
+ unsigned int vt_sys_clk_div;
+ unsigned int pre_pll_clk_div;
+ unsigned int pll_multiplier;
+ u16 data[MT9E013_SHORT_MAX];
+ u16 coarse,fine,line_length_pck;
+ int pixel_clk_freq;
int ret;
- /* the fine integration time is currently not calculated */
+ memset(data, 0, MT9E013_SHORT_MAX * sizeof(u16));
+ if (mt9e013_read_reg(client, 12, MT9E013_VT_PIX_CLK_DIV, data))
+ return -EINVAL;
+ vt_pix_clk_div = data[0];
+ vt_sys_clk_div = data[1];
+ pre_pll_clk_div = data[2];
+ pll_multiplier = data[3];
+ pixel_clk_freq = divsave_rounded(ext_clk_freq_mhz*pll_multiplier,
+ pre_pll_clk_div*vt_sys_clk_div*vt_pix_clk_div);
+
+
+ memset(data, 0, MT9E013_SHORT_MAX * sizeof(u16));
+ ret = mt9e013_read_reg(client, 4,
+ MT9E013_COARSE_INTEGRATION_TIME, data);
+ coarse = data[0];
+ fine = data[1];
+
ret = mt9e013_read_reg(client, MT9E013_16BIT,
- MT9E013_COARSE_INTEGRATION_TIME, &coarse);
- *value = coarse;
+ MT9E013_LINE_LENGTH_PCK, data);
+ line_length_pck = data[0];
+ /* divide meaninless zeros already in numerator to
+ * get numerator fit to 16 bit.
+ */
+ pixel_clk_freq = pixel_clk_freq / 100000;
+ *value = (((coarse * line_length_pck + fine)/100000) << 16)
+ + pixel_clk_freq;
return ret;
}
@@ -1250,7 +1280,7 @@ static struct mt9e013_control mt9e013_controls[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "exposure",
.minimum = 0x0,
- .maximum = 0xffff,
+ .maximum = 0xffffffff,
.step = 0x01,
.default_value = 0x00,
.flags = 0,