#define OV9282_REG_MIPI_CTRL00 0x4800
#define OV9282_GATED_CLOCK BIT(5)
+/* Flash/Strobe control registers */
+#define OV9282_REG_STROBE_FRAME_SPAN 0x3925
+#define OV9282_STROBE_FRAME_SPAN_DEFAULT 0x0000001a
+
/* Input clock rate */
#define OV9282_INCLK_RATE 24000000
return ov9282_write_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1, current_val);
}
+static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, u32 value)
+{
+ /*
+ * Calculate "strobe_frame_span" increments from a given value (µs).
+ * This is quite tricky as "The step width of shift and span is
+ * programmable under system clock domain.", but it's not documented
+ * how to program this step width (at least in the datasheet available
+ * to the author at time of writing).
+ * The formula below is interpolated from different modes/framerates
+ * and should work quite well for most settings.
+ */
+ u32 val = value * 192 / (ov9282->cur_mode->width + ov9282->hblank_ctrl->val);
+ int ret;
+
+ ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN, 1,
+ (val >> 24) & 0xff);
+ if (ret)
+ return ret;
+
+ ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 1, 1,
+ (val >> 16) & 0xff);
+ if (ret)
+ return ret;
+
+ ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 2, 1,
+ (val >> 8) & 0xff);
+ if (ret)
+ return ret;
+
+ return ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 3, 1,
+ val & 0xff);
+}
+
/**
* ov9282_set_ctrl() - Set subdevice control
* @ctrl: pointer to v4l2_ctrl structure
case V4L2_CID_FLASH_STROBE_OE:
ret = ov9282_set_ctrl_flash_strobe_oe(ov9282, ctrl->val);
break;
+ case V4L2_CID_FLASH_DURATION:
+ ret = ov9282_set_ctrl_flash_duration(ov9282, ctrl->val);
+ break;
default:
dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
ret = -EINVAL;
u32 lpfr;
int ret;
- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
if (ret)
return ret;
v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops,
V4L2_CID_FLASH_STROBE_OE, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
+ 0, 13900, 1, 8);
+
ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
if (!ret) {
/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */