Skip to content

Commit 3b92c06

Browse files
Omer Faruk Edemenpopcornmix
authored andcommitted
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 e584321 commit 3b92c06

File tree

1 file changed

+78
-7
lines changed

1 file changed

+78
-7
lines changed

drivers/media/i2c/ov9282.c

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@
7474
#define OV9282_REG_MIPI_CTRL00 0x4800
7575
#define OV9282_GATED_CLOCK BIT(5)
7676

77+
/* Trigger mode registers */
78+
#define OV9282_REG_POWER_CTRL 0x4F00
79+
#define OV9282_REG_LOW_POWER_MODE_CTRL 0x3030
80+
#define OV9282_REG_NUM_FRAME_ON_TRIG 0x303F
81+
#define OV9282_REG_SLEEP_PERIOD_CTRL0 0x302C
82+
#define OV9282_REG_SLEEP_PERIOD_CTRL3 0x302F
83+
#define OV9282_REG_TIMING_23 0x3823
84+
7785
/* Input clock rate */
7886
#define OV9282_INCLK_RATE 24000000
7987

@@ -196,6 +204,7 @@ struct ov9282 {
196204
const struct ov9282_mode *cur_mode;
197205
u32 code;
198206
struct mutex mutex;
207+
int trigger_mode;
199208
};
200209

201210
static const s64 link_freq[] = {
@@ -956,6 +965,52 @@ static int ov9282_get_selection(struct v4l2_subdev *sd,
956965
return -EINVAL;
957966
}
958967

968+
/**
969+
* ov9282_apply_trigger_config() - Configure sensor for FSIN external trigger mode
970+
* @ov9282: pointer to ov9282 device
971+
*
972+
* Return: 0 on success, error code otherwise.
973+
*/
974+
static int ov9282_apply_trigger_config(struct ov9282 *ov9282)
975+
{
976+
int ret;
977+
978+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
979+
1, OV9282_MODE_STANDBY);
980+
if (ret)
981+
return ret;
982+
983+
/* Low power mode */
984+
ret = ov9282_write_reg(ov9282, OV9282_REG_POWER_CTRL, 1, 0x01);
985+
if (ret)
986+
return ret;
987+
988+
/* External trigger snapshot */
989+
ret = ov9282_write_reg(ov9282, OV9282_REG_LOW_POWER_MODE_CTRL, 1, 0x04);
990+
if (ret)
991+
return ret;
992+
993+
/* 1 frame per trigger */
994+
ret = ov9282_write_reg(ov9282, OV9282_REG_NUM_FRAME_ON_TRIG, 1, 0x01);
995+
if (ret)
996+
return ret;
997+
998+
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL0, 1, 0x00);
999+
if (ret)
1000+
return ret;
1001+
1002+
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL3, 1, 0x7F);
1003+
if (ret)
1004+
return ret;
1005+
1006+
/* No auto wake */
1007+
ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_23, 1, 0x00);
1008+
if (ret)
1009+
return ret;
1010+
1011+
return 0;
1012+
}
1013+
9591014
/**
9601015
* ov9282_start_streaming() - Start sensor stream
9611016
* @ov9282: pointer to ov9282 device
@@ -1007,15 +1062,26 @@ static int ov9282_start_streaming(struct ov9282 *ov9282)
10071062
return ret;
10081063
}
10091064

1010-
/* Start streaming */
1011-
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1012-
1, OV9282_MODE_STREAMING);
1013-
if (ret) {
1014-
dev_err(ov9282->dev, "fail to start streaming");
1015-
return ret;
1065+
/* Configure FSIN external trigger mode */
1066+
if (ov9282->trigger_mode > 0) {
1067+
ret = ov9282_apply_trigger_config(ov9282);
1068+
if (ret) {
1069+
dev_err(ov9282->dev, "failed to config external trigger mode");
1070+
return ret;
1071+
}
1072+
/* stay in standby mode and wait for trigger signal */
1073+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1074+
1, OV9282_MODE_STANDBY);
1075+
} else {
1076+
/* Start streaming */
1077+
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
1078+
1, OV9282_MODE_STREAMING);
10161079
}
10171080

1018-
return 0;
1081+
if (ret)
1082+
dev_err(ov9282->dev, "fail to start streaming");
1083+
1084+
return ret;
10191085
}
10201086

10211087
/**
@@ -1401,6 +1467,7 @@ static int ov9282_probe(struct i2c_client *client)
14011467
{
14021468
struct ov9282 *ov9282;
14031469
int ret;
1470+
u32 trig_mod;
14041471

14051472
ov9282 = devm_kzalloc(&client->dev, sizeof(*ov9282), GFP_KERNEL);
14061473
if (!ov9282)
@@ -1440,6 +1507,10 @@ static int ov9282_probe(struct i2c_client *client)
14401507
ov9282->code = MEDIA_BUS_FMT_Y10_1X10;
14411508
ov9282->vblank = ov9282->cur_mode->vblank;
14421509

1510+
ret = of_property_read_u32(client->dev.of_node,
1511+
"trigger-mode", &trig_mod);
1512+
ov9282->trigger_mode = (ret == 0) ? trig_mod : -1;
1513+
14431514
ret = ov9282_init_controls(ov9282);
14441515
if (ret) {
14451516
dev_err(ov9282->dev, "failed to init controls: %d", ret);

0 commit comments

Comments
 (0)