diff options
Diffstat (limited to 'drivers/media/video/mt9t031.c')
-rw-r--r-- | drivers/media/video/mt9t031.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 9a6489689382..6966f644977e 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -73,6 +73,8 @@ struct mt9t031 { | |||
73 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ | 73 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ |
74 | u16 xskip; | 74 | u16 xskip; |
75 | u16 yskip; | 75 | u16 yskip; |
76 | unsigned int gain; | ||
77 | unsigned int exposure; | ||
76 | unsigned char autoexposure; | 78 | unsigned char autoexposure; |
77 | }; | 79 | }; |
78 | 80 | ||
@@ -301,16 +303,15 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
301 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, | 303 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, |
302 | rect->height + icd->y_skip_top - 1); | 304 | rect->height + icd->y_skip_top - 1); |
303 | if (ret >= 0 && mt9t031->autoexposure) { | 305 | if (ret >= 0 && mt9t031->autoexposure) { |
304 | ret = set_shutter(client, | 306 | unsigned int total_h = rect->height + icd->y_skip_top + vblank; |
305 | rect->height + icd->y_skip_top + vblank); | 307 | ret = set_shutter(client, total_h); |
306 | if (ret >= 0) { | 308 | if (ret >= 0) { |
307 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 309 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
308 | const struct v4l2_queryctrl *qctrl = | 310 | const struct v4l2_queryctrl *qctrl = |
309 | soc_camera_find_qctrl(icd->ops, | 311 | soc_camera_find_qctrl(icd->ops, |
310 | V4L2_CID_EXPOSURE); | 312 | V4L2_CID_EXPOSURE); |
311 | icd->exposure = (shutter_max / 2 + (rect->height + | 313 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
312 | icd->y_skip_top + vblank - 1) * | 314 | (qctrl->maximum - qctrl->minimum)) / |
313 | (qctrl->maximum - qctrl->minimum)) / | ||
314 | shutter_max + qctrl->minimum; | 315 | shutter_max + qctrl->minimum; |
315 | } | 316 | } |
316 | } | 317 | } |
@@ -553,6 +554,12 @@ static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
553 | case V4L2_CID_EXPOSURE_AUTO: | 554 | case V4L2_CID_EXPOSURE_AUTO: |
554 | ctrl->value = mt9t031->autoexposure; | 555 | ctrl->value = mt9t031->autoexposure; |
555 | break; | 556 | break; |
557 | case V4L2_CID_GAIN: | ||
558 | ctrl->value = mt9t031->gain; | ||
559 | break; | ||
560 | case V4L2_CID_EXPOSURE: | ||
561 | ctrl->value = mt9t031->exposure; | ||
562 | break; | ||
556 | } | 563 | } |
557 | return 0; | 564 | return 0; |
558 | } | 565 | } |
@@ -624,7 +631,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
624 | } | 631 | } |
625 | 632 | ||
626 | /* Success */ | 633 | /* Success */ |
627 | icd->gain = ctrl->value; | 634 | mt9t031->gain = ctrl->value; |
628 | break; | 635 | break; |
629 | case V4L2_CID_EXPOSURE: | 636 | case V4L2_CID_EXPOSURE: |
630 | /* mt9t031 has maximum == default */ | 637 | /* mt9t031 has maximum == default */ |
@@ -641,7 +648,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
641 | old, shutter); | 648 | old, shutter); |
642 | if (set_shutter(client, shutter) < 0) | 649 | if (set_shutter(client, shutter) < 0) |
643 | return -EIO; | 650 | return -EIO; |
644 | icd->exposure = ctrl->value; | 651 | mt9t031->exposure = ctrl->value; |
645 | mt9t031->autoexposure = 0; | 652 | mt9t031->autoexposure = 0; |
646 | } | 653 | } |
647 | break; | 654 | break; |
@@ -649,14 +656,14 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
649 | if (ctrl->value) { | 656 | if (ctrl->value) { |
650 | const u16 vblank = MT9T031_VERTICAL_BLANK; | 657 | const u16 vblank = MT9T031_VERTICAL_BLANK; |
651 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 658 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
652 | if (set_shutter(client, mt9t031->rect.height + | 659 | unsigned int total_h = mt9t031->rect.height + |
653 | icd->y_skip_top + vblank) < 0) | 660 | icd->y_skip_top + vblank; |
661 | |||
662 | if (set_shutter(client, total_h) < 0) | ||
654 | return -EIO; | 663 | return -EIO; |
655 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 664 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
656 | icd->exposure = (shutter_max / 2 + | 665 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
657 | (mt9t031->rect.height + | 666 | (qctrl->maximum - qctrl->minimum)) / |
658 | icd->y_skip_top + vblank - 1) * | ||
659 | (qctrl->maximum - qctrl->minimum)) / | ||
660 | shutter_max + qctrl->minimum; | 667 | shutter_max + qctrl->minimum; |
661 | mt9t031->autoexposure = 1; | 668 | mt9t031->autoexposure = 1; |
662 | } else | 669 | } else |
@@ -700,6 +707,10 @@ static int mt9t031_video_probe(struct i2c_client *client) | |||
700 | if (ret < 0) | 707 | if (ret < 0) |
701 | dev_err(&client->dev, "Failed to initialise the camera\n"); | 708 | dev_err(&client->dev, "Failed to initialise the camera\n"); |
702 | 709 | ||
710 | /* mt9t031_idle() has reset the chip to default. */ | ||
711 | mt9t031->exposure = 255; | ||
712 | mt9t031->gain = 64; | ||
713 | |||
703 | return ret; | 714 | return ret; |
704 | } | 715 | } |
705 | 716 | ||