diff options
-rw-r--r-- | drivers/media/video/mt9m001.c | 43 | ||||
-rw-r--r-- | drivers/media/video/mt9m111.c | 29 | ||||
-rw-r--r-- | drivers/media/video/mt9t031.c | 37 | ||||
-rw-r--r-- | drivers/media/video/mt9v022.c | 46 | ||||
-rw-r--r-- | drivers/media/video/mx1_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/video/ov772x.c | 6 | ||||
-rw-r--r-- | drivers/media/video/pxa_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/video/soc_camera.c | 33 | ||||
-rw-r--r-- | drivers/media/video/soc_camera_platform.c | 3 | ||||
-rw-r--r-- | drivers/media/video/tw9910.c | 3 | ||||
-rw-r--r-- | include/media/soc_camera.h | 17 |
11 files changed, 141 insertions, 82 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 4b394798a293..45388d2ce2fd 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -80,6 +80,8 @@ struct mt9m001 { | |||
80 | struct v4l2_rect rect; /* Sensor window */ | 80 | struct v4l2_rect rect; /* Sensor window */ |
81 | __u32 fourcc; | 81 | __u32 fourcc; |
82 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ | 82 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ |
83 | unsigned int gain; | ||
84 | unsigned int exposure; | ||
83 | unsigned char autoexposure; | 85 | unsigned char autoexposure; |
84 | }; | 86 | }; |
85 | 87 | ||
@@ -129,8 +131,8 @@ static int mt9m001_init(struct i2c_client *client) | |||
129 | dev_dbg(&client->dev, "%s\n", __func__); | 131 | dev_dbg(&client->dev, "%s\n", __func__); |
130 | 132 | ||
131 | /* | 133 | /* |
132 | * We don't know, whether platform provides reset, | 134 | * We don't know, whether platform provides reset, issue a soft reset |
133 | * issue a soft reset too | 135 | * too. This returns all registers to their default values. |
134 | */ | 136 | */ |
135 | ret = reg_write(client, MT9M001_RESET, 1); | 137 | ret = reg_write(client, MT9M001_RESET, 1); |
136 | if (!ret) | 138 | if (!ret) |
@@ -200,6 +202,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
200 | struct soc_camera_device *icd = client->dev.platform_data; | 202 | struct soc_camera_device *icd = client->dev.platform_data; |
201 | int ret; | 203 | int ret; |
202 | const u16 hblank = 9, vblank = 25; | 204 | const u16 hblank = 9, vblank = 25; |
205 | unsigned int total_h; | ||
203 | 206 | ||
204 | if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 || | 207 | if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 || |
205 | mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16) | 208 | mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16) |
@@ -219,6 +222,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
219 | soc_camera_limit_side(&rect.top, &rect.height, | 222 | soc_camera_limit_side(&rect.top, &rect.height, |
220 | MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); | 223 | MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); |
221 | 224 | ||
225 | total_h = rect.height + icd->y_skip_top + vblank; | ||
226 | |||
222 | /* Blanking and start values - default... */ | 227 | /* Blanking and start values - default... */ |
223 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); | 228 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); |
224 | if (!ret) | 229 | if (!ret) |
@@ -236,15 +241,13 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
236 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, | 241 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, |
237 | rect.height + icd->y_skip_top - 1); | 242 | rect.height + icd->y_skip_top - 1); |
238 | if (!ret && mt9m001->autoexposure) { | 243 | if (!ret && mt9m001->autoexposure) { |
239 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, | 244 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); |
240 | rect.height + icd->y_skip_top + vblank); | ||
241 | if (!ret) { | 245 | if (!ret) { |
242 | const struct v4l2_queryctrl *qctrl = | 246 | const struct v4l2_queryctrl *qctrl = |
243 | soc_camera_find_qctrl(icd->ops, | 247 | soc_camera_find_qctrl(icd->ops, |
244 | V4L2_CID_EXPOSURE); | 248 | V4L2_CID_EXPOSURE); |
245 | icd->exposure = (524 + (rect.height + icd->y_skip_top + | 249 | mt9m001->exposure = (524 + (total_h - 1) * |
246 | vblank - 1) * | 250 | (qctrl->maximum - qctrl->minimum)) / |
247 | (qctrl->maximum - qctrl->minimum)) / | ||
248 | 1048 + qctrl->minimum; | 251 | 1048 + qctrl->minimum; |
249 | } | 252 | } |
250 | } | 253 | } |
@@ -457,6 +460,12 @@ static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
457 | case V4L2_CID_EXPOSURE_AUTO: | 460 | case V4L2_CID_EXPOSURE_AUTO: |
458 | ctrl->value = mt9m001->autoexposure; | 461 | ctrl->value = mt9m001->autoexposure; |
459 | break; | 462 | break; |
463 | case V4L2_CID_GAIN: | ||
464 | ctrl->value = mt9m001->gain; | ||
465 | break; | ||
466 | case V4L2_CID_EXPOSURE: | ||
467 | ctrl->value = mt9m001->exposure; | ||
468 | break; | ||
460 | } | 469 | } |
461 | return 0; | 470 | return 0; |
462 | } | 471 | } |
@@ -518,7 +527,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
518 | } | 527 | } |
519 | 528 | ||
520 | /* Success */ | 529 | /* Success */ |
521 | icd->gain = ctrl->value; | 530 | mt9m001->gain = ctrl->value; |
522 | break; | 531 | break; |
523 | case V4L2_CID_EXPOSURE: | 532 | case V4L2_CID_EXPOSURE: |
524 | /* mt9m001 has maximum == default */ | 533 | /* mt9m001 has maximum == default */ |
@@ -535,21 +544,21 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
535 | shutter); | 544 | shutter); |
536 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) | 545 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) |
537 | return -EIO; | 546 | return -EIO; |
538 | icd->exposure = ctrl->value; | 547 | mt9m001->exposure = ctrl->value; |
539 | mt9m001->autoexposure = 0; | 548 | mt9m001->autoexposure = 0; |
540 | } | 549 | } |
541 | break; | 550 | break; |
542 | case V4L2_CID_EXPOSURE_AUTO: | 551 | case V4L2_CID_EXPOSURE_AUTO: |
543 | if (ctrl->value) { | 552 | if (ctrl->value) { |
544 | const u16 vblank = 25; | 553 | const u16 vblank = 25; |
554 | unsigned int total_h = mt9m001->rect.height + | ||
555 | icd->y_skip_top + vblank; | ||
545 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, | 556 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, |
546 | mt9m001->rect.height + | 557 | total_h) < 0) |
547 | icd->y_skip_top + vblank) < 0) | ||
548 | return -EIO; | 558 | return -EIO; |
549 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 559 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
550 | icd->exposure = (524 + (mt9m001->rect.height + | 560 | mt9m001->exposure = (524 + (total_h - 1) * |
551 | icd->y_skip_top + vblank - 1) * | 561 | (qctrl->maximum - qctrl->minimum)) / |
552 | (qctrl->maximum - qctrl->minimum)) / | ||
553 | 1048 + qctrl->minimum; | 562 | 1048 + qctrl->minimum; |
554 | mt9m001->autoexposure = 1; | 563 | mt9m001->autoexposure = 1; |
555 | } else | 564 | } else |
@@ -629,6 +638,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, | |||
629 | if (ret < 0) | 638 | if (ret < 0) |
630 | dev_err(&client->dev, "Failed to initialise the camera\n"); | 639 | dev_err(&client->dev, "Failed to initialise the camera\n"); |
631 | 640 | ||
641 | /* mt9m001_init() has reset the chip, returning registers to defaults */ | ||
642 | mt9m001->gain = 64; | ||
643 | mt9m001->exposure = 255; | ||
644 | |||
632 | return ret; | 645 | return ret; |
633 | } | 646 | } |
634 | 647 | ||
@@ -701,7 +714,7 @@ static int mt9m001_probe(struct i2c_client *client, | |||
701 | 714 | ||
702 | /* Second stage probe - when a capture adapter is there */ | 715 | /* Second stage probe - when a capture adapter is there */ |
703 | icd->ops = &mt9m001_ops; | 716 | icd->ops = &mt9m001_ops; |
704 | icd->y_skip_top = 1; | 717 | icd->y_skip_top = 0; |
705 | 718 | ||
706 | mt9m001->rect.left = MT9M001_COLUMN_SKIP; | 719 | mt9m001->rect.left = MT9M001_COLUMN_SKIP; |
707 | mt9m001->rect.top = MT9M001_ROW_SKIP; | 720 | mt9m001->rect.top = MT9M001_ROW_SKIP; |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 186902f9be2e..90da699601ea 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -153,6 +153,7 @@ struct mt9m111 { | |||
153 | enum mt9m111_context context; | 153 | enum mt9m111_context context; |
154 | struct v4l2_rect rect; | 154 | struct v4l2_rect rect; |
155 | u32 pixfmt; | 155 | u32 pixfmt; |
156 | unsigned int gain; | ||
156 | unsigned char autoexposure; | 157 | unsigned char autoexposure; |
157 | unsigned char datawidth; | 158 | unsigned char datawidth; |
158 | unsigned int powered:1; | 159 | unsigned int powered:1; |
@@ -513,7 +514,8 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt) | |||
513 | ret = mt9m111_setfmt_yuv(client); | 514 | ret = mt9m111_setfmt_yuv(client); |
514 | break; | 515 | break; |
515 | default: | 516 | default: |
516 | dev_err(&client->dev, "Pixel format not handled : %x\n", pixfmt); | 517 | dev_err(&client->dev, "Pixel format not handled : %x\n", |
518 | pixfmt); | ||
517 | ret = -EINVAL; | 519 | ret = -EINVAL; |
518 | } | 520 | } |
519 | 521 | ||
@@ -536,9 +538,9 @@ static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
536 | }; | 538 | }; |
537 | int ret; | 539 | int ret; |
538 | 540 | ||
539 | dev_dbg(&client->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", | 541 | dev_dbg(&client->dev, |
540 | __func__, pix->pixelformat, rect.left, rect.top, rect.width, | 542 | "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__, |
541 | rect.height); | 543 | pix->pixelformat, rect.left, rect.top, rect.width, rect.height); |
542 | 544 | ||
543 | ret = mt9m111_make_rect(client, &rect); | 545 | ret = mt9m111_make_rect(client, &rect); |
544 | if (!ret) | 546 | if (!ret) |
@@ -672,8 +674,10 @@ static const struct v4l2_queryctrl mt9m111_controls[] = { | |||
672 | }; | 674 | }; |
673 | 675 | ||
674 | static int mt9m111_resume(struct soc_camera_device *icd); | 676 | static int mt9m111_resume(struct soc_camera_device *icd); |
677 | static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state); | ||
675 | 678 | ||
676 | static struct soc_camera_ops mt9m111_ops = { | 679 | static struct soc_camera_ops mt9m111_ops = { |
680 | .suspend = mt9m111_suspend, | ||
677 | .resume = mt9m111_resume, | 681 | .resume = mt9m111_resume, |
678 | .query_bus_param = mt9m111_query_bus_param, | 682 | .query_bus_param = mt9m111_query_bus_param, |
679 | .set_bus_param = mt9m111_set_bus_param, | 683 | .set_bus_param = mt9m111_set_bus_param, |
@@ -714,13 +718,13 @@ static int mt9m111_get_global_gain(struct i2c_client *client) | |||
714 | 718 | ||
715 | static int mt9m111_set_global_gain(struct i2c_client *client, int gain) | 719 | static int mt9m111_set_global_gain(struct i2c_client *client, int gain) |
716 | { | 720 | { |
717 | struct soc_camera_device *icd = client->dev.platform_data; | 721 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
718 | u16 val; | 722 | u16 val; |
719 | 723 | ||
720 | if (gain > 63 * 2 * 2) | 724 | if (gain > 63 * 2 * 2) |
721 | return -EINVAL; | 725 | return -EINVAL; |
722 | 726 | ||
723 | icd->gain = gain; | 727 | mt9m111->gain = gain; |
724 | if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) | 728 | if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) |
725 | val = (1 << 10) | (1 << 9) | (gain / 4); | 729 | val = (1 << 10) | (1 << 9) | (gain / 4); |
726 | else if ((gain >= 64) && (gain < 64 * 2)) | 730 | else if ((gain >= 64) && (gain < 64 * 2)) |
@@ -844,17 +848,26 @@ static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
844 | return ret; | 848 | return ret; |
845 | } | 849 | } |
846 | 850 | ||
851 | static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state) | ||
852 | { | ||
853 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
854 | struct mt9m111 *mt9m111 = to_mt9m111(client); | ||
855 | |||
856 | mt9m111->gain = mt9m111_get_global_gain(client); | ||
857 | |||
858 | return 0; | ||
859 | } | ||
860 | |||
847 | static int mt9m111_restore_state(struct i2c_client *client) | 861 | static int mt9m111_restore_state(struct i2c_client *client) |
848 | { | 862 | { |
849 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 863 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
850 | struct soc_camera_device *icd = client->dev.platform_data; | ||
851 | 864 | ||
852 | mt9m111_set_context(client, mt9m111->context); | 865 | mt9m111_set_context(client, mt9m111->context); |
853 | mt9m111_set_pixfmt(client, mt9m111->pixfmt); | 866 | mt9m111_set_pixfmt(client, mt9m111->pixfmt); |
854 | mt9m111_setup_rect(client, &mt9m111->rect); | 867 | mt9m111_setup_rect(client, &mt9m111->rect); |
855 | mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); | 868 | mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); |
856 | mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); | 869 | mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); |
857 | mt9m111_set_global_gain(client, icd->gain); | 870 | mt9m111_set_global_gain(client, mt9m111->gain); |
858 | mt9m111_set_autoexposure(client, mt9m111->autoexposure); | 871 | mt9m111_set_autoexposure(client, mt9m111->autoexposure); |
859 | mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance); | 872 | mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance); |
860 | return 0; | 873 | return 0; |
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 | ||
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 5c47b55823c8..995607f9d3ba 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); | |||
45 | #define MT9V022_PIXEL_OPERATION_MODE 0x0f | 45 | #define MT9V022_PIXEL_OPERATION_MODE 0x0f |
46 | #define MT9V022_LED_OUT_CONTROL 0x1b | 46 | #define MT9V022_LED_OUT_CONTROL 0x1b |
47 | #define MT9V022_ADC_MODE_CONTROL 0x1c | 47 | #define MT9V022_ADC_MODE_CONTROL 0x1c |
48 | #define MT9V022_ANALOG_GAIN 0x34 | 48 | #define MT9V022_ANALOG_GAIN 0x35 |
49 | #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 | 49 | #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 |
50 | #define MT9V022_PIXCLK_FV_LV 0x74 | 50 | #define MT9V022_PIXCLK_FV_LV 0x74 |
51 | #define MT9V022_DIGITAL_TEST_PATTERN 0x7f | 51 | #define MT9V022_DIGITAL_TEST_PATTERN 0x7f |
@@ -156,6 +156,10 @@ static int mt9v022_init(struct i2c_client *client) | |||
156 | /* AEC, AGC on */ | 156 | /* AEC, AGC on */ |
157 | ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); | 157 | ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); |
158 | if (!ret) | 158 | if (!ret) |
159 | ret = reg_write(client, MT9V022_ANALOG_GAIN, 16); | ||
160 | if (!ret) | ||
161 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480); | ||
162 | if (!ret) | ||
159 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); | 163 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); |
160 | if (!ret) | 164 | if (!ret) |
161 | /* default - auto */ | 165 | /* default - auto */ |
@@ -540,8 +544,12 @@ static struct soc_camera_ops mt9v022_ops = { | |||
540 | static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 544 | static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
541 | { | 545 | { |
542 | struct i2c_client *client = sd->priv; | 546 | struct i2c_client *client = sd->priv; |
547 | const struct v4l2_queryctrl *qctrl; | ||
548 | unsigned long range; | ||
543 | int data; | 549 | int data; |
544 | 550 | ||
551 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | ||
552 | |||
545 | switch (ctrl->id) { | 553 | switch (ctrl->id) { |
546 | case V4L2_CID_VFLIP: | 554 | case V4L2_CID_VFLIP: |
547 | data = reg_read(client, MT9V022_READ_MODE); | 555 | data = reg_read(client, MT9V022_READ_MODE); |
@@ -567,6 +575,24 @@ static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
567 | return -EIO; | 575 | return -EIO; |
568 | ctrl->value = !!(data & 0x2); | 576 | ctrl->value = !!(data & 0x2); |
569 | break; | 577 | break; |
578 | case V4L2_CID_GAIN: | ||
579 | data = reg_read(client, MT9V022_ANALOG_GAIN); | ||
580 | if (data < 0) | ||
581 | return -EIO; | ||
582 | |||
583 | range = qctrl->maximum - qctrl->minimum; | ||
584 | ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum; | ||
585 | |||
586 | break; | ||
587 | case V4L2_CID_EXPOSURE: | ||
588 | data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH); | ||
589 | if (data < 0) | ||
590 | return -EIO; | ||
591 | |||
592 | range = qctrl->maximum - qctrl->minimum; | ||
593 | ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum; | ||
594 | |||
595 | break; | ||
570 | } | 596 | } |
571 | return 0; | 597 | return 0; |
572 | } | 598 | } |
@@ -575,7 +601,6 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
575 | { | 601 | { |
576 | int data; | 602 | int data; |
577 | struct i2c_client *client = sd->priv; | 603 | struct i2c_client *client = sd->priv; |
578 | struct soc_camera_device *icd = client->dev.platform_data; | ||
579 | const struct v4l2_queryctrl *qctrl; | 604 | const struct v4l2_queryctrl *qctrl; |
580 | 605 | ||
581 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); | 606 | qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); |
@@ -605,12 +630,9 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
605 | return -EINVAL; | 630 | return -EINVAL; |
606 | else { | 631 | else { |
607 | unsigned long range = qctrl->maximum - qctrl->minimum; | 632 | unsigned long range = qctrl->maximum - qctrl->minimum; |
608 | /* Datasheet says 16 to 64. autogain only works properly | 633 | /* Valid values 16 to 64, 32 to 64 must be even. */ |
609 | * after setting gain to maximum 14. Larger values | ||
610 | * produce "white fly" noise effect. On the whole, | ||
611 | * manually setting analog gain does no good. */ | ||
612 | unsigned long gain = ((ctrl->value - qctrl->minimum) * | 634 | unsigned long gain = ((ctrl->value - qctrl->minimum) * |
613 | 10 + range / 2) / range + 4; | 635 | 48 + range / 2) / range + 16; |
614 | if (gain >= 32) | 636 | if (gain >= 32) |
615 | gain &= ~1; | 637 | gain &= ~1; |
616 | /* The user wants to set gain manually, hope, she | 638 | /* The user wants to set gain manually, hope, she |
@@ -619,11 +641,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
619 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | 641 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) |
620 | return -EIO; | 642 | return -EIO; |
621 | 643 | ||
622 | dev_info(&client->dev, "Setting gain from %d to %lu\n", | 644 | dev_dbg(&client->dev, "Setting gain from %d to %lu\n", |
623 | reg_read(client, MT9V022_ANALOG_GAIN), gain); | 645 | reg_read(client, MT9V022_ANALOG_GAIN), gain); |
624 | if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) | 646 | if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) |
625 | return -EIO; | 647 | return -EIO; |
626 | icd->gain = ctrl->value; | ||
627 | } | 648 | } |
628 | break; | 649 | break; |
629 | case V4L2_CID_EXPOSURE: | 650 | case V4L2_CID_EXPOSURE: |
@@ -646,7 +667,6 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
646 | if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, | 667 | if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
647 | shutter) < 0) | 668 | shutter) < 0) |
648 | return -EIO; | 669 | return -EIO; |
649 | icd->exposure = ctrl->value; | ||
650 | } | 670 | } |
651 | break; | 671 | break; |
652 | case V4L2_CID_AUTOGAIN: | 672 | case V4L2_CID_AUTOGAIN: |
@@ -827,6 +847,10 @@ static int mt9v022_probe(struct i2c_client *client, | |||
827 | mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; | 847 | mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; |
828 | 848 | ||
829 | icd->ops = &mt9v022_ops; | 849 | icd->ops = &mt9v022_ops; |
850 | /* | ||
851 | * MT9V022 _really_ corrupts the first read out line. | ||
852 | * TODO: verify on i.MX31 | ||
853 | */ | ||
830 | icd->y_skip_top = 1; | 854 | icd->y_skip_top = 1; |
831 | 855 | ||
832 | mt9v022->rect.left = MT9V022_COLUMN_SKIP; | 856 | mt9v022->rect.left = MT9V022_COLUMN_SKIP; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 3875483ab9d5..5f37952c75cf 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -548,7 +548,8 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
548 | 548 | ||
549 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 549 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
550 | if (!xlate) { | 550 | if (!xlate) { |
551 | dev_warn(icd->dev.parent, "Format %x not found\n", pix->pixelformat); | 551 | dev_warn(icd->dev.parent, "Format %x not found\n", |
552 | pix->pixelformat); | ||
552 | return -EINVAL; | 553 | return -EINVAL; |
553 | } | 554 | } |
554 | 555 | ||
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 776a91dcfbe6..eccb40ab7fec 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -404,7 +404,8 @@ struct ov772x_priv { | |||
404 | int model; | 404 | int model; |
405 | unsigned short flag_vflip:1; | 405 | unsigned short flag_vflip:1; |
406 | unsigned short flag_hflip:1; | 406 | unsigned short flag_hflip:1; |
407 | unsigned short band_filter; /* 256 - BDBASE, 0 if (!COM8[5]) */ | 407 | /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ |
408 | unsigned short band_filter; | ||
408 | }; | 409 | }; |
409 | 410 | ||
410 | #define ENDMARKER { 0xff, 0xff } | 411 | #define ENDMARKER { 0xff, 0xff } |
@@ -587,7 +588,8 @@ static const struct v4l2_queryctrl ov772x_controls[] = { | |||
587 | 588 | ||
588 | static struct ov772x_priv *to_ov772x(const struct i2c_client *client) | 589 | static struct ov772x_priv *to_ov772x(const struct i2c_client *client) |
589 | { | 590 | { |
590 | return container_of(i2c_get_clientdata(client), struct ov772x_priv, subdev); | 591 | return container_of(i2c_get_clientdata(client), struct ov772x_priv, |
592 | subdev); | ||
591 | } | 593 | } |
592 | 594 | ||
593 | static int ov772x_write_array(struct i2c_client *client, | 595 | static int ov772x_write_array(struct i2c_client *client, |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index a19bb76e175d..6952e9602d5d 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -274,7 +274,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
274 | 274 | ||
275 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { | 275 | for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { |
276 | if (buf->dmas[i].sg_cpu) | 276 | if (buf->dmas[i].sg_cpu) |
277 | dma_free_coherent(ici->v4l2_dev.dev, buf->dmas[i].sg_size, | 277 | dma_free_coherent(ici->v4l2_dev.dev, |
278 | buf->dmas[i].sg_size, | ||
278 | buf->dmas[i].sg_cpu, | 279 | buf->dmas[i].sg_cpu, |
279 | buf->dmas[i].sg_dma); | 280 | buf->dmas[i].sg_dma); |
280 | buf->dmas[i].sg_cpu = NULL; | 281 | buf->dmas[i].sg_cpu = NULL; |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 27921162514c..e8248ba0c03c 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -327,7 +327,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
327 | static int soc_camera_open(struct file *file) | 327 | static int soc_camera_open(struct file *file) |
328 | { | 328 | { |
329 | struct video_device *vdev = video_devdata(file); | 329 | struct video_device *vdev = video_devdata(file); |
330 | struct soc_camera_device *icd = container_of(vdev->parent, struct soc_camera_device, dev); | 330 | struct soc_camera_device *icd = container_of(vdev->parent, |
331 | struct soc_camera_device, | ||
332 | dev); | ||
331 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 333 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
332 | struct soc_camera_host *ici; | 334 | struct soc_camera_host *ici; |
333 | struct soc_camera_file *icf; | 335 | struct soc_camera_file *icf; |
@@ -349,7 +351,10 @@ static int soc_camera_open(struct file *file) | |||
349 | goto emgi; | 351 | goto emgi; |
350 | } | 352 | } |
351 | 353 | ||
352 | /* Protect against icd->ops->remove() until we module_get() both drivers. */ | 354 | /* |
355 | * Protect against icd->ops->remove() until we module_get() both | ||
356 | * drivers. | ||
357 | */ | ||
353 | mutex_lock(&icd->video_lock); | 358 | mutex_lock(&icd->video_lock); |
354 | 359 | ||
355 | icf->icd = icd; | 360 | icf->icd = icd; |
@@ -670,19 +675,6 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, | |||
670 | 675 | ||
671 | WARN_ON(priv != file->private_data); | 676 | WARN_ON(priv != file->private_data); |
672 | 677 | ||
673 | switch (ctrl->id) { | ||
674 | case V4L2_CID_GAIN: | ||
675 | if (icd->gain == (unsigned short)~0) | ||
676 | return -EINVAL; | ||
677 | ctrl->value = icd->gain; | ||
678 | return 0; | ||
679 | case V4L2_CID_EXPOSURE: | ||
680 | if (icd->exposure == (unsigned short)~0) | ||
681 | return -EINVAL; | ||
682 | ctrl->value = icd->exposure; | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | if (ici->ops->get_ctrl) { | 678 | if (ici->ops->get_ctrl) { |
687 | ret = ici->ops->get_ctrl(icd, ctrl); | 679 | ret = ici->ops->get_ctrl(icd, ctrl); |
688 | if (ret != -ENOIOCTLCMD) | 680 | if (ret != -ENOIOCTLCMD) |
@@ -944,7 +936,10 @@ static int soc_camera_probe(struct device *dev) | |||
944 | if (ret < 0) | 936 | if (ret < 0) |
945 | goto eadddev; | 937 | goto eadddev; |
946 | 938 | ||
947 | /* FIXME: this is racy, have to use driver-binding notification */ | 939 | /* |
940 | * FIXME: this is racy, have to use driver-binding notification, | ||
941 | * when it is available | ||
942 | */ | ||
948 | control = to_soc_camera_control(icd); | 943 | control = to_soc_camera_control(icd); |
949 | if (!control || !control->driver || !dev_get_drvdata(control) || | 944 | if (!control || !control->driver || !dev_get_drvdata(control) || |
950 | !try_module_get(control->driver->owner)) { | 945 | !try_module_get(control->driver->owner)) { |
@@ -1279,7 +1274,6 @@ static int video_dev_create(struct soc_camera_device *icd) | |||
1279 | */ | 1274 | */ |
1280 | static int soc_camera_video_start(struct soc_camera_device *icd) | 1275 | static int soc_camera_video_start(struct soc_camera_device *icd) |
1281 | { | 1276 | { |
1282 | const struct v4l2_queryctrl *qctrl; | ||
1283 | int ret; | 1277 | int ret; |
1284 | 1278 | ||
1285 | if (!icd->dev.parent) | 1279 | if (!icd->dev.parent) |
@@ -1297,11 +1291,6 @@ static int soc_camera_video_start(struct soc_camera_device *icd) | |||
1297 | return ret; | 1291 | return ret; |
1298 | } | 1292 | } |
1299 | 1293 | ||
1300 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); | ||
1301 | icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0; | ||
1302 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | ||
1303 | icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0; | ||
1304 | |||
1305 | return 0; | 1294 | return 0; |
1306 | } | 1295 | } |
1307 | 1296 | ||
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index 3825c358172f..1b6dd02a801f 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c | |||
@@ -33,7 +33,8 @@ static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev) | |||
33 | 33 | ||
34 | static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd) | 34 | static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd) |
35 | { | 35 | { |
36 | struct platform_device *pdev = to_platform_device(to_soc_camera_control(icd)); | 36 | struct platform_device *pdev = |
37 | to_platform_device(to_soc_camera_control(icd)); | ||
37 | return pdev->dev.platform_data; | 38 | return pdev->dev.platform_data; |
38 | } | 39 | } |
39 | 40 | ||
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index fbf4130dfc5d..269ab044072a 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c | |||
@@ -357,7 +357,8 @@ static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = { | |||
357 | */ | 357 | */ |
358 | static struct tw9910_priv *to_tw9910(const struct i2c_client *client) | 358 | static struct tw9910_priv *to_tw9910(const struct i2c_client *client) |
359 | { | 359 | { |
360 | return container_of(i2c_get_clientdata(client), struct tw9910_priv, subdev); | 360 | return container_of(i2c_get_clientdata(client), struct tw9910_priv, |
361 | subdev); | ||
361 | } | 362 | } |
362 | 363 | ||
363 | static int tw9910_set_scale(struct i2c_client *client, | 364 | static int tw9910_set_scale(struct i2c_client *client, |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index f95cc4a2d9af..3d74e60032dd 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -27,8 +27,6 @@ struct soc_camera_device { | |||
27 | unsigned short width_min; | 27 | unsigned short width_min; |
28 | unsigned short height_min; | 28 | unsigned short height_min; |
29 | unsigned short y_skip_top; /* Lines to skip at the top */ | 29 | unsigned short y_skip_top; /* Lines to skip at the top */ |
30 | unsigned short gain; | ||
31 | unsigned short exposure; | ||
32 | unsigned char iface; /* Host number */ | 30 | unsigned char iface; /* Host number */ |
33 | unsigned char devnum; /* Device number per host */ | 31 | unsigned char devnum; /* Device number per host */ |
34 | unsigned char buswidth; /* See comment in .c */ | 32 | unsigned char buswidth; /* See comment in .c */ |
@@ -128,29 +126,34 @@ struct soc_camera_link { | |||
128 | void (*free_bus)(struct soc_camera_link *); | 126 | void (*free_bus)(struct soc_camera_link *); |
129 | }; | 127 | }; |
130 | 128 | ||
131 | static inline struct soc_camera_device *to_soc_camera_dev(const struct device *dev) | 129 | static inline struct soc_camera_device *to_soc_camera_dev( |
130 | const struct device *dev) | ||
132 | { | 131 | { |
133 | return container_of(dev, struct soc_camera_device, dev); | 132 | return container_of(dev, struct soc_camera_device, dev); |
134 | } | 133 | } |
135 | 134 | ||
136 | static inline struct soc_camera_host *to_soc_camera_host(const struct device *dev) | 135 | static inline struct soc_camera_host *to_soc_camera_host( |
136 | const struct device *dev) | ||
137 | { | 137 | { |
138 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); | 138 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); |
139 | 139 | ||
140 | return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev); | 140 | return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev); |
141 | } | 141 | } |
142 | 142 | ||
143 | static inline struct soc_camera_link *to_soc_camera_link(const struct soc_camera_device *icd) | 143 | static inline struct soc_camera_link *to_soc_camera_link( |
144 | const struct soc_camera_device *icd) | ||
144 | { | 145 | { |
145 | return icd->dev.platform_data; | 146 | return icd->dev.platform_data; |
146 | } | 147 | } |
147 | 148 | ||
148 | static inline struct device *to_soc_camera_control(const struct soc_camera_device *icd) | 149 | static inline struct device *to_soc_camera_control( |
150 | const struct soc_camera_device *icd) | ||
149 | { | 151 | { |
150 | return dev_get_drvdata(&icd->dev); | 152 | return dev_get_drvdata(&icd->dev); |
151 | } | 153 | } |
152 | 154 | ||
153 | static inline struct v4l2_subdev *soc_camera_to_subdev(const struct soc_camera_device *icd) | 155 | static inline struct v4l2_subdev *soc_camera_to_subdev( |
156 | const struct soc_camera_device *icd) | ||
154 | { | 157 | { |
155 | struct device *control = to_soc_camera_control(icd); | 158 | struct device *control = to_soc_camera_control(icd); |
156 | return dev_get_drvdata(control); | 159 | return dev_get_drvdata(control); |