aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 13057b966ee9..a5210e4d67af 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -71,6 +71,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
71#define MT9V022_COLUMN_SKIP 1 71#define MT9V022_COLUMN_SKIP 1
72#define MT9V022_ROW_SKIP 4 72#define MT9V022_ROW_SKIP 4
73 73
74#define MT9V022_HORIZONTAL_BLANKING_MIN 43
75#define MT9V022_HORIZONTAL_BLANKING_MAX 1023
76#define MT9V022_HORIZONTAL_BLANKING_DEF 94
77#define MT9V022_VERTICAL_BLANKING_MIN 2
78#define MT9V022_VERTICAL_BLANKING_MAX 3000
79#define MT9V022_VERTICAL_BLANKING_DEF 45
80
74#define is_mt9v024(id) (id == 0x1324) 81#define is_mt9v024(id) (id == 0x1324)
75 82
76/* MT9V022 has only one fixed colorspace per pixelcode */ 83/* MT9V022 has only one fixed colorspace per pixelcode */
@@ -136,6 +143,8 @@ struct mt9v022 {
136 struct v4l2_ctrl *autogain; 143 struct v4l2_ctrl *autogain;
137 struct v4l2_ctrl *gain; 144 struct v4l2_ctrl *gain;
138 }; 145 };
146 struct v4l2_ctrl *hblank;
147 struct v4l2_ctrl *vblank;
139 struct v4l2_rect rect; /* Sensor window */ 148 struct v4l2_rect rect; /* Sensor window */
140 const struct mt9v022_datafmt *fmt; 149 const struct mt9v022_datafmt *fmt;
141 const struct mt9v022_datafmt *fmts; 150 const struct mt9v022_datafmt *fmts;
@@ -277,11 +286,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
277 * Default 94, Phytec driver says: 286 * Default 94, Phytec driver says:
278 * "width + horizontal blank >= 660" 287 * "width + horizontal blank >= 660"
279 */ 288 */
280 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, 289 ret = v4l2_ctrl_s_ctrl(mt9v022->hblank,
281 rect.width > 660 - 43 ? 43 : 290 rect.width > 660 - 43 ? 43 : 660 - rect.width);
282 660 - rect.width);
283 if (!ret) 291 if (!ret)
284 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); 292 ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45);
285 if (!ret) 293 if (!ret)
286 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); 294 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
287 if (!ret) 295 if (!ret)
@@ -504,6 +512,18 @@ static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
504 range = exp->maximum - exp->minimum; 512 range = exp->maximum - exp->minimum;
505 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum; 513 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
506 return 0; 514 return 0;
515 case V4L2_CID_HBLANK:
516 data = reg_read(client, MT9V022_HORIZONTAL_BLANKING);
517 if (data < 0)
518 return -EIO;
519 ctrl->val = data;
520 return 0;
521 case V4L2_CID_VBLANK:
522 data = reg_read(client, MT9V022_VERTICAL_BLANKING);
523 if (data < 0)
524 return -EIO;
525 ctrl->val = data;
526 return 0;
507 } 527 }
508 return -EINVAL; 528 return -EINVAL;
509} 529}
@@ -585,6 +605,16 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
585 return -EIO; 605 return -EIO;
586 } 606 }
587 return 0; 607 return 0;
608 case V4L2_CID_HBLANK:
609 if (reg_write(client, MT9V022_HORIZONTAL_BLANKING,
610 ctrl->val) < 0)
611 return -EIO;
612 return 0;
613 case V4L2_CID_VBLANK:
614 if (reg_write(client, MT9V022_VERTICAL_BLANKING,
615 ctrl->val) < 0)
616 return -EIO;
617 return 0;
588 } 618 }
589 return -EINVAL; 619 return -EINVAL;
590} 620}
@@ -852,10 +882,21 @@ static int mt9v022_probe(struct i2c_client *client,
852 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, 882 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
853 V4L2_CID_EXPOSURE, 1, 255, 1, 255); 883 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
854 884
885 mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
886 V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN,
887 MT9V022_HORIZONTAL_BLANKING_MAX, 1,
888 MT9V022_HORIZONTAL_BLANKING_DEF);
889
890 mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
891 V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN,
892 MT9V022_VERTICAL_BLANKING_MAX, 1,
893 MT9V022_VERTICAL_BLANKING_DEF);
894
855 mt9v022->subdev.ctrl_handler = &mt9v022->hdl; 895 mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
856 if (mt9v022->hdl.error) { 896 if (mt9v022->hdl.error) {
857 int err = mt9v022->hdl.error; 897 int err = mt9v022->hdl.error;
858 898
899 dev_err(&client->dev, "control initialisation err %d\n", err);
859 kfree(mt9v022); 900 kfree(mt9v022);
860 return err; 901 return err;
861 } 902 }