Skip to content

Commit dded039

Browse files
author
Omer Faruk Edemen
committed
media: i2c: ov9282: Add external FSIN trigger snapshot mode
This patch adds support for external FSIN-triggered snapshot mode to the OmniVision OV9282 sensor driver. It enables frame capture synchronized with an external hardware trigger signal. Signed-off-by: Omer Faruk Edemen <[email protected]>
1 parent 3829e1b commit dded039

File tree

1 file changed

+84
-7
lines changed

1 file changed

+84
-7
lines changed

drivers/media/i2c/ov9282.c

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@
6565
#define OV9282_REG_MIPI_CTRL00 0x4800
6666
#define OV9282_GATED_CLOCK BIT(5)
6767

68+
/* Trigger mode registers */
69+
#define OV9282_REG_POWER_CTRL 0x4F00
70+
#define OV9282_REG_LOW_POWER_MODE_CTRL 0x3030
71+
#define OV9282_REG_NUM_FRAME_ON_TRIG 0x303F
72+
#define OV9282_REG_SLEEP_PERIOD_CTRL0 0x302C
73+
#define OV9282_REG_SLEEP_PERIOD_CTRL3 0x302F
74+
#define OV9282_REG_TIMING_23 0x3823
75+
6876
/* Input clock rate */
6977
#define OV9282_INCLK_RATE 24000000
7078

@@ -187,6 +195,7 @@ struct ov9282 {
187195
const struct ov9282_mode *cur_mode;
188196
u32 code;
189197
struct mutex mutex;
198+
int trigger_mode;
190199
};
191200

192201
static const s64 link_freq[] = {
@@ -947,6 +956,58 @@ static int ov9282_get_selection(struct v4l2_subdev *sd,
947956
return -EINVAL;
948957
}
949958

959+
/**
960+
* ov9282_apply_trigger_config() - Configure sensor for FSIN external trigger mode
961+
* @ov9282: pointer to ov9282 device
962+
*
963+
* Return: 0 on success, error code otherwise.
964+
*/
965+
static int ov9282_apply_trigger_config(struct ov9282 *ov9282)
966+
{
967+
int ret;
968+
969+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
970+
1, OV9282_MODE_STANDBY);
971+
if (ret)
972+
return ret;
973+
974+
/* Low power mode */
975+
ret = ov9282_write_reg(ov9282, OV9282_REG_POWER_CTRL, 1, 0x01);
976+
if (ret)
977+
return ret;
978+
979+
/* External trigger snapshot */
980+
ret = ov9282_write_reg(ov9282, OV9282_REG_LOW_POWER_MODE_CTRL, 1, 0x04);
981+
if (ret)
982+
return ret;
983+
984+
/* 1 frame per trigger */
985+
ret = ov9282_write_reg(ov9282, OV9282_REG_NUM_FRAME_ON_TRIG, 1, 0x01);
986+
if (ret)
987+
return ret;
988+
989+
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL0, 1, 0x00);
990+
if (ret)
991+
return ret;
992+
993+
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL3, 1, 0x7F);
994+
if (ret)
995+
return ret;
996+
997+
/* No auto wake */
998+
ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_23, 1, 0x00);
999+
if (ret)
1000+
return ret;
1001+
1002+
/* stay standby mode and wait for trigger signal */
1003+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1004+
1, OV9282_MODE_STANDBY);
1005+
if (ret)
1006+
return ret;
1007+
1008+
return 0;
1009+
}
1010+
9501011
/**
9511012
* ov9282_start_streaming() - Start sensor stream
9521013
* @ov9282: pointer to ov9282 device
@@ -998,15 +1059,26 @@ static int ov9282_start_streaming(struct ov9282 *ov9282)
9981059
return ret;
9991060
}
10001061

1001-
/* Start streaming */
1002-
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1003-
1, OV9282_MODE_STREAMING);
1004-
if (ret) {
1005-
dev_err(ov9282->dev, "fail to start streaming");
1006-
return ret;
1062+
/* Configure FSIN external trigger mode */
1063+
if (ov9282->trigger_mode > 0) {
1064+
ret = ov9282_apply_trigger_config(ov9282);
1065+
if (ret) {
1066+
dev_err(ov9282->dev, "failed to config external trigger mode");
1067+
return ret;
1068+
}
1069+
/* stay in standby mode and wait for trigger signal */
1070+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1071+
1, OV9282_MODE_STANDBY);
1072+
} else {
1073+
/* Start streaming */
1074+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1075+
1, OV9282_MODE_STREAMING);
10071076
}
10081077

1009-
return 0;
1078+
if (ret)
1079+
dev_err(ov9282->dev, "fail to start streaming");
1080+
1081+
return ret;
10101082
}
10111083

10121084
/**
@@ -1392,6 +1464,7 @@ static int ov9282_probe(struct i2c_client *client)
13921464
{
13931465
struct ov9282 *ov9282;
13941466
int ret;
1467+
u32 trig_mod;
13951468

13961469
ov9282 = devm_kzalloc(&client->dev, sizeof(*ov9282), GFP_KERNEL);
13971470
if (!ov9282)
@@ -1431,6 +1504,10 @@ static int ov9282_probe(struct i2c_client *client)
14311504
ov9282->code = MEDIA_BUS_FMT_Y10_1X10;
14321505
ov9282->vblank = ov9282->cur_mode->vblank;
14331506

1507+
ret = of_property_read_u32(client->dev.of_node,
1508+
"trigger-mode", &trig_mod);
1509+
ov9282->trigger_mode = (ret == 0) ? trig_mod : -1;
1510+
14341511
ret = ov9282_init_controls(ov9282);
14351512
if (ret) {
14361513
dev_err(ov9282->dev, "failed to init controls: %d", ret);

0 commit comments

Comments
 (0)