mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
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 <ofedemen@lectrontech.com>
This commit is contained in:
committed by
Dom Cobley
parent
3c1835d0a2
commit
5526ee14ca
@@ -74,6 +74,14 @@
|
||||
#define OV9282_REG_MIPI_CTRL00 0x4800
|
||||
#define OV9282_GATED_CLOCK BIT(5)
|
||||
|
||||
/* Trigger mode registers */
|
||||
#define OV9282_REG_POWER_CTRL 0x4F00
|
||||
#define OV9282_REG_LOW_POWER_MODE_CTRL 0x3030
|
||||
#define OV9282_REG_NUM_FRAME_ON_TRIG 0x303F
|
||||
#define OV9282_REG_SLEEP_PERIOD_CTRL0 0x302C
|
||||
#define OV9282_REG_SLEEP_PERIOD_CTRL3 0x302F
|
||||
#define OV9282_REG_TIMING_23 0x3823
|
||||
|
||||
/* Input clock rate */
|
||||
#define OV9282_INCLK_RATE 24000000
|
||||
|
||||
@@ -196,6 +204,7 @@ struct ov9282 {
|
||||
const struct ov9282_mode *cur_mode;
|
||||
u32 code;
|
||||
struct mutex mutex;
|
||||
int trigger_mode;
|
||||
};
|
||||
|
||||
static const s64 link_freq[] = {
|
||||
@@ -956,6 +965,52 @@ static int ov9282_get_selection(struct v4l2_subdev *sd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ov9282_apply_trigger_config() - Configure sensor for FSIN external trigger mode
|
||||
* @ov9282: pointer to ov9282 device
|
||||
*
|
||||
* Return: 0 on success, error code otherwise.
|
||||
*/
|
||||
static int ov9282_apply_trigger_config(struct ov9282 *ov9282)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
|
||||
1, OV9282_MODE_STANDBY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Low power mode */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_POWER_CTRL, 1, 0x01);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* External trigger snapshot */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_LOW_POWER_MODE_CTRL, 1, 0x04);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 1 frame per trigger */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_NUM_FRAME_ON_TRIG, 1, 0x01);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL0, 1, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL3, 1, 0x7F);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* No auto wake */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_23, 1, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ov9282_start_streaming() - Start sensor stream
|
||||
* @ov9282: pointer to ov9282 device
|
||||
@@ -1007,15 +1062,26 @@ static int ov9282_start_streaming(struct ov9282 *ov9282)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start streaming */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
|
||||
1, OV9282_MODE_STREAMING);
|
||||
if (ret) {
|
||||
dev_err(ov9282->dev, "fail to start streaming");
|
||||
return ret;
|
||||
/* Configure FSIN external trigger mode */
|
||||
if (ov9282->trigger_mode > 0) {
|
||||
ret = ov9282_apply_trigger_config(ov9282);
|
||||
if (ret) {
|
||||
dev_err(ov9282->dev, "failed to config external trigger mode");
|
||||
return ret;
|
||||
}
|
||||
/* stay in standby mode and wait for trigger signal */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
|
||||
1, OV9282_MODE_STANDBY);
|
||||
} else {
|
||||
/* Start streaming */
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT,
|
||||
1, OV9282_MODE_STREAMING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (ret)
|
||||
dev_err(ov9282->dev, "fail to start streaming");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1400,6 +1466,7 @@ static int ov9282_probe(struct i2c_client *client)
|
||||
{
|
||||
struct ov9282 *ov9282;
|
||||
int ret;
|
||||
u32 trig_mod;
|
||||
|
||||
ov9282 = devm_kzalloc(&client->dev, sizeof(*ov9282), GFP_KERNEL);
|
||||
if (!ov9282)
|
||||
@@ -1439,6 +1506,10 @@ static int ov9282_probe(struct i2c_client *client)
|
||||
ov9282->code = MEDIA_BUS_FMT_Y10_1X10;
|
||||
ov9282->vblank = ov9282->cur_mode->vblank;
|
||||
|
||||
ret = of_property_read_u32(client->dev.of_node,
|
||||
"trigger-mode", &trig_mod);
|
||||
ov9282->trigger_mode = (ret == 0) ? trig_mod : -1;
|
||||
|
||||
ret = ov9282_init_controls(ov9282);
|
||||
if (ret) {
|
||||
dev_err(ov9282->dev, "failed to init controls: %d", ret);
|
||||
|
||||
Reference in New Issue
Block a user