diff options
author | Johannes Obermaier <johannes.obermaier@gmail.com> | 2011-06-02 11:43:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:52:25 -0400 |
commit | 590929f32adc3aaa702c287b624a0d0382730088 (patch) | |
tree | 6d6e194c9d52ede5cd21170298f81a0f05b30282 | |
parent | 1048af2f810b3d08210c600ca3c8e84877edbbc7 (diff) |
[media] mt9v011: Added exposure for mt9v011
There are problems when you use this camera/sensor in a very bright room
or outside. The image is completely white, because it is overexposed.
The driver uses a default value which is not suitable for all
environments.
This patch makes it possible to adjust the exposure time by youself. I
found out by logging the i2c-data, that the windows driver for this
sensor is doing this, too. I tested the camera on a sunny day and after
adjusting the exposure time, I was able to see a very good image.
Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Johannes Obermaier <johannes.obermaier@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/mt9v011.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index a6cf05aa4550..fbbd018c94ab 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c | |||
@@ -59,6 +59,15 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = { | |||
59 | .default_value = 0x0020, | 59 | .default_value = 0x0020, |
60 | .flags = 0, | 60 | .flags = 0, |
61 | }, { | 61 | }, { |
62 | .id = V4L2_CID_EXPOSURE, | ||
63 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
64 | .name = "Exposure", | ||
65 | .minimum = 0, | ||
66 | .maximum = 2047, | ||
67 | .step = 1, | ||
68 | .default_value = 0x01fc, | ||
69 | .flags = 0, | ||
70 | }, { | ||
62 | .id = V4L2_CID_RED_BALANCE, | 71 | .id = V4L2_CID_RED_BALANCE, |
63 | .type = V4L2_CTRL_TYPE_INTEGER, | 72 | .type = V4L2_CTRL_TYPE_INTEGER, |
64 | .name = "Red Balance", | 73 | .name = "Red Balance", |
@@ -105,7 +114,7 @@ struct mt9v011 { | |||
105 | unsigned hflip:1; | 114 | unsigned hflip:1; |
106 | unsigned vflip:1; | 115 | unsigned vflip:1; |
107 | 116 | ||
108 | u16 global_gain, red_bal, blue_bal; | 117 | u16 global_gain, exposure, red_bal, blue_bal; |
109 | }; | 118 | }; |
110 | 119 | ||
111 | static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd) | 120 | static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd) |
@@ -184,6 +193,9 @@ static void set_balance(struct v4l2_subdev *sd) | |||
184 | { | 193 | { |
185 | struct mt9v011 *core = to_mt9v011(sd); | 194 | struct mt9v011 *core = to_mt9v011(sd); |
186 | u16 green1_gain, green2_gain, blue_gain, red_gain; | 195 | u16 green1_gain, green2_gain, blue_gain, red_gain; |
196 | u16 exposure; | ||
197 | |||
198 | exposure = core->exposure; | ||
187 | 199 | ||
188 | green1_gain = core->global_gain; | 200 | green1_gain = core->global_gain; |
189 | green2_gain = core->global_gain; | 201 | green2_gain = core->global_gain; |
@@ -198,6 +210,7 @@ static void set_balance(struct v4l2_subdev *sd) | |||
198 | mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain); | 210 | mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain); |
199 | mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain); | 211 | mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain); |
200 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); | 212 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); |
213 | mt9v011_write(sd, R09_MT9V011_SHUTTER_WIDTH, exposure); | ||
201 | } | 214 | } |
202 | 215 | ||
203 | static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator) | 216 | static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator) |
@@ -338,6 +351,9 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
338 | case V4L2_CID_GAIN: | 351 | case V4L2_CID_GAIN: |
339 | ctrl->value = core->global_gain; | 352 | ctrl->value = core->global_gain; |
340 | return 0; | 353 | return 0; |
354 | case V4L2_CID_EXPOSURE: | ||
355 | ctrl->value = core->exposure; | ||
356 | return 0; | ||
341 | case V4L2_CID_RED_BALANCE: | 357 | case V4L2_CID_RED_BALANCE: |
342 | ctrl->value = core->red_bal; | 358 | ctrl->value = core->red_bal; |
343 | return 0; | 359 | return 0; |
@@ -392,6 +408,9 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
392 | case V4L2_CID_GAIN: | 408 | case V4L2_CID_GAIN: |
393 | core->global_gain = ctrl->value; | 409 | core->global_gain = ctrl->value; |
394 | break; | 410 | break; |
411 | case V4L2_CID_EXPOSURE: | ||
412 | core->exposure = ctrl->value; | ||
413 | break; | ||
395 | case V4L2_CID_RED_BALANCE: | 414 | case V4L2_CID_RED_BALANCE: |
396 | core->red_bal = ctrl->value; | 415 | core->red_bal = ctrl->value; |
397 | break; | 416 | break; |
@@ -598,6 +617,7 @@ static int mt9v011_probe(struct i2c_client *c, | |||
598 | } | 617 | } |
599 | 618 | ||
600 | core->global_gain = 0x0024; | 619 | core->global_gain = 0x0024; |
620 | core->exposure = 0x01fc; | ||
601 | core->width = 640; | 621 | core->width = 640; |
602 | core->height = 480; | 622 | core->height = 480; |
603 | core->xtal = 27000000; /* Hz */ | 623 | core->xtal = 27000000; /* Hz */ |