linux-leds.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282
@ 2025-05-07  7:51 Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 01/10] media: v4l: ctrls: add a control for flash/strobe duration Richard Leitner
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

This series adds a new v4l2 controls named "strobe duration" with id
V4L2_CID_FLASH_DURATION. This control enables setting a desired
flash/strobe length/duration in µs.

As a first user of this new control add basic flash/strobe support for
ov9282 sensors using their "hardware strobe output". The duration
calculation is only interpolated from various measurements, as no
documentation was found.

Further flash/strobe-related controls as well as a migration to v4l2-cci
helpers for ov9282 will likely be implemented in future series.

All register addresses/values are based on the OV9281 datasheet v1.53
(january 2019). This series was tested using an ov9281 VisionComponents
camera module.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
Changes in v4:
- Fix FLASH_DURATION implementation in v4l2-flash-led-class.c by adding a
  missing brace and enum entry (thanks Sakari)
- Fix format of multiline comment in ov9282.c (thanks Sakari)
- Add missing NULL check in ov9282.c (thanks Sakari)
- Adapt nr_of_controls_hint for v4l2 handler in ov9282.c (thanks Sakari)
- Add patch for implementing try_ctrl for strobe_duration (thanks Sakari)
- Link to v3: https://lore.kernel.org/r/20250429-ov9282-flash-strobe-v3-0-2105ce179952@linux.dev

Changes in v3:
- create separate patch for leds driver changes (thanks Lee)
- Link to v2: https://lore.kernel.org/r/20250314-ov9282-flash-strobe-v2-0-14d7a281342d@linux.dev

Changes in v2:
- remove not needed controls in struct ov9282 (thanks Dave)
- Fix commit message of 3/3 regarding framerate get/set (thanks Dave)
- Add V4L2_CID_FLASH_STROBE_SOURCE impementation to ov9282
- Add new V4L2_CID_FLASH_DURATION control (as suggested by Laurent)
- Use FLASH_DURATION instead of FLASH_TIMEOUT for ov9282
- Link to v1: https://lore.kernel.org/r/20250303-ov9282-flash-strobe-v1-0-0fd57a1564ba@linux.dev

---
Richard Leitner (10):
      media: v4l: ctrls: add a control for flash/strobe duration
      leds: flash: add support for flash/stobe duration
      media: v4l2-flash: add support for flash/strobe duration
      media: v4l2-flash: fix flash_timeout comment
      Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION
      media: i2c: ov9282: add output enable register definitions
      media: i2c: ov9282: add led_mode v4l2 control
      media: i2c: ov9282: add strobe_duration v4l2 control
      media: i2c: ov9282: add strobe_source v4l2 control
      media: i2c: ov9282: implement try_ctrl for strobe_duration

 .../userspace-api/media/v4l/ext-ctrls-flash.rst    |   5 +
 drivers/leds/led-class-flash.c                     |  15 +++
 drivers/media/i2c/ov9282.c                         | 148 ++++++++++++++++++++-
 drivers/media/v4l2-core/v4l2-ctrls-defs.c          |   1 +
 drivers/media/v4l2-core/v4l2-flash-led-class.c     |  25 ++++
 include/linux/led-class-flash.h                    |  18 ++-
 include/uapi/linux/v4l2-controls.h                 |   1 +
 7 files changed, 208 insertions(+), 5 deletions(-)
---
base-commit: 92a09c47464d040866cf2b4cd052bc60555185fb
change-id: 20250303-ov9282-flash-strobe-ac6bd00c9de6
prerequisite-change-id: 20250225-b4-ov9282-gain-ef1cdaba5bfd:v1
prerequisite-patch-id: 86f2582378ff7095ab65ce4bb25a143eb639e840
prerequisite-patch-id: b06eb6ec697aaf0b3155b4b2370f171d0d304ae2
prerequisite-patch-id: b123047d71bfb9b93f743bbdd6893d5a98495801

Best regards,
-- 
Richard Leitner <richard.leitner@linux.dev>



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v4 01/10] media: v4l: ctrls: add a control for flash/strobe duration
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 02/10] leds: flash: add support for flash/stobe duration Richard Leitner
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add a control V4L2_CID_FLASH_DURATION to set the duration of a
flash/strobe pulse. This is different to the V4L2_CID_FLASH_TIMEOUT
control, as the timeout defines a limit after which the flash is
"forcefully" turned off again.

On the other hand the new V4L2_CID_FLASH_DURATION is the desired length
of the flash/strobe pulse.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/v4l2-core/v4l2-ctrls-defs.c | 1 +
 include/uapi/linux/v4l2-controls.h        | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 1ea52011247accc51d0261f56eab1cf13c0624a0..f9ed7273a9f3eafe01c31b638e1c8d9fcf5424af 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1135,6 +1135,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_FLASH_FAULT:		return "Faults";
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to Strobe";
+	case V4L2_CID_FLASH_DURATION:		return "Strobe Duration";
 
 	/* JPEG encoder controls */
 	/* Keep the order of the 'case's the same as in v4l2-controls.h! */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 72e32814ea83dee5f1202c1249eac7cf3b85a22a..72c6bd26e2dfa23a0224e745e5cd07c9fca0c8b5 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1180,6 +1180,7 @@ enum v4l2_flash_strobe_source {
 
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
+#define V4L2_CID_FLASH_DURATION			(V4L2_CID_FLASH_CLASS_BASE + 13)
 
 
 /* JPEG-class control IDs */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 02/10] leds: flash: add support for flash/stobe duration
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 01/10] media: v4l: ctrls: add a control for flash/strobe duration Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-13 10:08   ` (subset) " Lee Jones
  2025-05-07  7:51 ` [PATCH v4 03/10] media: v4l2-flash: add support for flash/strobe duration Richard Leitner
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add support for the new V4L2_CID_FLASH_DURATION control to the leds
driver.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/leds/led-class-flash.c  | 15 +++++++++++++++
 include/linux/led-class-flash.h | 16 ++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/leds/led-class-flash.c b/drivers/leds/led-class-flash.c
index f4e26ce84862c05092a9598e63ed301967852f13..165035a8826ca7d44a5cd265a5130a76c6e94347 100644
--- a/drivers/leds/led-class-flash.c
+++ b/drivers/leds/led-class-flash.c
@@ -440,6 +440,21 @@ int led_update_flash_brightness(struct led_classdev_flash *fled_cdev)
 }
 EXPORT_SYMBOL_GPL(led_update_flash_brightness);
 
+int led_set_flash_duration(struct led_classdev_flash *fled_cdev, u32 duration)
+{
+	struct led_classdev *led_cdev = &fled_cdev->led_cdev;
+	struct led_flash_setting *s = &fled_cdev->duration;
+
+	s->val = duration;
+	led_clamp_align(s);
+
+	if (!(led_cdev->flags & LED_SUSPENDED))
+		return call_flash_op(fled_cdev, duration_set, s->val);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(led_set_flash_duration);
+
 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
 MODULE_DESCRIPTION("LED Flash class interface");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/led-class-flash.h b/include/linux/led-class-flash.h
index 36df927ec4b7dcaf9074c6ef32ac8ce83a87a79d..21ec856c36bc67decda46aa8ff1c040ffdcf1181 100644
--- a/include/linux/led-class-flash.h
+++ b/include/linux/led-class-flash.h
@@ -45,6 +45,8 @@ struct led_flash_ops {
 	int (*timeout_set)(struct led_classdev_flash *fled_cdev, u32 timeout);
 	/* get the flash LED fault */
 	int (*fault_get)(struct led_classdev_flash *fled_cdev, u32 *fault);
+	/* set flash duration */
+	int (*duration_set)(struct led_classdev_flash *fled_cdev, u32 duration);
 };
 
 /*
@@ -75,6 +77,9 @@ struct led_classdev_flash {
 	/* flash timeout value in microseconds along with its constraints */
 	struct led_flash_setting timeout;
 
+	/* flash timeout value in microseconds along with its constraints */
+	struct led_flash_setting duration;
+
 	/* LED Flash class sysfs groups */
 	const struct attribute_group *sysfs_groups[LED_FLASH_SYSFS_GROUPS_SIZE];
 };
@@ -209,4 +214,15 @@ int led_set_flash_timeout(struct led_classdev_flash *fled_cdev, u32 timeout);
  */
 int led_get_flash_fault(struct led_classdev_flash *fled_cdev, u32 *fault);
 
+/**
+ * led_set_flash_duration - set flash LED duration
+ * @fled_cdev: the flash LED to set
+ * @timeout: the flash duration to set it to
+ *
+ * Set the flash strobe duration.
+ *
+ * Returns: 0 on success or negative error value on failure
+ */
+int led_set_flash_duration(struct led_classdev_flash *fled_cdev, u32 duration);
+
 #endif	/* __LINUX_FLASH_LEDS_H_INCLUDED */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 03/10] media: v4l2-flash: add support for flash/strobe duration
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 01/10] media: v4l: ctrls: add a control for flash/strobe duration Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 02/10] leds: flash: add support for flash/stobe duration Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 04/10] media: v4l2-flash: fix flash_timeout comment Richard Leitner
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add support for the new V4L2_CID_FLASH_DURATION control to the v4l2
flash led class.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/v4l2-core/v4l2-flash-led-class.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 355595a0fefac72c2f6941a30fa430d37dbdccfe..69b6c2026e0ad905aaebcdabe1e7002fc48f9e2c 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -29,6 +29,7 @@ enum ctrl_init_data_id {
 	INDICATOR_INTENSITY,
 	FLASH_TIMEOUT,
 	STROBE_SOURCE,
+	FLASH_DURATION,
 	/*
 	 * Only above values are applicable to
 	 * the 'ctrls' array in the struct v4l2_flash.
@@ -298,6 +299,12 @@ static int v4l2_flash_s_ctrl(struct v4l2_ctrl *c)
 		 * microamperes for flash intensity units.
 		 */
 		return led_set_flash_brightness(fled_cdev, c->val);
+	case V4L2_CID_FLASH_DURATION:
+		/*
+		 * No conversion is needed as LED Flash class also uses
+		 * microseconds for flash duration units.
+		 */
+		return led_set_flash_duration(fled_cdev, c->val);
 	}
 
 	return -EINVAL;
@@ -424,6 +431,14 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash,
 		ctrl_cfg->flags = V4L2_CTRL_FLAG_VOLATILE |
 				  V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
 	}
+
+	/* Init FLASH_DURATION ctrl data */
+	if (has_flash_op(fled_cdev, duration_set)) {
+		ctrl_init_data[FLASH_DURATION].cid = V4L2_CID_FLASH_DURATION;
+		ctrl_cfg = &ctrl_init_data[FLASH_DURATION].config;
+		__lfs_to_v4l2_ctrl_config(&fled_cdev->duration, ctrl_cfg);
+		ctrl_cfg->id = V4L2_CID_FLASH_DURATION;
+	}
 }
 
 static int v4l2_flash_init_controls(struct v4l2_flash *v4l2_flash,
@@ -543,6 +558,16 @@ static int __sync_device_with_v4l2_controls(struct v4l2_flash *v4l2_flash)
 			return ret;
 	}
 
+	if (ctrls[FLASH_DURATION]) {
+		if (WARN_ON_ONCE(!fled_cdev))
+			return -EINVAL;
+
+		ret = led_set_flash_duration(fled_cdev,
+					ctrls[FLASH_DURATION]->val);
+		if (ret < 0)
+			return ret;
+	}
+
 	/*
 	 * For some hardware arrangements setting strobe source may affect
 	 * torch mode. Synchronize strobe source setting only if not in torch

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 04/10] media: v4l2-flash: fix flash_timeout comment
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (2 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 03/10] media: v4l2-flash: add support for flash/strobe duration Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 05/10] Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION Richard Leitner
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

The comment for the flash_timeout setter mentioned it is the "flash
duration". Fix this by changing it to "flash timeout".

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 include/linux/led-class-flash.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/led-class-flash.h b/include/linux/led-class-flash.h
index 21ec856c36bc67decda46aa8ff1c040ffdcf1181..775a96217518936633541c7a5d394502dbf04f83 100644
--- a/include/linux/led-class-flash.h
+++ b/include/linux/led-class-flash.h
@@ -197,7 +197,7 @@ int led_update_flash_brightness(struct led_classdev_flash *fled_cdev);
  * @fled_cdev: the flash LED to set
  * @timeout: the flash timeout to set it to
  *
- * Set the flash strobe duration.
+ * Set the flash strobe timeout.
  *
  * Returns: 0 on success or negative error value on failure
  */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 05/10] Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (3 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 04/10] media: v4l2-flash: fix flash_timeout comment Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 06/10] media: i2c: ov9282: add output enable register definitions Richard Leitner
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add the new strobe_duration control to v4l uAPI documentation.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst
index d22c5efb806a183a3ad67ec3e6550b002a51659a..03a58ef94be7c870f55d5a9bb09503995dbfb402 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-flash.rst
@@ -186,3 +186,8 @@ Flash Control IDs
     charged before strobing. LED flashes often require a cooldown period
     after strobe during which another strobe will not be possible. This
     is a read-only control.
+
+``V4L2_CID_FLASH_DURATION (integer)``
+    Duration the flash should be on when the flash LED is in flash mode
+    (V4L2_FLASH_LED_MODE_FLASH). The unit should be microseconds (µs)
+    if possible.

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 06/10] media: i2c: ov9282: add output enable register definitions
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (4 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 05/10] Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-07  7:51 ` [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control Richard Leitner
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add #define's for the output enable registers (0x3004, 0x3005, 0x3006),
also known as SC_CTRL_04, SC_CTRL_05, SC_CTRL_04. Use those register
definitions instead of the raw values in the `common_regs` struct.

All values are based on the OV9281 datasheet v1.53 (january 2019).

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/i2c/ov9282.c | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index c882a021cf18852237bf9b9524d3de0c5b48cbcb..f42e0d439753e74d14e3a3592029e48f49234927 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -37,6 +37,29 @@
 #define OV9282_REG_ID		0x300a
 #define OV9282_ID		0x9281
 
+/* Output enable registers */
+#define OV9282_REG_OUTPUT_ENABLE4	0x3004
+#define OV9282_OUTPUT_ENABLE4_GPIO2	BIT(1)
+#define OV9282_OUTPUT_ENABLE4_D9	BIT(0)
+
+#define OV9282_REG_OUTPUT_ENABLE5	0x3005
+#define OV9282_OUTPUT_ENABLE5_D8	BIT(7)
+#define OV9282_OUTPUT_ENABLE5_D7	BIT(6)
+#define OV9282_OUTPUT_ENABLE5_D6	BIT(5)
+#define OV9282_OUTPUT_ENABLE5_D5	BIT(4)
+#define OV9282_OUTPUT_ENABLE5_D4	BIT(3)
+#define OV9282_OUTPUT_ENABLE5_D3	BIT(2)
+#define OV9282_OUTPUT_ENABLE5_D2	BIT(1)
+#define OV9282_OUTPUT_ENABLE5_D1	BIT(0)
+
+#define OV9282_REG_OUTPUT_ENABLE6	0x3006
+#define OV9282_OUTPUT_ENABLE6_D0	BIT(7)
+#define OV9282_OUTPUT_ENABLE6_PCLK	BIT(6)
+#define OV9282_OUTPUT_ENABLE6_HREF	BIT(5)
+#define OV9282_OUTPUT_ENABLE6_STROBE	BIT(3)
+#define OV9282_OUTPUT_ENABLE6_ILPWM	BIT(2)
+#define OV9282_OUTPUT_ENABLE6_VSYNC	BIT(1)
+
 /* Exposure control */
 #define OV9282_REG_EXPOSURE	0x3500
 #define OV9282_EXPOSURE_MIN	1
@@ -213,9 +236,9 @@ static const struct ov9282_reg common_regs[] = {
 	{0x0302, 0x32},
 	{0x030e, 0x02},
 	{0x3001, 0x00},
-	{0x3004, 0x00},
-	{0x3005, 0x00},
-	{0x3006, 0x04},
+	{OV9282_REG_OUTPUT_ENABLE4, 0x00},
+	{OV9282_REG_OUTPUT_ENABLE5, 0x00},
+	{OV9282_REG_OUTPUT_ENABLE6, OV9282_OUTPUT_ENABLE6_ILPWM},
 	{0x3011, 0x0a},
 	{0x3013, 0x18},
 	{0x301c, 0xf0},

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (5 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 06/10] media: i2c: ov9282: add output enable register definitions Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-26 20:41   ` Sakari Ailus
  2025-05-07  7:51 ` [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration " Richard Leitner
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add V4L2_CID_FLASH_LED_MODE support using the "strobe output enable"
feature of the sensor. This implements following modes:

 - V4L2_FLASH_LED_MODE_NONE, which disables the strobe output
 - V4L2_FLASH_LED_MODE_FLASH, which enables the strobe output

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

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/i2c/ov9282.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index f42e0d439753e74d14e3a3592029e48f49234927..b6de96997426f7225a061bfdc841aa062e8d0891 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -670,6 +670,23 @@ static int ov9282_set_ctrl_vflip(struct ov9282 *ov9282, int value)
 				current_val);
 }
 
+static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
+{
+	u32 current_val;
+	int ret = ov9282_read_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
+				  &current_val);
+	if (ret)
+		return ret;
+
+	if (mode == V4L2_FLASH_LED_MODE_FLASH)
+		current_val |= OV9282_OUTPUT_ENABLE6_STROBE;
+	else
+		current_val &= ~OV9282_OUTPUT_ENABLE6_STROBE;
+
+	return ov9282_write_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
+				current_val);
+}
+
 /**
  * ov9282_set_ctrl() - Set subdevice control
  * @ctrl: pointer to v4l2_ctrl structure
@@ -736,6 +753,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
 		ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_HTS, 2,
 				       (ctrl->val + ov9282->cur_mode->width) >> 1);
 		break;
+	case V4L2_CID_FLASH_LED_MODE:
+		ret = ov9282_set_ctrl_flash_led_mode(ov9282, ctrl->val);
+		break;
 	default:
 		dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
 		ret = -EINVAL;
@@ -1326,7 +1346,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 	u32 lpfr;
 	int ret;
 
-	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
 	if (ret)
 		return ret;
 
@@ -1391,6 +1411,13 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 						OV9282_TIMING_HTS_MAX - mode->width,
 						1, hblank_min);
 
+	/* Flash/Strobe controls */
+	v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
+			       V4L2_CID_FLASH_LED_MODE,
+			       V4L2_FLASH_LED_MODE_TORCH,
+			       (1 << V4L2_FLASH_LED_MODE_TORCH),
+			       V4L2_FLASH_LED_MODE_NONE);
+
 	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
 	if (!ret) {
 		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration v4l2 control
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (6 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-26 20:27   ` Sakari Ailus
  2025-05-07  7:51 ` [PATCH v4 09/10] media: i2c: ov9282: add strobe_source " Richard Leitner
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

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>
---
 drivers/media/i2c/ov9282.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index b6de96997426f7225a061bfdc841aa062e8d0891..0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -97,6 +97,10 @@
 #define OV9282_REG_MIPI_CTRL00	0x4800
 #define OV9282_GATED_CLOCK	BIT(5)
 
+/* Flash/Strobe control registers */
+#define OV9282_REG_FLASH_DURATION	0x3925
+#define OV9282_FLASH_DURATION_DEFAULT	0x0000001A
+
 /* Input clock rate */
 #define OV9282_INCLK_RATE	24000000
 
@@ -687,6 +691,25 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
 				current_val);
 }
 
+static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int 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);
+
+	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
+	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
+	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 2, 1, (val >> 8) & 0xff);
+	return ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 3, 1, val & 0xff);
+}
+
 /**
  * ov9282_set_ctrl() - Set subdevice control
  * @ctrl: pointer to v4l2_ctrl structure
@@ -756,6 +779,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_FLASH_LED_MODE:
 		ret = ov9282_set_ctrl_flash_led_mode(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;
@@ -1346,7 +1372,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 	u32 lpfr;
 	int ret;
 
-	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
 	if (ret)
 		return ret;
 
@@ -1418,6 +1444,9 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 			       (1 << V4L2_FLASH_LED_MODE_TORCH),
 			       V4L2_FLASH_LED_MODE_NONE);
 
+	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 */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 09/10] media: i2c: ov9282: add strobe_source v4l2 control
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (7 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration " Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-26 20:24   ` Sakari Ailus
  2025-05-07  7:51 ` [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration Richard Leitner
  2025-05-26 18:41 ` [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
  10 siblings, 1 reply; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

Add read-only V4L2_CID_FLASH_STROBE_SOURCE control. Its value is fixed
to V4L2_FLASH_STROBE_SOURCE_EXTERNAL as the camera sensor triggers the
strobe based on its register settings.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/i2c/ov9282.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index 0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03..09d522d5977ec6fb82028ddb6015f05c9328191d 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -1368,11 +1368,12 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 	struct v4l2_ctrl_handler *ctrl_hdlr = &ov9282->ctrl_handler;
 	const struct ov9282_mode *mode = ov9282->cur_mode;
 	struct v4l2_fwnode_device_properties props;
+	struct v4l2_ctrl *ctrl;
 	u32 hblank_min;
 	u32 lpfr;
 	int ret;
 
-	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 13);
 	if (ret)
 		return ret;
 
@@ -1447,6 +1448,14 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
 	v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
 			  0, 13900, 1, 8);
 
+	ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
+				      V4L2_CID_FLASH_STROBE_SOURCE,
+				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
+				      ~(1 << V4L2_FLASH_STROBE_SOURCE_EXTERNAL),
+				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
 	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
 	if (!ret) {
 		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (8 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 09/10] media: i2c: ov9282: add strobe_source " Richard Leitner
@ 2025-05-07  7:51 ` Richard Leitner
  2025-05-26 20:22   ` Sakari Ailus
  2025-05-26 18:41 ` [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
  10 siblings, 1 reply; 21+ messages in thread
From: Richard Leitner @ 2025-05-07  7:51 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds,
	Richard Leitner

As the granularity of the hardware supported values is lower than the
control value, implement a try_ctrl() function for
V4L2_CID_FLASH_DURATION. This function calculates the nearest possible
µs strobe duration for the given value and returns it back to the
caller.

Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
---
 drivers/media/i2c/ov9282.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index 09d522d5977ec6fb82028ddb6015f05c9328191d..f75882dcb73bea0e00e2cb37ffc19ec3c3a8b126 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -128,6 +128,8 @@
 #define OV9282_REG_MIN		0x00
 #define OV9282_REG_MAX		0xfffff
 
+#define OV9282_STROBE_SPAN_FACTOR	192
+
 static const char * const ov9282_supply_names[] = {
 	"avdd",		/* Analog power */
 	"dovdd",	/* Digital I/O power */
@@ -691,7 +693,7 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
 				current_val);
 }
 
-static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
+static u32 ov9282_us_to_flash_duration(struct ov9282 *ov9282, u32 value)
 {
 	/*
 	 * Calculate "strobe_frame_span" increments from a given value (µs).
@@ -702,7 +704,31 @@ static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
 	 * 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);
+	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
+
+	return value * OV9282_STROBE_SPAN_FACTOR / frame_width;
+}
+
+static u32 ov9282_flash_duration_to_us(struct ov9282 *ov9282, u32 value)
+{
+	/*
+	 * As the calculation in ov9282_us_to_flash_duration uses an integer
+	 * divison calculate in ns here to get more precision. Then check if
+	 * we need to compensate that divison by incrementing the µs result.
+	 */
+	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
+	u64 ns = value * 1000 * frame_width / OV9282_STROBE_SPAN_FACTOR;
+	u32 us = ns / 1000;
+	u32 remainder = ns % 1000;
+
+	if (remainder > 0)
+		us++;
+	return us;
+}
+
+static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
+{
+	u32 val = ov9282_us_to_flash_duration(ov9282, value);
 
 	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
 	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
@@ -792,9 +818,35 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
 	return ret;
 }
 
+static int ov9282_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov9282 *ov9282 =
+		container_of(ctrl->handler, struct ov9282, ctrl_handler);
+
+	if (ctrl->id == V4L2_CID_FLASH_DURATION) {
+		u32 fd = ov9282_us_to_flash_duration(ov9282, ctrl->val);
+		u32 us = ctrl->val;
+		u32 us0 = ov9282_flash_duration_to_us(ov9282, fd);
+		u32 us1 = ov9282_flash_duration_to_us(ov9282, (fd + 1));
+
+		if ((us1 - us) < (us - us0))
+			ctrl->val = us1;
+		else
+			ctrl->val = us0;
+
+		if (us != ctrl->val) {
+			dev_dbg(ov9282->dev, "using next valid strobe_duration %u instead of %u\n",
+				ctrl->val, us);
+		}
+	}
+
+	return 0;
+}
+
 /* V4l2 subdevice control ops*/
 static const struct v4l2_ctrl_ops ov9282_ctrl_ops = {
 	.s_ctrl = ov9282_set_ctrl,
+	.try_ctrl = ov9282_try_ctrl,
 };
 
 /**

-- 
2.47.2



^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: (subset) [PATCH v4 02/10] leds: flash: add support for flash/stobe duration
  2025-05-07  7:51 ` [PATCH v4 02/10] leds: flash: add support for flash/stobe duration Richard Leitner
@ 2025-05-13 10:08   ` Lee Jones
  0 siblings, 0 replies; 21+ messages in thread
From: Lee Jones @ 2025-05-13 10:08 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart, Richard Leitner
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds

On Wed, 07 May 2025 09:51:31 +0200, Richard Leitner wrote:
> Add support for the new V4L2_CID_FLASH_DURATION control to the leds
> driver.
> 
> 

Applied, thanks!

[02/10] leds: flash: add support for flash/stobe duration
        commit: 4cad0552415aa8c43af8d8d5924226c9b4c83889

--
Lee Jones [李琼斯]


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282
  2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
                   ` (9 preceding siblings ...)
  2025-05-07  7:51 ` [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration Richard Leitner
@ 2025-05-26 18:41 ` Richard Leitner
  10 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-26 18:41 UTC (permalink / raw)
  To: Sakari Ailus, Dave Stevenson, Mauro Carvalho Chehab, Lee Jones,
	Pavel Machek, Laurent Pinchart
  Cc: Hans Verkuil, linux-media, linux-kernel, linux-leds

Hi everybody,

this is a friendly ping :-)

Any feedback on this version of the series?
(except for that one approved patch ;-) )

Thanks & regards;
rl

On Wed, May 07, 2025 at 09:51:29AM +0200, Richard Leitner wrote:
> This series adds a new v4l2 controls named "strobe duration" with id
> V4L2_CID_FLASH_DURATION. This control enables setting a desired
> flash/strobe length/duration in µs.
> 
> As a first user of this new control add basic flash/strobe support for
> ov9282 sensors using their "hardware strobe output". The duration
> calculation is only interpolated from various measurements, as no
> documentation was found.
> 
> Further flash/strobe-related controls as well as a migration to v4l2-cci
> helpers for ov9282 will likely be implemented in future series.
> 
> All register addresses/values are based on the OV9281 datasheet v1.53
> (january 2019). This series was tested using an ov9281 VisionComponents
> camera module.
> 
> Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> ---
> Changes in v4:
> - Fix FLASH_DURATION implementation in v4l2-flash-led-class.c by adding a
>   missing brace and enum entry (thanks Sakari)
> - Fix format of multiline comment in ov9282.c (thanks Sakari)
> - Add missing NULL check in ov9282.c (thanks Sakari)
> - Adapt nr_of_controls_hint for v4l2 handler in ov9282.c (thanks Sakari)
> - Add patch for implementing try_ctrl for strobe_duration (thanks Sakari)
> - Link to v3: https://lore.kernel.org/r/20250429-ov9282-flash-strobe-v3-0-2105ce179952@linux.dev
> 
> Changes in v3:
> - create separate patch for leds driver changes (thanks Lee)
> - Link to v2: https://lore.kernel.org/r/20250314-ov9282-flash-strobe-v2-0-14d7a281342d@linux.dev
> 
> Changes in v2:
> - remove not needed controls in struct ov9282 (thanks Dave)
> - Fix commit message of 3/3 regarding framerate get/set (thanks Dave)
> - Add V4L2_CID_FLASH_STROBE_SOURCE impementation to ov9282
> - Add new V4L2_CID_FLASH_DURATION control (as suggested by Laurent)
> - Use FLASH_DURATION instead of FLASH_TIMEOUT for ov9282
> - Link to v1: https://lore.kernel.org/r/20250303-ov9282-flash-strobe-v1-0-0fd57a1564ba@linux.dev
> 
> ---
> Richard Leitner (10):
>       media: v4l: ctrls: add a control for flash/strobe duration
>       leds: flash: add support for flash/stobe duration
>       media: v4l2-flash: add support for flash/strobe duration
>       media: v4l2-flash: fix flash_timeout comment
>       Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION
>       media: i2c: ov9282: add output enable register definitions
>       media: i2c: ov9282: add led_mode v4l2 control
>       media: i2c: ov9282: add strobe_duration v4l2 control
>       media: i2c: ov9282: add strobe_source v4l2 control
>       media: i2c: ov9282: implement try_ctrl for strobe_duration
> 
>  .../userspace-api/media/v4l/ext-ctrls-flash.rst    |   5 +
>  drivers/leds/led-class-flash.c                     |  15 +++
>  drivers/media/i2c/ov9282.c                         | 148 ++++++++++++++++++++-
>  drivers/media/v4l2-core/v4l2-ctrls-defs.c          |   1 +
>  drivers/media/v4l2-core/v4l2-flash-led-class.c     |  25 ++++
>  include/linux/led-class-flash.h                    |  18 ++-
>  include/uapi/linux/v4l2-controls.h                 |   1 +
>  7 files changed, 208 insertions(+), 5 deletions(-)
> ---
> base-commit: 92a09c47464d040866cf2b4cd052bc60555185fb
> change-id: 20250303-ov9282-flash-strobe-ac6bd00c9de6
> prerequisite-change-id: 20250225-b4-ov9282-gain-ef1cdaba5bfd:v1
> prerequisite-patch-id: 86f2582378ff7095ab65ce4bb25a143eb639e840
> prerequisite-patch-id: b06eb6ec697aaf0b3155b4b2370f171d0d304ae2
> prerequisite-patch-id: b123047d71bfb9b93f743bbdd6893d5a98495801
> 
> Best regards,
> -- 
> Richard Leitner <richard.leitner@linux.dev>
> 
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration
  2025-05-07  7:51 ` [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration Richard Leitner
@ 2025-05-26 20:22   ` Sakari Ailus
  2025-05-28  9:25     ` Richard Leitner
  0 siblings, 1 reply; 21+ messages in thread
From: Sakari Ailus @ 2025-05-26 20:22 UTC (permalink / raw)
  To: Richard Leitner
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Richard,

Thanks for the update.

On Wed, May 07, 2025 at 09:51:39AM +0200, Richard Leitner wrote:
> As the granularity of the hardware supported values is lower than the
> control value, implement a try_ctrl() function for
> V4L2_CID_FLASH_DURATION. This function calculates the nearest possible
> µs strobe duration for the given value and returns it back to the
> caller.
> 
> Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> ---
>  drivers/media/i2c/ov9282.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 54 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> index 09d522d5977ec6fb82028ddb6015f05c9328191d..f75882dcb73bea0e00e2cb37ffc19ec3c3a8b126 100644
> --- a/drivers/media/i2c/ov9282.c
> +++ b/drivers/media/i2c/ov9282.c
> @@ -128,6 +128,8 @@
>  #define OV9282_REG_MIN		0x00
>  #define OV9282_REG_MAX		0xfffff
>  
> +#define OV9282_STROBE_SPAN_FACTOR	192
> +
>  static const char * const ov9282_supply_names[] = {
>  	"avdd",		/* Analog power */
>  	"dovdd",	/* Digital I/O power */
> @@ -691,7 +693,7 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
>  				current_val);
>  }
>  
> -static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> +static u32 ov9282_us_to_flash_duration(struct ov9282 *ov9282, u32 value)
>  {
>  	/*
>  	 * Calculate "strobe_frame_span" increments from a given value (µs).
> @@ -702,7 +704,31 @@ static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
>  	 * 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);
> +	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
> +
> +	return value * OV9282_STROBE_SPAN_FACTOR / frame_width;
> +}
> +
> +static u32 ov9282_flash_duration_to_us(struct ov9282 *ov9282, u32 value)
> +{
> +	/*
> +	 * As the calculation in ov9282_us_to_flash_duration uses an integer
> +	 * divison calculate in ns here to get more precision. Then check if
> +	 * we need to compensate that divison by incrementing the µs result.
> +	 */
> +	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
> +	u64 ns = value * 1000 * frame_width / OV9282_STROBE_SPAN_FACTOR;
> +	u32 us = ns / 1000;
> +	u32 remainder = ns % 1000;
> +
> +	if (remainder > 0)
> +		us++;

It looks like you're trying to round up here. Wouldn't

	return DIV_ROUND_UP(ns, 1000);

do the same?

> +	return us;
> +}
> +
> +static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> +{
> +	u32 val = ov9282_us_to_flash_duration(ov9282, value);
>  
>  	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
>  	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
> @@ -792,9 +818,35 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
>  	return ret;
>  }
>  
> +static int ov9282_try_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct ov9282 *ov9282 =
> +		container_of(ctrl->handler, struct ov9282, ctrl_handler);
> +
> +	if (ctrl->id == V4L2_CID_FLASH_DURATION) {
> +		u32 fd = ov9282_us_to_flash_duration(ov9282, ctrl->val);
> +		u32 us = ctrl->val;
> +		u32 us0 = ov9282_flash_duration_to_us(ov9282, fd);
> +		u32 us1 = ov9282_flash_duration_to_us(ov9282, (fd + 1));
> +
> +		if ((us1 - us) < (us - us0))

Is this missing abs?

> +			ctrl->val = us1;
> +		else
> +			ctrl->val = us0;
> +
> +		if (us != ctrl->val) {
> +			dev_dbg(ov9282->dev, "using next valid strobe_duration %u instead of %u\n",
> +				ctrl->val, us);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /* V4l2 subdevice control ops*/
>  static const struct v4l2_ctrl_ops ov9282_ctrl_ops = {
>  	.s_ctrl = ov9282_set_ctrl,
> +	.try_ctrl = ov9282_try_ctrl,
>  };
>  
>  /**
> 

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 09/10] media: i2c: ov9282: add strobe_source v4l2 control
  2025-05-07  7:51 ` [PATCH v4 09/10] media: i2c: ov9282: add strobe_source " Richard Leitner
@ 2025-05-26 20:24   ` Sakari Ailus
  2025-05-28  9:46     ` Richard Leitner
  0 siblings, 1 reply; 21+ messages in thread
From: Sakari Ailus @ 2025-05-26 20:24 UTC (permalink / raw)
  To: Richard Leitner
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Richard,

On Wed, May 07, 2025 at 09:51:38AM +0200, Richard Leitner wrote:
> Add read-only V4L2_CID_FLASH_STROBE_SOURCE control. Its value is fixed
> to V4L2_FLASH_STROBE_SOURCE_EXTERNAL as the camera sensor triggers the
> strobe based on its register settings.

Is strobe source control relevant for the sensor? It's triggering the flash
but the flash LED isn't connected to it, is it?

> 
> Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> ---
>  drivers/media/i2c/ov9282.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> index 0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03..09d522d5977ec6fb82028ddb6015f05c9328191d 100644
> --- a/drivers/media/i2c/ov9282.c
> +++ b/drivers/media/i2c/ov9282.c
> @@ -1368,11 +1368,12 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  	struct v4l2_ctrl_handler *ctrl_hdlr = &ov9282->ctrl_handler;
>  	const struct ov9282_mode *mode = ov9282->cur_mode;
>  	struct v4l2_fwnode_device_properties props;
> +	struct v4l2_ctrl *ctrl;
>  	u32 hblank_min;
>  	u32 lpfr;
>  	int ret;
>  
> -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 13);
>  	if (ret)
>  		return ret;
>  
> @@ -1447,6 +1448,14 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  	v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
>  			  0, 13900, 1, 8);
>  
> +	ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
> +				      V4L2_CID_FLASH_STROBE_SOURCE,
> +				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
> +				      ~(1 << V4L2_FLASH_STROBE_SOURCE_EXTERNAL),
> +				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL);
> +	if (ctrl)
> +		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
>  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
>  	if (!ret) {
>  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> 

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration v4l2 control
  2025-05-07  7:51 ` [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration " Richard Leitner
@ 2025-05-26 20:27   ` Sakari Ailus
  2025-06-16 22:11     ` Richard Leitner
  0 siblings, 1 reply; 21+ messages in thread
From: Sakari Ailus @ 2025-05-26 20:27 UTC (permalink / raw)
  To: Richard Leitner
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Richard,

On Wed, May 07, 2025 at 09:51:37AM +0200, Richard Leitner wrote:
> 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>
> ---
>  drivers/media/i2c/ov9282.c | 31 ++++++++++++++++++++++++++++++-
>  1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> index b6de96997426f7225a061bfdc841aa062e8d0891..0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03 100644
> --- a/drivers/media/i2c/ov9282.c
> +++ b/drivers/media/i2c/ov9282.c
> @@ -97,6 +97,10 @@
>  #define OV9282_REG_MIPI_CTRL00	0x4800
>  #define OV9282_GATED_CLOCK	BIT(5)
>  
> +/* Flash/Strobe control registers */
> +#define OV9282_REG_FLASH_DURATION	0x3925
> +#define OV9282_FLASH_DURATION_DEFAULT	0x0000001A

Lower case hexadecimals are preferred.

> +
>  /* Input clock rate */
>  #define OV9282_INCLK_RATE	24000000
>  
> @@ -687,6 +691,25 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
>  				current_val);
>  }
>  
> +static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)

I'd use u32 for the value here.

> +{
> +	/*
> +	 * 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);
> +
> +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
> +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
> +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 2, 1, (val >> 8) & 0xff);
> +	return ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 3, 1, val & 0xff);
> +}
> +
>  /**
>   * ov9282_set_ctrl() - Set subdevice control
>   * @ctrl: pointer to v4l2_ctrl structure
> @@ -756,6 +779,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_FLASH_LED_MODE:
>  		ret = ov9282_set_ctrl_flash_led_mode(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;
> @@ -1346,7 +1372,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  	u32 lpfr;
>  	int ret;
>  
> -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
>  	if (ret)
>  		return ret;
>  
> @@ -1418,6 +1444,9 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  			       (1 << V4L2_FLASH_LED_MODE_TORCH),
>  			       V4L2_FLASH_LED_MODE_NONE);
>  
> +	v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
> +			  0, 13900, 1, 8);

It'd be nice to calculate the limits based on the relevant parameters
rather than use a hard-coded value here.

> +
>  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
>  	if (!ret) {
>  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> 

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control
  2025-05-07  7:51 ` [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control Richard Leitner
@ 2025-05-26 20:41   ` Sakari Ailus
  2025-05-28 12:15     ` Richard Leitner
  0 siblings, 1 reply; 21+ messages in thread
From: Sakari Ailus @ 2025-05-26 20:41 UTC (permalink / raw)
  To: Richard Leitner
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Richard,

On Wed, May 07, 2025 at 09:51:36AM +0200, Richard Leitner wrote:
> Add V4L2_CID_FLASH_LED_MODE support using the "strobe output enable"
> feature of the sensor. This implements following modes:

The flash LED mode control is, well, setting the flash LED mode. There's no
LED on the sensor so I think I'd add a new control for this.

I'd call it V4L2_FLASH_LED_STROBE_ENABLE, and make it a boolean control.

(My apologies for not giving a better review for this set earlier on.)

How does this sensor make use the information? E.g. what's the latching
point this setting in relation to a given frame?

> 
>  - V4L2_FLASH_LED_MODE_NONE, which disables the strobe output
>  - V4L2_FLASH_LED_MODE_FLASH, which enables the strobe output
> 
> All values are based on the OV9281 datasheet v1.53 (january 2019) and
> tested using an ov9281 VisionComponents module.
> 
> Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> ---
>  drivers/media/i2c/ov9282.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> index f42e0d439753e74d14e3a3592029e48f49234927..b6de96997426f7225a061bfdc841aa062e8d0891 100644
> --- a/drivers/media/i2c/ov9282.c
> +++ b/drivers/media/i2c/ov9282.c
> @@ -670,6 +670,23 @@ static int ov9282_set_ctrl_vflip(struct ov9282 *ov9282, int value)
>  				current_val);
>  }
>  
> +static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
> +{
> +	u32 current_val;
> +	int ret = ov9282_read_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
> +				  &current_val);
> +	if (ret)
> +		return ret;
> +
> +	if (mode == V4L2_FLASH_LED_MODE_FLASH)
> +		current_val |= OV9282_OUTPUT_ENABLE6_STROBE;
> +	else
> +		current_val &= ~OV9282_OUTPUT_ENABLE6_STROBE;
> +
> +	return ov9282_write_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
> +				current_val);
> +}
> +
>  /**
>   * ov9282_set_ctrl() - Set subdevice control
>   * @ctrl: pointer to v4l2_ctrl structure
> @@ -736,6 +753,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
>  		ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_HTS, 2,
>  				       (ctrl->val + ov9282->cur_mode->width) >> 1);
>  		break;
> +	case V4L2_CID_FLASH_LED_MODE:
> +		ret = ov9282_set_ctrl_flash_led_mode(ov9282, ctrl->val);
> +		break;
>  	default:
>  		dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
>  		ret = -EINVAL;
> @@ -1326,7 +1346,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  	u32 lpfr;
>  	int ret;
>  
> -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
>  	if (ret)
>  		return ret;
>  
> @@ -1391,6 +1411,13 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
>  						OV9282_TIMING_HTS_MAX - mode->width,
>  						1, hblank_min);
>  
> +	/* Flash/Strobe controls */
> +	v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
> +			       V4L2_CID_FLASH_LED_MODE,
> +			       V4L2_FLASH_LED_MODE_TORCH,
> +			       (1 << V4L2_FLASH_LED_MODE_TORCH),
> +			       V4L2_FLASH_LED_MODE_NONE);
> +
>  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
>  	if (!ret) {
>  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> 

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration
  2025-05-26 20:22   ` Sakari Ailus
@ 2025-05-28  9:25     ` Richard Leitner
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-28  9:25 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

On Mon, May 26, 2025 at 08:22:15PM +0000, Sakari Ailus wrote:
> Hi Richard,
> 
> Thanks for the update.

Thank you for the review!

> 
> On Wed, May 07, 2025 at 09:51:39AM +0200, Richard Leitner wrote:
> > As the granularity of the hardware supported values is lower than the
> > control value, implement a try_ctrl() function for
> > V4L2_CID_FLASH_DURATION. This function calculates the nearest possible
> > µs strobe duration for the given value and returns it back to the
> > caller.
> > 
> > Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> > ---
> >  drivers/media/i2c/ov9282.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 54 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> > index 09d522d5977ec6fb82028ddb6015f05c9328191d..f75882dcb73bea0e00e2cb37ffc19ec3c3a8b126 100644
> > --- a/drivers/media/i2c/ov9282.c
> > +++ b/drivers/media/i2c/ov9282.c
> > @@ -128,6 +128,8 @@
> >  #define OV9282_REG_MIN		0x00
> >  #define OV9282_REG_MAX		0xfffff
> >  
> > +#define OV9282_STROBE_SPAN_FACTOR	192
> > +
> >  static const char * const ov9282_supply_names[] = {
> >  	"avdd",		/* Analog power */
> >  	"dovdd",	/* Digital I/O power */
> > @@ -691,7 +693,7 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
> >  				current_val);
> >  }
> >  
> > -static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> > +static u32 ov9282_us_to_flash_duration(struct ov9282 *ov9282, u32 value)
> >  {
> >  	/*
> >  	 * Calculate "strobe_frame_span" increments from a given value (µs).
> > @@ -702,7 +704,31 @@ static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> >  	 * 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);
> > +	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
> > +
> > +	return value * OV9282_STROBE_SPAN_FACTOR / frame_width;
> > +}
> > +
> > +static u32 ov9282_flash_duration_to_us(struct ov9282 *ov9282, u32 value)
> > +{
> > +	/*
> > +	 * As the calculation in ov9282_us_to_flash_duration uses an integer
> > +	 * divison calculate in ns here to get more precision. Then check if
> > +	 * we need to compensate that divison by incrementing the µs result.
> > +	 */
> > +	u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
> > +	u64 ns = value * 1000 * frame_width / OV9282_STROBE_SPAN_FACTOR;
> > +	u32 us = ns / 1000;
> > +	u32 remainder = ns % 1000;
> > +
> > +	if (remainder > 0)
> > +		us++;
> 
> It looks like you're trying to round up here. Wouldn't
> 
> 	return DIV_ROUND_UP(ns, 1000);
> 
> do the same?

Yes, thanks for the suggestion. I wasn't thinking of DIV_ROUND_UP here,
but this makes the code way more readable :-)

Will adapt this in v5.

> 
> > +	return us;
> > +}
> > +
> > +static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> > +{
> > +	u32 val = ov9282_us_to_flash_duration(ov9282, value);
> >  
> >  	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
> >  	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
> > @@ -792,9 +818,35 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
> >  	return ret;
> >  }
> >  
> > +static int ov9282_try_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +	struct ov9282 *ov9282 =
> > +		container_of(ctrl->handler, struct ov9282, ctrl_handler);
> > +
> > +	if (ctrl->id == V4L2_CID_FLASH_DURATION) {
> > +		u32 fd = ov9282_us_to_flash_duration(ov9282, ctrl->val);
> > +		u32 us = ctrl->val;
> > +		u32 us0 = ov9282_flash_duration_to_us(ov9282, fd);
> > +		u32 us1 = ov9282_flash_duration_to_us(ov9282, (fd + 1));
> > +
> > +		if ((us1 - us) < (us - us0))
> 
> Is this missing abs?

IMHO this abs() isn't required here, as the (fd + 1) value should be
always higher than the fd one. But nonetheless it doesn't hurt, so I'll
add it in v5. Thanks!

> 
> > +			ctrl->val = us1;
> > +		else
> > +			ctrl->val = us0;
> > +
> > +		if (us != ctrl->val) {
> > +			dev_dbg(ov9282->dev, "using next valid strobe_duration %u instead of %u\n",
> > +				ctrl->val, us);
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /* V4l2 subdevice control ops*/
> >  static const struct v4l2_ctrl_ops ov9282_ctrl_ops = {
> >  	.s_ctrl = ov9282_set_ctrl,
> > +	.try_ctrl = ov9282_try_ctrl,
> >  };
> >  
> >  /**
> > 
> 
> -- 
> Regards,
> 
> Sakari Ailus

thanks & regards;rl

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 09/10] media: i2c: ov9282: add strobe_source v4l2 control
  2025-05-26 20:24   ` Sakari Ailus
@ 2025-05-28  9:46     ` Richard Leitner
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-28  9:46 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

On Mon, May 26, 2025 at 08:24:40PM +0000, Sakari Ailus wrote:
> Hi Richard,

Hi Sakari,

thanks for the review!

> 
> On Wed, May 07, 2025 at 09:51:38AM +0200, Richard Leitner wrote:
> > Add read-only V4L2_CID_FLASH_STROBE_SOURCE control. Its value is fixed
> > to V4L2_FLASH_STROBE_SOURCE_EXTERNAL as the camera sensor triggers the
> > strobe based on its register settings.
> 
> Is strobe source control relevant for the sensor? It's triggering the flash
> but the flash LED isn't connected to it, is it?

Exactly. The sensor is only triggering a "strobe output" pin, but no
LEDs are on the sensor module. Nonetheless at least in our use-case the LEDs
are switched directly by this output pin of the sensor (via some FET
circuit).

So to be honest I don't know if it is relevant, or not. I guess the
sensor in this case is a "external strobe source" as seen from the
kernel, isn't it?

> 
> > 
> > Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> > ---
> >  drivers/media/i2c/ov9282.c | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> > index 0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03..09d522d5977ec6fb82028ddb6015f05c9328191d 100644
> > --- a/drivers/media/i2c/ov9282.c
> > +++ b/drivers/media/i2c/ov9282.c
> > @@ -1368,11 +1368,12 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  	struct v4l2_ctrl_handler *ctrl_hdlr = &ov9282->ctrl_handler;
> >  	const struct ov9282_mode *mode = ov9282->cur_mode;
> >  	struct v4l2_fwnode_device_properties props;
> > +	struct v4l2_ctrl *ctrl;
> >  	u32 hblank_min;
> >  	u32 lpfr;
> >  	int ret;
> >  
> > -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
> > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 13);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -1447,6 +1448,14 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  	v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
> >  			  0, 13900, 1, 8);
> >  
> > +	ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
> > +				      V4L2_CID_FLASH_STROBE_SOURCE,
> > +				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
> > +				      ~(1 << V4L2_FLASH_STROBE_SOURCE_EXTERNAL),
> > +				      V4L2_FLASH_STROBE_SOURCE_EXTERNAL);
> > +	if (ctrl)
> > +		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> >  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
> >  	if (!ret) {
> >  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> > 
> 
> -- 
> Regards,
> 
> Sakari Ailus

thanks & regards;rl

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control
  2025-05-26 20:41   ` Sakari Ailus
@ 2025-05-28 12:15     ` Richard Leitner
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-05-28 12:15 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Sakari,

On Mon, May 26, 2025 at 08:41:08PM +0000, Sakari Ailus wrote:
> Hi Richard,
> 
> On Wed, May 07, 2025 at 09:51:36AM +0200, Richard Leitner wrote:
> > Add V4L2_CID_FLASH_LED_MODE support using the "strobe output enable"
> > feature of the sensor. This implements following modes:
> 
> The flash LED mode control is, well, setting the flash LED mode. There's no
> LED on the sensor so I think I'd add a new control for this.
> 
> I'd call it V4L2_FLASH_LED_STROBE_ENABLE, and make it a boolean control.
> 
> (My apologies for not giving a better review for this set earlier on.)

No problem. I'm open for discussions all the time ;-)

I'm basically fine with renaming this, but is there any benefit we get
by introducing such a new control?

IMHO V4L2_CID_FLASH_LED_MODE and V4L2_FLASH_LED_STROBE_ENABLE sound
pretty similar and I'm not sure this is "worth" a new v4l2 control.

But of course, you guys are the domain expert, so please feel free to
"overrule" my gut feeling. ;-)

> 
> How does this sensor make use the information? E.g. what's the latching
> point this setting in relation to a given frame?

I'm not sure if I understand you correctly, but the strobe pulse
"starting time" is configurable using registers on the sensor. To keep
this patchset small I've decided to not include this
"strobe_frame_shift" setting (which may be positive or negative) here.

Nonetheless I'm planning to send another series adding more features of
the sensors as soon as this got merged.

IMHO we would need another new v4l2 control for this then (something
like V4L2_FLASH_LED_STROBE_SHIFT).

Does that answer your question?

> 
> > 
> >  - V4L2_FLASH_LED_MODE_NONE, which disables the strobe output
> >  - V4L2_FLASH_LED_MODE_FLASH, which enables the strobe output
> > 
> > All values are based on the OV9281 datasheet v1.53 (january 2019) and
> > tested using an ov9281 VisionComponents module.
> > 
> > Signed-off-by: Richard Leitner <richard.leitner@linux.dev>
> > ---
> >  drivers/media/i2c/ov9282.c | 29 ++++++++++++++++++++++++++++-
> >  1 file changed, 28 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> > index f42e0d439753e74d14e3a3592029e48f49234927..b6de96997426f7225a061bfdc841aa062e8d0891 100644
> > --- a/drivers/media/i2c/ov9282.c
> > +++ b/drivers/media/i2c/ov9282.c
> > @@ -670,6 +670,23 @@ static int ov9282_set_ctrl_vflip(struct ov9282 *ov9282, int value)
> >  				current_val);
> >  }
> >  
> > +static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
> > +{
> > +	u32 current_val;
> > +	int ret = ov9282_read_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
> > +				  &current_val);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (mode == V4L2_FLASH_LED_MODE_FLASH)
> > +		current_val |= OV9282_OUTPUT_ENABLE6_STROBE;
> > +	else
> > +		current_val &= ~OV9282_OUTPUT_ENABLE6_STROBE;
> > +
> > +	return ov9282_write_reg(ov9282, OV9282_REG_OUTPUT_ENABLE6, 1,
> > +				current_val);
> > +}
> > +
> >  /**
> >   * ov9282_set_ctrl() - Set subdevice control
> >   * @ctrl: pointer to v4l2_ctrl structure
> > @@ -736,6 +753,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
> >  		ret = ov9282_write_reg(ov9282, OV9282_REG_TIMING_HTS, 2,
> >  				       (ctrl->val + ov9282->cur_mode->width) >> 1);
> >  		break;
> > +	case V4L2_CID_FLASH_LED_MODE:
> > +		ret = ov9282_set_ctrl_flash_led_mode(ov9282, ctrl->val);
> > +		break;
> >  	default:
> >  		dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
> >  		ret = -EINVAL;
> > @@ -1326,7 +1346,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  	u32 lpfr;
> >  	int ret;
> >  
> > -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
> > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -1391,6 +1411,13 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  						OV9282_TIMING_HTS_MAX - mode->width,
> >  						1, hblank_min);
> >  
> > +	/* Flash/Strobe controls */
> > +	v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
> > +			       V4L2_CID_FLASH_LED_MODE,
> > +			       V4L2_FLASH_LED_MODE_TORCH,
> > +			       (1 << V4L2_FLASH_LED_MODE_TORCH),
> > +			       V4L2_FLASH_LED_MODE_NONE);
> > +
> >  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
> >  	if (!ret) {
> >  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> > 
> 
> -- 
> Regards,
> 
> Sakari Ailus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration v4l2 control
  2025-05-26 20:27   ` Sakari Ailus
@ 2025-06-16 22:11     ` Richard Leitner
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Leitner @ 2025-06-16 22:11 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Dave Stevenson, Mauro Carvalho Chehab, Lee Jones, Pavel Machek,
	Laurent Pinchart, Hans Verkuil, linux-media, linux-kernel,
	linux-leds

Hi Sakari,

thanks also for reviewing this patch :-)

On Mon, May 26, 2025 at 08:27:29PM +0000, Sakari Ailus wrote:
> Hi Richard,
> 
> On Wed, May 07, 2025 at 09:51:37AM +0200, Richard Leitner wrote:
> > 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>
> > ---
> >  drivers/media/i2c/ov9282.c | 31 ++++++++++++++++++++++++++++++-
> >  1 file changed, 30 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> > index b6de96997426f7225a061bfdc841aa062e8d0891..0bbdf08d7cda8f72e05fdc292aa69a4c821e4e03 100644
> > --- a/drivers/media/i2c/ov9282.c
> > +++ b/drivers/media/i2c/ov9282.c
> > @@ -97,6 +97,10 @@
> >  #define OV9282_REG_MIPI_CTRL00	0x4800
> >  #define OV9282_GATED_CLOCK	BIT(5)
> >  
> > +/* Flash/Strobe control registers */
> > +#define OV9282_REG_FLASH_DURATION	0x3925
> > +#define OV9282_FLASH_DURATION_DEFAULT	0x0000001A
> 
> Lower case hexadecimals are preferred.

Sure. Will fix that in v5.

> 
> > +
> >  /* Input clock rate */
> >  #define OV9282_INCLK_RATE	24000000
> >  
> > @@ -687,6 +691,25 @@ static int ov9282_set_ctrl_flash_led_mode(struct ov9282 *ov9282, int mode)
> >  				current_val);
> >  }
> >  
> > +static int ov9282_set_ctrl_flash_duration(struct ov9282 *ov9282, int value)
> 
> I'd use u32 for the value here.

Sounds legit. Will adapt that in v5.

> 
> > +{
> > +	/*
> > +	 * 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);
> > +
> > +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION, 1, (val >> 24) & 0xff);
> > +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 1, 1, (val >> 16) & 0xff);
> > +	ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 2, 1, (val >> 8) & 0xff);
> > +	return ov9282_write_reg(ov9282, OV9282_REG_FLASH_DURATION + 3, 1, val & 0xff);
> > +}
> > +
> >  /**
> >   * ov9282_set_ctrl() - Set subdevice control
> >   * @ctrl: pointer to v4l2_ctrl structure
> > @@ -756,6 +779,9 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
> >  	case V4L2_CID_FLASH_LED_MODE:
> >  		ret = ov9282_set_ctrl_flash_led_mode(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;
> > @@ -1346,7 +1372,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  	u32 lpfr;
> >  	int ret;
> >  
> > -	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
> > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -1418,6 +1444,9 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
> >  			       (1 << V4L2_FLASH_LED_MODE_TORCH),
> >  			       V4L2_FLASH_LED_MODE_NONE);
> >  
> > +	v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
> > +			  0, 13900, 1, 8);
> 
> It'd be nice to calculate the limits based on the relevant parameters
> rather than use a hard-coded value here.

Ok :-)
I will send an updated v5 where the maximum flash duration is set to the
current exposure time in µs tomorrow.

> 
> > +
> >  	ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
> >  	if (!ret) {
> >  		/* Failure sets ctrl_hdlr->error, which we check afterwards anyway */
> > 
> 
> -- 
> Regards,
> 
> Sakari Ailus

thanks & regards;rl

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2025-06-16 22:12 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-07  7:51 [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner
2025-05-07  7:51 ` [PATCH v4 01/10] media: v4l: ctrls: add a control for flash/strobe duration Richard Leitner
2025-05-07  7:51 ` [PATCH v4 02/10] leds: flash: add support for flash/stobe duration Richard Leitner
2025-05-13 10:08   ` (subset) " Lee Jones
2025-05-07  7:51 ` [PATCH v4 03/10] media: v4l2-flash: add support for flash/strobe duration Richard Leitner
2025-05-07  7:51 ` [PATCH v4 04/10] media: v4l2-flash: fix flash_timeout comment Richard Leitner
2025-05-07  7:51 ` [PATCH v4 05/10] Documentation: uAPI: media: add V4L2_CID_FLASH_DURATION Richard Leitner
2025-05-07  7:51 ` [PATCH v4 06/10] media: i2c: ov9282: add output enable register definitions Richard Leitner
2025-05-07  7:51 ` [PATCH v4 07/10] media: i2c: ov9282: add led_mode v4l2 control Richard Leitner
2025-05-26 20:41   ` Sakari Ailus
2025-05-28 12:15     ` Richard Leitner
2025-05-07  7:51 ` [PATCH v4 08/10] media: i2c: ov9282: add strobe_duration " Richard Leitner
2025-05-26 20:27   ` Sakari Ailus
2025-06-16 22:11     ` Richard Leitner
2025-05-07  7:51 ` [PATCH v4 09/10] media: i2c: ov9282: add strobe_source " Richard Leitner
2025-05-26 20:24   ` Sakari Ailus
2025-05-28  9:46     ` Richard Leitner
2025-05-07  7:51 ` [PATCH v4 10/10] media: i2c: ov9282: implement try_ctrl for strobe_duration Richard Leitner
2025-05-26 20:22   ` Sakari Ailus
2025-05-28  9:25     ` Richard Leitner
2025-05-26 18:41 ` [PATCH v4 00/10] Add strobe/flash duration v4l2 ctrl & use it for ov9282 Richard Leitner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).