Skip to content

Commit af49ead

Browse files
Cai YiWeiZhengShunQian
authored andcommitted
media: soc_camera: ov9750 fix flip and exposure bug
Change-Id: I7f90247dd3f2be32c26b68a4f074b20d09e06cb2 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
1 parent 3ec57b8 commit af49ead

1 file changed

Lines changed: 35 additions & 23 deletions

File tree

drivers/media/i2c/soc_camera/rockchip/ov9750_v4l2-i2c-subdev.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,20 @@ static struct ov_camera_module_reg ov9750_init_tab_1280_960_30fps[] = {
135135
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3601, 0x60},
136136
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3602, 0x22},
137137
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3610, 0xe8},
138-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3611, 0x5c},
139-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3612, 0x18},
140-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3613, 0x3a},
138+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3611, 0x56},
139+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3612, 0x48},
140+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3613, 0x5a},
141141
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3614, 0x91},
142142
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3615, 0x79},
143143
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3617, 0x57},
144144
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3621, 0x90},
145145
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3622, 0x00},
146146
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3623, 0x00},
147+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3625, 0x07},
147148
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3633, 0x10},
148149
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3634, 0x10},
149150
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3635, 0x14},
150-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3636, 0x14},
151+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3636, 0x13},
151152
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3650, 0x00},
152153
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3652, 0xff},
153154
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3654, 0x00},
@@ -188,7 +189,7 @@ static struct ov_camera_module_reg ov9750_init_tab_1280_960_30fps[] = {
188189
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37b5, 0x36},
189190
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37c2, 0x04},
190191
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37c5, 0x00},
191-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37c7, 0x31},
192+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37c7, 0x38},
192193
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37c8, 0x00},
193194
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x37d1, 0x13},
194195
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3800, 0x00},
@@ -297,9 +298,9 @@ static struct ov_camera_module_reg ov9750_init_tab_1280_960_30fps[] = {
297298
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x300f, 0x00},
298299
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3733, 0x10},
299300
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3610, 0xe8},
300-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3611, 0x5c},
301+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3611, 0x56},
301302
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3635, 0x14},
302-
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3636, 0x14},
303+
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3636, 0x13},
303304
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3620, 0x84},
304305
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x3614, 0x96},
305306
{OV_CAMERA_MODULE_REG_TYPE_DATA, 0x481f, 0x30},
@@ -333,7 +334,9 @@ static struct ov_camera_module_config ov9750_configs[] = {
333334
.reg_table_num_entries =
334335
ARRAY_SIZE(ov9750_init_tab_1280_960_30fps),
335336
.v_blanking_time_us = 3078,
336-
PLTFRM_CAM_ITF_MIPI_CFG(0, 2, 400, OV9750_EXT_CLK)
337+
.max_exp_gain_h = 16,
338+
.max_exp_gain_l = 0,
339+
PLTFRM_CAM_ITF_MIPI_CFG(0, 2, 402, OV9750_EXT_CLK)
337340
}
338341
};
339342

@@ -378,7 +381,7 @@ static int ov9750_set_flip(struct ov_camera_module *cam_mod,
378381
}
379382

380383
if (mode == OV_FLIP_BIT_MASK) {
381-
match_reg[0] = 0xc6;
384+
match_reg[0] = 0x86;
382385
match_reg[1] = 0x40;
383386
match_reg[2] = 0x20;
384387
} else if (mode == OV_MIRROR_BIT_MASK) {
@@ -387,7 +390,7 @@ static int ov9750_set_flip(struct ov_camera_module *cam_mod,
387390
match_reg[2] = 0x00;
388391
} else if (mode == (OV_MIRROR_BIT_MASK |
389392
OV_FLIP_BIT_MASK)) {
390-
match_reg[0] = 0xc6;
393+
match_reg[0] = 0x86;
391394
match_reg[1] = 0x46;
392395
match_reg[2] = 0x20;
393396
} else {
@@ -442,10 +445,9 @@ static int OV9750_auto_adjust_fps(struct ov_camera_module *cam_mod,
442445
int ret;
443446
u32 vts;
444447

445-
if ((cam_mod->exp_config.exp_time + OV9750_COARSE_INTG_TIME_MAX_MARGIN)
448+
if ((exp_time + OV9750_COARSE_INTG_TIME_MAX_MARGIN)
446449
> cam_mod->vts_min)
447-
vts = cam_mod->exp_config.exp_time +
448-
OV9750_COARSE_INTG_TIME_MAX_MARGIN;
450+
vts = exp_time + OV9750_COARSE_INTG_TIME_MAX_MARGIN;
449451
else
450452
vts = cam_mod->vts_min;
451453

@@ -516,6 +518,7 @@ static int ov9750_write_aec(struct ov_camera_module *cam_mod)
516518
u32 a_gain = cam_mod->exp_config.gain;
517519
u32 exp_time = cam_mod->exp_config.exp_time;
518520

521+
mutex_lock(&cam_mod->lock);
519522
a_gain = a_gain * cam_mod->exp_config.gain_percent / 100;
520523
if (a_gain < 0x80)
521524
a_gain = 0x80;
@@ -551,13 +554,14 @@ static int ov9750_write_aec(struct ov_camera_module *cam_mod)
551554
ret |= ov9750_set_vts(cam_mod, cam_mod->exp_config.vts_value);
552555

553556
if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) {
554-
ret = ov_camera_module_write_reg(cam_mod,
557+
ret |= ov_camera_module_write_reg(cam_mod,
555558
OV9750_AEC_GROUP_UPDATE_ADDRESS,
556559
OV9750_AEC_GROUP_UPDATE_END_DATA);
557-
ret = ov_camera_module_write_reg(cam_mod,
560+
ret |= ov_camera_module_write_reg(cam_mod,
558561
OV9750_AEC_GROUP_UPDATE_ADDRESS,
559562
OV9750_AEC_GROUP_UPDATE_END_LAUNCH);
560563
}
564+
mutex_unlock(&cam_mod->lock);
561565
}
562566

563567
if (IS_ERR_VALUE(ret))
@@ -774,6 +778,8 @@ static int ov9750_g_timings(struct ov_camera_module *cam_mod,
774778
cam_mod->active_config->frm_intrvl.interval.denominator
775779
* vts
776780
* timings->line_length_pck;
781+
782+
timings->frame_length_lines = vts;
777783
return ret;
778784
err:
779785
ov_camera_module_pr_err(cam_mod,
@@ -827,13 +833,8 @@ static int ov9750_s_ext_ctrls(struct ov_camera_module *cam_mod,
827833
int ret = 0;
828834

829835
/* Handles only exposure and gain together special case. */
830-
if (ctrls->count == 1)
831-
ret = ov9750_s_ctrl(cam_mod, ctrls->ctrls[0].id);
832-
else if ((ctrls->count >= 3) &&
833-
(ctrls->ctrls[0].id == V4L2_CID_GAIN ||
834-
ctrls->ctrls[0].id == V4L2_CID_EXPOSURE ||
835-
ctrls->ctrls[1].id == V4L2_CID_GAIN ||
836-
ctrls->ctrls[1].id == V4L2_CID_EXPOSURE))
836+
if ((ctrls->ctrls[0].id == V4L2_CID_GAIN ||
837+
ctrls->ctrls[0].id == V4L2_CID_EXPOSURE))
837838
ret = ov9750_write_aec(cam_mod);
838839
else
839840
ret = -EINVAL;
@@ -860,7 +861,9 @@ static int ov9750_start_streaming(struct ov_camera_module *cam_mod)
860861
ret = OV9750_g_VTS(cam_mod, &cam_mod->vts_min);
861862
if (IS_ERR_VALUE(ret))
862863
goto err;
864+
mutex_lock(&cam_mod->lock);
863865
ret = ov_camera_module_write_reg(cam_mod, 0x0100, 0x01);
866+
mutex_unlock(&cam_mod->lock);
864867
if (IS_ERR_VALUE(ret))
865868
goto err;
866869

@@ -879,7 +882,9 @@ static int ov9750_stop_streaming(struct ov_camera_module *cam_mod)
879882
int ret = 0;
880883

881884
ov_camera_module_pr_info(cam_mod, "\n");
885+
mutex_lock(&cam_mod->lock);
882886
ret = ov_camera_module_write_reg(cam_mod, 0x0100, 0x00);
887+
mutex_unlock(&cam_mod->lock);
883888
if (IS_ERR_VALUE(ret))
884889
goto err;
885890

@@ -940,6 +945,7 @@ static struct v4l2_subdev_core_ops ov9750_camera_module_core_ops = {
940945

941946
static struct v4l2_subdev_video_ops ov9750_camera_module_video_ops = {
942947
.s_frame_interval = ov_camera_module_s_frame_interval,
948+
.g_frame_interval = ov_camera_module_g_frame_interval,
943949
.s_stream = ov_camera_module_s_stream
944950
};
945951

@@ -963,10 +969,12 @@ static struct ov_camera_module_custom_config ov9750_custom_config = {
963969
.s_ext_ctrls = ov9750_s_ext_ctrls,
964970
.g_timings = ov9750_g_timings,
965971
.set_flip = ov9750_set_flip,
972+
.s_vts = OV9750_auto_adjust_fps,
966973
.check_camera_id = ov9750_check_camera_id,
967974
.configs = ov9750_configs,
968975
.num_configs = ARRAY_SIZE(ov9750_configs),
969-
.power_up_delays_ms = {5, 30, 30}
976+
.power_up_delays_ms = {5, 30, 30},
977+
.exposure_valid_frame = {4, 4}
970978
};
971979

972980
static int ov9750_probe(struct i2c_client *client,
@@ -983,8 +991,11 @@ static int ov9750_probe(struct i2c_client *client,
983991
v4l2_i2c_subdev_init(&ov9750[cam_num].sd, client,
984992
&ov9750_camera_module_ops);
985993

994+
ov9750[cam_num].sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
986995
ov9750[cam_num].custom = ov9750_custom_config;
987996

997+
mutex_init(&ov9750[cam_num].lock);
998+
988999
ret = of_property_read_u32(np, "as-master", &as_master);
9891000
ov9750[cam_num].as_master = (ret == 0) ? as_master : -1;
9901001
cam_num++;
@@ -1004,6 +1015,7 @@ static int ov9750_remove(struct i2c_client *client)
10041015
if (!client->adapter)
10051016
return -ENODEV;
10061017

1018+
mutex_destroy(&cam_mod->lock);
10071019
ov_camera_module_release(cam_mod);
10081020

10091021
dev_info(&client->dev, "removed\n");

0 commit comments

Comments
 (0)