|
@@ -52,9 +52,11 @@
|
|
|
#define MT9V032_WINDOW_WIDTH_MAX 752
|
|
|
#define MT9V032_HORIZONTAL_BLANKING 0x05
|
|
|
#define MT9V032_HORIZONTAL_BLANKING_MIN 43
|
|
|
+#define MT9V032_HORIZONTAL_BLANKING_DEF 94
|
|
|
#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
|
|
|
#define MT9V032_VERTICAL_BLANKING 0x06
|
|
|
#define MT9V032_VERTICAL_BLANKING_MIN 4
|
|
|
+#define MT9V032_VERTICAL_BLANKING_DEF 45
|
|
|
#define MT9V032_VERTICAL_BLANKING_MAX 3000
|
|
|
#define MT9V032_CHIP_CONTROL 0x07
|
|
|
#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
|
|
@@ -138,6 +140,7 @@ struct mt9v032 {
|
|
|
u32 sysclk;
|
|
|
u16 chip_control;
|
|
|
u16 aec_agc;
|
|
|
+ u16 hblank;
|
|
|
};
|
|
|
|
|
|
static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
|
|
@@ -195,6 +198,16 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+mt9v032_update_hblank(struct mt9v032 *mt9v032)
|
|
|
+{
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
|
|
|
+ struct v4l2_rect *crop = &mt9v032->crop;
|
|
|
+
|
|
|
+ return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
|
|
|
+ max_t(s32, mt9v032->hblank, 660 - crop->width));
|
|
|
+}
|
|
|
+
|
|
|
#define EXT_CLK 25000000
|
|
|
|
|
|
static int mt9v032_power_on(struct mt9v032 *mt9v032)
|
|
@@ -329,8 +342,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
|
- ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
|
|
|
- max(43, 660 - crop->width));
|
|
|
+ ret = mt9v032_update_hblank(mt9v032);
|
|
|
if (ret < 0)
|
|
|
return ret;
|
|
|
|
|
@@ -514,6 +526,14 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
|
|
|
ctrl->val);
|
|
|
|
|
|
+ case V4L2_CID_HBLANK:
|
|
|
+ mt9v032->hblank = ctrl->val;
|
|
|
+ return mt9v032_update_hblank(mt9v032);
|
|
|
+
|
|
|
+ case V4L2_CID_VBLANK:
|
|
|
+ return mt9v032_write(client, MT9V032_VERTICAL_BLANKING,
|
|
|
+ ctrl->val);
|
|
|
+
|
|
|
case V4L2_CID_PIXEL_RATE:
|
|
|
case V4L2_CID_LINK_FREQ:
|
|
|
if (mt9v032->link_freq == NULL)
|
|
@@ -721,7 +741,7 @@ static int mt9v032_probe(struct i2c_client *client,
|
|
|
mutex_init(&mt9v032->power_lock);
|
|
|
mt9v032->pdata = pdata;
|
|
|
|
|
|
- v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 6);
|
|
|
+ v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 8);
|
|
|
|
|
|
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
|
|
|
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
|
|
@@ -735,6 +755,14 @@ static int mt9v032_probe(struct i2c_client *client,
|
|
|
V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
|
|
|
MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
|
|
|
MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
|
|
|
+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
|
|
|
+ V4L2_CID_HBLANK, MT9V032_HORIZONTAL_BLANKING_MIN,
|
|
|
+ MT9V032_HORIZONTAL_BLANKING_MAX, 1,
|
|
|
+ MT9V032_HORIZONTAL_BLANKING_DEF);
|
|
|
+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
|
|
|
+ V4L2_CID_VBLANK, MT9V032_VERTICAL_BLANKING_MIN,
|
|
|
+ MT9V032_VERTICAL_BLANKING_MAX, 1,
|
|
|
+ MT9V032_VERTICAL_BLANKING_DEF);
|
|
|
|
|
|
mt9v032->pixel_rate =
|
|
|
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
|
|
@@ -777,6 +805,7 @@ static int mt9v032_probe(struct i2c_client *client,
|
|
|
mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
|
|
|
|
|
|
mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
|
|
|
+ mt9v032->hblank = MT9V032_HORIZONTAL_BLANKING_DEF;
|
|
|
mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
|
|
|
|
|
|
v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
|