-
Notifications
You must be signed in to change notification settings - Fork 5.2k
media: ov9282: Add external trigger mode support #6954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rpi-6.12.y
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,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 | ||
|
||
|
@@ -187,6 +195,7 @@ | |
const struct ov9282_mode *cur_mode; | ||
u32 code; | ||
struct mutex mutex; | ||
int trigger_mode; | ||
}; | ||
|
||
static const s64 link_freq[] = { | ||
|
@@ -947,6 +956,65 @@ | |
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; | ||
Check failure on line 967 in drivers/media/i2c/ov9282.c
|
||
|
||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT, 1, OV9282_MODE_STANDBY); | ||
Check failure on line 969 in drivers/media/i2c/ov9282.c
|
||
if (ret) { | ||
Check failure on line 970 in drivers/media/i2c/ov9282.c
|
||
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 */ | ||
ov9282_write_reg(ov9282, OV9282_REG_NUM_FRAME_ON_TRIG, 1, 0x01); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL0, 1, 0x00); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
ov9282_write_reg(ov9282, OV9282_REG_SLEEP_PERIOD_CTRL3, 1, 0x7F); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
/* No auto wake */ | ||
ov9282_write_reg(ov9282, OV9282_REG_TIMING_23, 1, 0x00); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
/* stay standby mode and wait for trigger signal */ | ||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT, | ||
1, OV9282_MODE_STANDBY); | ||
if (ret) { | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* ov9282_start_streaming() - Start sensor stream | ||
* @ov9282: pointer to ov9282 device | ||
|
@@ -970,7 +1038,7 @@ | |
|
||
/* Write common registers */ | ||
ret = ov9282_write_regs(ov9282, common_regs_list.regs, | ||
common_regs_list.num_of_regs); | ||
common_regs_list.num_of_regs); | ||
if (ret) { | ||
dev_err(ov9282->dev, "fail to write common registers"); | ||
return ret; | ||
|
@@ -992,15 +1060,25 @@ | |
} | ||
|
||
/* Setup handler will write actual exposure and gain */ | ||
ret = __v4l2_ctrl_handler_setup(ov9282->sd.ctrl_handler); | ||
ret = __v4l2_ctrl_handler_setup(ov9282->sd.ctrl_handler); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whitespace change |
||
if (ret) { | ||
dev_err(ov9282->dev, "fail to setup handler"); | ||
return ret; | ||
} | ||
|
||
if (ov9282->trigger_mode > 0) { | ||
/* Configure FSIN external trigger mode */ | ||
ret = ov9282_apply_trigger_config(ov9282); | ||
if (ret) { | ||
dev_err(ov9282->dev, "failed to config external trigger mode"); | ||
return ret; | ||
} | ||
return 0; | ||
} | ||
|
||
/* Start streaming */ | ||
ret = ov9282_write_reg(ov9282, OV9282_REG_MODE_SELECT, | ||
1, OV9282_MODE_STREAMING); | ||
1, OV9282_MODE_STREAMING); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Odd whitespace change for no reason |
||
if (ret) { | ||
dev_err(ov9282->dev, "fail to start streaming"); | ||
return ret; | ||
|
@@ -1392,6 +1470,7 @@ | |
{ | ||
struct ov9282 *ov9282; | ||
int ret; | ||
u32 trig_mod; | ||
|
||
ov9282 = devm_kzalloc(&client->dev, sizeof(*ov9282), GFP_KERNEL); | ||
if (!ov9282) | ||
|
@@ -1431,6 +1510,9 @@ | |
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); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've not saved the result of
ov9282_write_reg
toret
, so this will never fail.Ditto subsequent calls.