Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: i2c: ov9282: add strobe_duration v4l2 control

Add V4L2_CID_FLASH_DURATION support using the "strobe_frame_span"
feature of the sensor. This is implemented by transforming the given µs
value by an interpolated formula to a "span step width" value and
writing it to register PWM_CTRL_25, PWM_CTRL_26, PWM_CTRL_27,
PWM_CTRL_28 (0x3925, 0x3926, 0x3927, 0x3928).

The maximum control value is set to the period of the current default
framerate.

All register values are based on the OV9281 datasheet v1.53 (jan 2019)
and tested using an ov9281 VisionComponents module.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
[Sakari Ailus: Remove redundant assignment of ret, declare ret as last.]
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Richard Leitner and committed by
Hans Verkuil
84ec7597 f007ad65

+44 -1
+44 -1
drivers/media/i2c/ov9282.c
··· 97 97 #define OV9282_REG_MIPI_CTRL00 0x4800 98 98 #define OV9282_GATED_CLOCK BIT(5) 99 99 100 + /* Flash/Strobe control registers */ 101 + #define OV9282_REG_STROBE_FRAME_SPAN 0x3925 102 + #define OV9282_STROBE_FRAME_SPAN_DEFAULT 0x0000001a 103 + 100 104 /* Input clock rate */ 101 105 #define OV9282_INCLK_RATE 24000000 102 106 ··· 691 687 return ov9282_write_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1, current_val); 692 688 } 693 689 690 + static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, u32 value) 691 + { 692 + /* 693 + * Calculate "strobe_frame_span" increments from a given value (µs). 694 + * This is quite tricky as "The step width of shift and span is 695 + * programmable under system clock domain.", but it's not documented 696 + * how to program this step width (at least in the datasheet available 697 + * to the author at time of writing). 698 + * The formula below is interpolated from different modes/framerates 699 + * and should work quite well for most settings. 700 + */ 701 + u32 val = value * 192 / (ov9282->cur_mode->width + ov9282->hblank_ctrl->val); 702 + int ret; 703 + 704 + ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN, 1, 705 + (val >> 24) & 0xff); 706 + if (ret) 707 + return ret; 708 + 709 + ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 1, 1, 710 + (val >> 16) & 0xff); 711 + if (ret) 712 + return ret; 713 + 714 + ret = ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 2, 1, 715 + (val >> 8) & 0xff); 716 + if (ret) 717 + return ret; 718 + 719 + return ov9282_write_reg(ov9282, OV9282_REG_STROBE_FRAME_SPAN + 3, 1, 720 + val & 0xff); 721 + } 722 + 694 723 /** 695 724 * ov9282_set_ctrl() - Set subdevice control 696 725 * @ctrl: pointer to v4l2_ctrl structure ··· 792 755 break; 793 756 case V4L2_CID_FLASH_STROBE_OE: 794 757 ret = ov9282_set_ctrl_flash_strobe_oe(ov9282, ctrl->val); 758 + break; 759 + case V4L2_CID_FLASH_DURATION: 760 + ret = ov9282_set_ctrl_flash_duration(ov9282, ctrl->val); 795 761 break; 796 762 default: 797 763 dev_err(ov9282->dev, "Invalid control %d", ctrl->id); ··· 1385 1345 u32 lpfr; 1386 1346 int ret; 1387 1347 1388 - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11); 1348 + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); 1389 1349 if (ret) 1390 1350 return ret; 1391 1351 ··· 1453 1413 /* Flash/Strobe controls */ 1454 1414 v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, 1455 1415 V4L2_CID_FLASH_STROBE_OE, 0, 1, 1, 0); 1416 + 1417 + v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, 1418 + 0, 13900, 1, 8); 1456 1419 1457 1420 ret = v4l2_fwnode_device_parse(ov9282->dev, &props); 1458 1421 if (!ret) {