aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mt9m001.c43
-rw-r--r--drivers/media/video/mt9m111.c29
-rw-r--r--drivers/media/video/mt9t031.c37
-rw-r--r--drivers/media/video/mt9v022.c46
-rw-r--r--drivers/media/video/mx1_camera.c3
-rw-r--r--drivers/media/video/ov772x.c6
-rw-r--r--drivers/media/video/pxa_camera.c3
-rw-r--r--drivers/media/video/soc_camera.c33
-rw-r--r--drivers/media/video/soc_camera_platform.c3
-rw-r--r--drivers/media/video/tw9910.c3
-rw-r--r--include/media/soc_camera.h17
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
674static int mt9m111_resume(struct soc_camera_device *icd); 676static int mt9m111_resume(struct soc_camera_device *icd);
677static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);
675 678
676static struct soc_camera_ops mt9m111_ops = { 679static 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
715static int mt9m111_set_global_gain(struct i2c_client *client, int gain) 719static 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
851static 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
847static int mt9m111_restore_state(struct i2c_client *client) 861static 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 = {
540static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 544static 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
588static struct ov772x_priv *to_ov772x(const struct i2c_client *client) 589static 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
593static int ov772x_write_array(struct i2c_client *client, 595static 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,
327static int soc_camera_open(struct file *file) 327static 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 */
1280static int soc_camera_video_start(struct soc_camera_device *icd) 1275static 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
34static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd) 34static 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 */
358static struct tw9910_priv *to_tw9910(const struct i2c_client *client) 358static 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
363static int tw9910_set_scale(struct i2c_client *client, 364static 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
131static inline struct soc_camera_device *to_soc_camera_dev(const struct device *dev) 129static 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
136static inline struct soc_camera_host *to_soc_camera_host(const struct device *dev) 135static 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
143static inline struct soc_camera_link *to_soc_camera_link(const struct soc_camera_device *icd) 143static 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
148static inline struct device *to_soc_camera_control(const struct soc_camera_device *icd) 149static 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
153static inline struct v4l2_subdev *soc_camera_to_subdev(const struct soc_camera_device *icd) 155static 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);